Language/Ruby

[Ruby, Jekyll] bundle을 통한 Jekyll 실행 에러 발생 관련 (bundle exec jekyll serve)

§※★ª 2021. 3. 23. 20:32

(이 글을 쓰려고하니까 ssh 로그가 다 올라가버려서 exception log를 전부 날렸다. 망할.)  

jekyll 테마를 직접 fork해서 사용하기 위해 Github Repository에서 Clone을 하고 내부 디렉토리에서 bundle을 통해 의존성을 설치했다.  

bundle은 Ruby에서 사용하는 특정 프로젝트의 특정 의존성들만 설치하기 위한 Ruby의 프로젝트 도구라고한다.  

보통 실행은 다음 명령어로 진행한다.  

> bundle exec jekyll serve

 

하지만 검색하기도 힘든 에러가 발생했다.

  Traceback (most recent call last):
          14: from /usr/local/bin/jekyll:23:in `<main>'
          13: from /usr/local/bin/jekyll:23:in `load'
          12: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/exe/jekyll:8:in `<top (required)>'
          11: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
          10: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
           9: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll.rb:191:in `<top (required)>'
           8: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll.rb:12:in `require_all'
           7: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll.rb:12:in `each'
           6: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll.rb:13:in `block in require_all'
           5: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
           4: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
           3: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll/drops/collection_drop.rb:3:in `<top (required)>'
           2: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll/drops/collection_drop.rb:4:in `<module:Jekyll>'
           1: from /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll/drops/collection_drop.rb:5:in `<module:Drops>'
  /var/lib/gems/2.5.0/gems/jekyll-4.2.0/lib/jekyll/drops/collection_drop.rb:10:in `<class:CollectionDrop>': undefined method `delegate_method_as' for Jekyll::Drops::CollectionDrop:Class (NoMethodError)
  Did you mean?  DelegateClass

Source: Link

 

은근히 삽질을 오래했지만 유사 사례를 이거밖에 찾지를 못했다. 문제점은 아무래도 Gems에 설치된 의존성과 OS 전역으로 설치된 Jekyll이 충돌해서 생기는 문제라는 듯 하다.

 

본인은 bundle exec jekyll serve (or s) 를 실행했을때 터지는 문제였지만 정작 jekyll --version은 잘 작동했다.

 

이 문제는 apt로 전역으로 설치한 jekyll이 문제인듯 싶어 이를 제거하기 위한 작업에 착수했다.

sudo apt remove jekyll

하지만 새로운 문제가 이어서 발생..

 

