Jekyllバージョンアップの際に思いのほか手こずった話 てっく煮さん製プラグインの更新に追従したい編

前回までのあらすじ

結論

fork していれば、だいたいなんとかなる。

環境

  • Ruby 1.9.3
    • RedCloth (4.2.9)
    • bundler (1.3.5)
    • classifier (1.3.3)
    • colorator (0.1)
    • commander (4.1.4)
    • directory_watcher (1.4.1)
    • fast-stemmer (1.0.2)
    • highline (1.6.19)
    • hparser (0.4.0 dc35f05)
    • jekyll (1.0.0 9f94eaf)
    • kramdown (0.14.2)
    • liquid (2.5.1)
    • maruku (0.6.1)
    • posix-spawn (0.3.6)
    • pygments.rb (0.4.2)
    • rake (10.1.0)
    • rdiscount (2.1.6)
    • redcarpet (2.2.2)
    • safe_yaml (0.7.1)
    • syntax (1.0.0)
    • yajl-ruby (1.1.0)

参考サイト

やりたい事: てっく煮プラグイン編

@nitoyon さんが公開しているリポジトリ( https://github.com/nitoyon/tech.nitoyon.com )内の _plugins を使わせていただきたい。

はじめはコピペで自分のリポジトリの _plugins 下に持ってきていた。

が、前述の通りコピペしただけなので更新に追従できず自爆。

どうしよう。プラグインだけ追従とかできるんだろうか。

方針

  • _plugins 下に置いておいて、折りを見て更新したい
  • コピペは避けたい
  • 自分用に少し手を入れたり、使う予定のないプラグインは削除したい
    • 例えば、先走ってJekyllのバージョンあげて互換性がなくなっちゃった場合の緊急回避策として(後述)

以降、三つのリポジトリが出てくるので、便宜上こう呼ぶ。

その1: 本家リポジトリをそのまま一部サブモジュール化(断念)

本家 リポジトリを 自分のJekyll リポジトリ内にサブモジュールとして clone してくる。

$ cd gosyujin.github.com
$ git submodule add http://github.com/nitoyon/tech.nitoyon.com.git _plugins/tech.nitoyon.com
Cloning into '_plugins/tech.nitoyon.com'...
remote: Counting objects: 15343, done.
remote: Compressing objects: 100% (4228/4228), done.
remote: Total 15343 (delta 5610), reused 14585 (delta 4852)
Receiving objects: 100% (15343/15343), 10.39 MiB | 623 KiB/s, done.
Resolving deltas: 100% (5610/5610), done.
warning: LF will be replaced by CRLF in .gitmodules.
The file will have its original line endings in your working directory.

※ Windowsの場合、パスの区切りに円マークを使うとうまくいかない?

以下のようなエラーが出た。

$ git --version
git version 1.8.1.msysgit.1
$ git submodule add http://github.com/nitoyon/tech.nitoyon.com.git _plugins\tech.nitoyon.com
fatal: Could not switch to '.git/modules/_plugins\': No such file or directory
Clone of 'http://github.com/nitoyon/tech.nitoyon.com.git' into submodule path '_plugins\tech.nitoyon.com' failed

サブモジュールとして引っ張ってくると、リポジトリの中身全部入りで取得されてしまう。

次に _plugins ディレクトリだけを切りだす。

$ cd _plugins\tech.nitoyon.com\
$ ls -a
./                           _layouts/                    favicon.ico
../                          _plugins/                    images/
.git                         _posts/                      img/
.gitignore                   _scripts/                    index.cgi
.htaccess                    about.css                    ja/
Gruntfile.js*                apple-touch-icon-114x114.png javascripts/
README.markdown              apple-touch-icon-72x72.png   misc/
_caches/                     apple-touch-icon.png         package.json
_config.yml                  blog.cgi                     stylesheets/
_includes/                   en/                          techni.css
_lang/                       entry.cgi
$ git filter-branch --subdirectory-filter _plugins HEAD
Rewrite 942d387c8d9d2f43efe2301cae1abe5ac7e489de (61/61)
Ref 'refs/heads/master' was rewritten
$ ls
archives.rb* converters/  ext/         filters/     lang.rb*     tags/        tags.rb*

これで、更新されたら fetch すれば 自分のJekyll にも更新が反映されるはず。

サブモジュールの更新…できない?

なんだけど、このサブモジュールに対する変更(とかファイル削除)ってどうやればいいんだ…?

ローカルでは好き放題できるし、コミット自体もできるけどそれを push する術と場所がない?

  • サブモジュールに対しては編集できない

やっぱり fork 必須?

……ってことは、

  • 本家
    • fork するだけ
  • forkした本家
    • ここで 本家 リポジトリへの更新追従とプラグインの変更などを行う
  • 自分のJekyll
    • forkした本家_plugins 以下をサブモジュールとして適用

するのが良いのか?というかしないとダメ?

その2: 本家リポジトリを一回forkしてそこから更新分を持ってくる(採用)

結局 Jekyl Bootstrap のケースと同じく fork するのが一番?

本家

まずは 本家 を GitHub 上から fork 。

fork した本家

forkした本家 をローカルに clone する。

$ git clone http://github.com/gosyujin/tech.nitoyon.com.git

プラグインの変更などをする場合はここで行い、修正内容を push する。

また、 本家 の更新にもガンガン追従していく。

自分の Jekyll

その1 でやった「サブモジュールとして持ってきて、 _plugins だけ切り出す」を forkした本家自分のJekyll 間で行う。

$ cd gosyujin.github.com
$ git submodule add http://github.com/gosyujin/tech.nitoyon.com.git _plugins/tech.nitoyon.com
$ git filter-branch --subdirectory-filter _plugins HEAD

これで 自分のJekyll 内にてっく煮プラグインが入った。

なおかつ、プラグインの修正などは forkした本家 で自由にでき、 本家 の更新への追従もここでできる。

という感じで運用できるだろうか。


おまけ 先走ってJekyllのバージョンあげて互換性がなくなっちゃった場合の緊急回避策

例えばこんな場合。

Jekyll を 1.0.0 から 1.2.2 に一気に上げた場合( pygments.rb も)、以下のようなエラーが起こってしまった。

gem 'jekyll', :git => 'http://github.com/mojombo/jekyll.git', :tag => 'v1.1.2'
gem 'pygments.rb', '=0.5.0'
  Generating... C:/work/gosyujin.github.com/_plugins/tech.nitoyon.com/ext/post_to_liquid_raw.rb:56:in `to_liquid': wrong number of arguments (1 for 0) (ArgumentError)
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/post.rb:255:in `render'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/site.rb:213:in `block in render'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/site.rb:212:in `each'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/site.rb:212:in `render'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/site.rb:44:in `process'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/command.rb:18:in `process_site'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/commands/build.rb:23:in `build'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/lib/jekyll/commands/build.rb:7:in `process'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/bundler/gems/jekyll-0db5dcf83217/bin/jekyll:96:in `block (2 levels) in <top (required)>'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/gems/commander-4.1.4/lib/commander/command.rb:180:in `call'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/gems/commander-4.1.4/lib/commander/command.rb:180:in `call'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/gems/commander-4.1.4/lib/commander/command.rb:155:in `run'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/gems/commander-4.1.4/lib/commander/runner.rb:402:in `run_active_command'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/gems/commander-4.1.4/lib/commander/runner.rb:78:in `run!'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/gems/commander-4.1.4/lib/commander/delegates.rb:11:in `run!'
      from C:/work/gosyujin.github.com/vendor/bundle/ruby/1.9.1/gems/commander-4.1.4/lib/commander/import.rb:10:in `block in <top (required)>'
    # add 'raw' attribute
    def to_liquid
      self.to_liquid_orig.deep_merge({
        "raw" => ToDrop.new(self)
      })
    end

うーむ post_to_liquid_raw.rb で呼んでる to_liquid の引数がおかしいと。

実装元のdiffをとってみる。

$ cd C:\work\gosyujin.github.com\vendor\bundle\ruby\1.9.1\bundler\gems\jekyll-0db5dcf83217\lib\jekyll
$ git diff v1.1.0..v1.1.2 -- ./post.rb
diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb
index 1b70e31..9ad2539 100644
--- a/lib/jekyll/post.rb
+++ b/lib/jekyll/post.rb
(略)
@@ -272,8 +275,8 @@ module Jekyll
     # Convert this post into a Hash for use in Liquid templates.
     #
     # Returns the representative Hash.
-    def to_liquid
-      further_data = Hash[ATTRIBUTES_FOR_LIQUID.map { |attribute|
+    def to_liquid(attrs = ATTRIBUTES_FOR_LIQUID)
+      further_data = Hash[attrs.map { |attribute|

すると v1.1.0 から v1.1.2 の間( v1.1.1 )で to_liquid に引数が加えられてる!

ATTRIBUTES_FOR_LIQUID はこんな定数が入っていた: ["title", "url", "date", "id", "categories", "next", "previous", "tags", "path", "content", "excerpt"]

post_to_liquid_raw.rbto_liquid にこの引数を足せばエラーが解消できるみたい。

…と、こういうちょいなおしをするためにも直接持ってこないで fork した方が自由がきいてよいかという話。

関連記事(この記事の初版より古い記事はリンクがグレーで表示されます)

  1. 2013/08/07 [Ruby] [Jekyll] [Git] Jekyllバージョンアップの際に思いのほか手こずった話 Jekyll Bootstrapの更新に追従したい編
  2. 2013/05/27 [Jekyll] [Ruby] Jekyll@GitHub Pagesの運用形態を変えたのでAnalyticsの設定が効かなくなっていた
  3. 2013/05/23 [Jekyll] [Liquid] [Ruby] 記事の目次を出力するJekyllプラグインの改良
  4. 2013/05/21 [Jekyll] [Git] GitHub PagesでJekyllプラグインを使えるようにするには…
  5. 2013/04/11 [Ruby] [Jekyll] Jekyllのバージョンを 0.12.0 にあげた
  6. 2014/04/01 [Ruby] [Jekyll] [イベント] kawasaki.rb #010 で発表してきました #kwskrb
  7. 2014/01/28 [Jekyll] [GitHub] [Ruby] Jekyllプロジェクトへpull requestを行う手順(したとは言っていない)
  8. 2012/11/12 [Ruby] [Jekyll] はてなダイアリーのエントリをJekyllへ移行する
  9. 2012/10/10 [Jekyll] [Liquid] [Ruby] Jekyll(Liquid)で記事の目次を出力するプラグインを作ってみた
  10. 2012/09/21 [Python] [Ruby] [Jekyll] Pygmentsを使ってJekyll内記事のコードハイライトを実現する
  11. 2012/09/20 [Jekyll] [StartUp] [Ruby] JekyllをGitHub Pagesに上げるための準備
  12. 2012/09/14 [Ruby] [StartUp] [Jekyll] JekyllとJekyll Bootstrapでかんたん静的サイト生成…するための準備
  13. 2013/12/24 [Ruby] RubyでQRコードを生成してみる
  14. 2013/12/14 [Git] Gitの.git/objectsの中身を追ってみる
  15. 2013/11/25 [Jekyll] Jekyllのプラグイン作成で複数ファイルにまたがったタグをどう扱えばいいのかわからない話