bundlerでgithub上のunicornを強引に入れる

みんな、unicornをカスタマイズして使う時は、オフィシャルのgithubリポジトリ(defunkt/unicorn)からforkしていじると思う。
そしたらそれを↓こんな感じにbundlerから入れてみたいと思うのが人情

gem 'unicorn', :git => 'git://github.com/mirakui/unicorn.git', :ref => '〜〜'

でも、unicornのgemspecはbundler friendlyになってないので、このままだとインストール出来ない。なんでかっていうと

  • make等で生成される、gitリポジトリには含まれてないファイルがgemspecで呼ばれている
  • gem build時に'VERSION'環境変数が無いとエラーになるようになってる

から。

これを強引にbundler対応させる。以下のようにする。(unicorn-4.2.0前提)

1. defunkt/unicornをforkする

あきらかに汚い方法なので、自分のリポジトリとしてforkしてからやりましょう
https://github.com/defunkt/unicorn

2. unicorn.gemspecを修正

VERSION環境変数を無理やり指定する。

@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+ENV["VERSION"] = "4.2.0"
 ENV["VERSION"] or abort "VERSION= must be specified"
 manifest = File.readlines('.manifest').map! { |x| x.chomp! }
 require 'wrongdoc'

3. gem buildに必要なファイルをmakeする

$ make ragel
$ make .manifest

make ragelは、ext/unicorn_http/unicorn_http.rlからext/unicorn_http/unicorn_http.cを生成する。
make .manifestは、文字通り.manifestを生成する。このファイルにはリポジトリに含まれてるファイルの一覧が書かれる。
あと.manifestのmakeにはpandocが必要になると思う

4. .manifestを修正する

.manifestから、gemの使用には直接関係ないけど書かれていることによってビルドがこけるファイルをめんどうなので消す。ちゃんとそれぞれmakeしてもいいんだけど…
以下の6つを消せばいい。

5. git add -f 〜 git push する

.manifestとunicorn_http.cは.gitignoreに書かれているんだけど、強引にaddしちゃう。自分のリポジトリならいいよね。

$ git add -f .manifest ext/unicorn_http/unicorn_http.c
$ git commit
$ git push

6. 完成

ここまでやってpushしたリポジトリならbundle installできる。

# Gemfile
gem 'unicorn', :git => 'git://github.com/mirakui/unicorn.git', :ref => '〜〜'
$ bundle install

やりましたね

結論

こんな感じに、だいぶダーティにやらないといけないので、githubに置いたオレオレunicornをGemfileに書くのは現状厳しいと思う。別の手段がとれるなら(gemにして配布するとか)そっちを検討するべきだと思う

ちなみに

unicornは"v4.2.0"みたいなgit tagがそのリビジョンについてないと、unicorn-4.2.0.gemが生成できないようになってるみたい。ガッチガチですな