Liquid Exception: uninitialized constant Kramdown::Utils::OrderedHash in feed.xml
bundler: failed to load command: jekyll (/home/ronnie/gems/bin/jekyll)
NameError: uninitialized constant Kramdown::Utils::OrderedHash
/usr/lib/ruby/vendor_ruby/kramdown/parser/html.rb:113:in parse_html_attributes' /usr/lib/ruby/vendor_ruby/kramdown/parser/html.rb:89:inhandle_html_start_tag’
/usr/lib/ruby/vendor_ruby/kramdown/parser/kramdown/html.rb:83:in parse_block_html' /usr/lib/ruby/vendor_ruby/kramdown/parser/kramdown.rb:148:inblock (2 levels) in parse_blocks’
/usr/lib/ruby/vendor_ruby/kramdown/parser/kramdown.rb:146:in any?' /usr/lib/ruby/vendor_ruby/kramdown/parser/kramdown.rb:146:inblock in parse_blocks’
/usr/lib/ruby/vendor_ruby/kramdown/parser/kramdown.rb:144:in catch' /usr/lib/ruby/vendor_ruby/kramdown/parser/kramdown.rb:144:inparse_blocks’
/usr/lib/ruby/vendor_ruby/kramdown/parser/kramdown.rb:89:in parse' /home/ronnie/gems/gems/kramdown-parser-gfm-1.1.0/lib/kramdown/parser/gfm.rb:56:inparse’
/usr/lib/ruby/vendor_ruby/kramdown/parser/base.rb:69:in parse' /home/ronnie/gems/gems/kramdown-2.1.0/lib/kramdown/document.rb:102:ininitialize’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/converters/markdown/kramdown_parser.rb:40:in new' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/converters/markdown/kramdown_parser.rb:40:inconvert’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/converters/markdown.rb:86:in block in convert' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/cache.rb:111:inrescue in getset’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/cache.rb:108:in getset' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/converters/markdown.rb:85:inconvert’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/filters.rb:19:in markdownify' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/strainer.rb:56:ininvoke’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/context.rb:86:in invoke' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/variable.rb:84:inblock in render’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/variable.rb:82:in each' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/variable.rb:82:ininject’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/variable.rb:82:in render' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/block_body.rb:103:inrender_node_to_output’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/block_body.rb:80:in render' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/if.rb:46:inblock (2 levels) in render’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/if.rb:44:in each' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/if.rb:44:inblock in render’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/context.rb:123:in stack' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/if.rb:43:inrender’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/block_body.rb:103:in render_node_to_output' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/block_body.rb:82:inrender’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/for.rb:160:in block (2 levels) in render_segment' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/for.rb:158:ineach’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/for.rb:158:in block in render_segment' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/context.rb:123:instack’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/for.rb:150:in render_segment' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/tags/for.rb:79:inrender’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/block_body.rb:103:in render_node_to_output' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/block_body.rb:82:inrender’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/template.rb:208:in block in render' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/template.rb:242:inwith_profiling’
/home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/template.rb:207:in render' /home/ronnie/gems/gems/liquid-4.0.3/lib/liquid/template.rb:220:inrender!’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:35:in block (3 levels) in render!' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:49:inmeasure_counts’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:34:in block (2 levels) in render!' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:53:inmeasure_bytes’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:33:in block in render!' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:60:inmeasure_time’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/liquid_renderer/file.rb:32:in render!' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/renderer.rb:127:inrender_liquid’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/renderer.rb:80:in render_document' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/renderer.rb:63:inrun’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/convertible.rb:210:in do_layout' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/page.rb:136:inrender’
/usr/lib/ruby/vendor_ruby/jekyll-feed.rb:85:in feed_content' /usr/lib/ruby/vendor_ruby/jekyll-feed.rb:78:inblock in write’
/usr/lib/ruby/vendor_ruby/jekyll-feed.rb:78:in open' /usr/lib/ruby/vendor_ruby/jekyll-feed.rb:78:inwrite’
/usr/lib/ruby/vendor_ruby/jekyll-feed.rb:55:in generate' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/site.rb:185:inblock in generate’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/site.rb:183:in each' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/site.rb:183:ingenerate’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/site.rb:75:in process' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/command.rb:28:inprocess_site’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/commands/build.rb:65:in build' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/commands/build.rb:36:inprocess’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/command.rb:89:in block in process_with_graceful_fail' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/command.rb:89:ineach’
/home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/command.rb:89:in process_with_graceful_fail' /home/ronnie/gems/gems/jekyll-4.0.0/lib/jekyll/commands/serve.rb:86:inblock (2 levels) in init_with_program’
/usr/lib/ruby/vendor_ruby/mercenary/command.rb:220:in block in execute' /usr/lib/ruby/vendor_ruby/mercenary/command.rb:220:ineach’
/usr/lib/ruby/vendor_ruby/mercenary/command.rb:220:in execute' /usr/lib/ruby/vendor_ruby/mercenary/program.rb:42:ingo’
/usr/lib/ruby/vendor_ruby/mercenary.rb:19:in program' /home/ronnie/gems/gems/jekyll-4.0.0/exe/jekyll:15:in<top (required)>’
/home/ronnie/gems/bin/jekyll:23:in load' /home/ronnie/gems/bin/jekyll:23:in<top (required)>’

Source : Link

 

NameError: uninitialized constant Kramdown::Utils::OrderedHash 에 주목을 했다. 중복되는 Jekyll은 불명 삭제했을터, 그러면 무슨 문제일까?

 

> 일부 Gem은 홈 디렉토리에서 로드되고 있는 상황 (/home/ronnie/gems/~)

> 다른 Gem은 OS 차원에서의 전역 모듈이 포함된 위치에서 로드되고 있는 상황 (/usr/lib/ruby/vendor_ruby)

(관련 문제에 대한 Stackoverflow : Link)

 

여기서 문제는, Kramdown 모듈의 버전의 괴리감에서 생기는 문제라고한다. 홈 디렉토리와 전역 모듈에 존재하는 라이브러리의 버전이 달라서 그런것. Kramdown은 Jekyll 엔진에서 마크다운 옵션의 한 종류라고한다. 허나 2.0.0 버전 이후로 OrderedHash 란 기능이 완전이 remove 되었다는것. 없어져버린 기능을 참조하는 바람에 생긴 에러인듯 하다.

 

이에 대한 해결책으로는 전역 모듈이 포함된 디렉토리를 참조못하게 삭제하라는 것.

 

놀랍게도 실행되는 상황

이로인해 몇시간이나 잡아먹은 문제를 해결할 수 있었다..

 

Bundle을 사용할때는 앞으로 이러한 모듈 관리에 주의해야겠다고 생각했다. Gem 저장소를 home 디렉토리에 별도로 마련해 사용한다면 (찾아보니 Ruby 이용시에는 대부분 이렇게 사용하는듯 함) apt를 통한 설치는 가급적이면 자제해야하는것 같다.

 

Ruby는 당근마켓덕분에 알게된 언어지만 이런식으로라도 언어에 대해 더 알게된 것만으로도 다행이라고 생각.