Railsプロジェクトでgemを変更しながら開発する場合、
- Gemfileに:pathでローカルのgemを指定
gem 'mygem', :path => '../mygem'
- gemを変更したらgem側をプッシュ
- 本体のプロジェクトのGemfileのgemの指定をリモート向けに戻して
bundle update mygem
- やっと本体のプロジェクトをコミット、プッシュ
- またGemfileに:pathでローカルのgemを指定
することになりますが、頻度が多いと面倒になります。
bundle local
以下のコマンドにより、Gemfileを変更する必要がなくなります。
$ bundle config local.mygem ../mygem
($ bundle config local.mygem /Users/user/path/to/mygem)
設定はプロジェクトごとではなく、グローバルになるようです。
$ cat ~/.bundle/config
---
BUNDLE_LOCAL__MYGEM: ../mygem
bundle実行時の出力は少し違うので、設定の違いを判断できます。
$ bundle
Using mygem (0.1.9) from git@github.com:hoge/mygem.git (at ../mygem)
gem側のブランチを複数扱ったりする場合や、古いリビジョンを参照したいなどの場合には、bundleコマンドの挙動やGemfile.lockの変化などが、自分の意図に反して混乱する可能性もあります。
その場合はおとなしく元に戻して、従来通り:pathを使う事をお勧めします。
~/.bundle/config
を消せば大丈夫なはずです。
Bundler 1.2から使えるようです。
その他、プロジェクトごとに指定できるかは未調査。
bundle local解除用alias
切り替えがしやすいように以下のようなaliasをおすすめ
alias bl_on='mv $HOME/.bundle_OFF $HOME/.bundle'
alias bl_off='mv $HOME/.bundle $HOME/.bundle_OFF'
次に述べる副作用の関係上、特にリリースなどに携わる人は良く理解して切り替えがすぐにできるようにしていることが望まれる
副作用
ローカルgemのプッシュし忘れ
考えられる副作用としては、gemをプッシュし忘れて、でもそれを参照する本体のプロジェクトは最新の状態でプッシュしたりしたときに、他のメンバーにとっては最新のgemが無く、プル+bundleするのに失敗するということが起こり得ると思います。
ローカルgemからのdependencyの追加
これはとても大切
特にリリース回りを担当する人は知っておかないと、リリース直前でなぜか起動できないとかいろいろ起こり得る
ローカルgem内の mygem.gemspec
に s.add_dependency 'some_shared_gem'
を追加したとする。
ローカルgemを含むプロジェクト側をただbundle install
しても、このdependencyは追加されない。何が問題となるかと言うと、ほとんどの場合追加されたdependencyはコード内でrequire 'some_shared_gem'
を必要とする。プロジェクト側でrails
でもrake
でも起動しようとすると、some_shared_gem
のLoad Errorになる。
対応方法は2つ
- bundle localを解除して、gem側もプッシュ済みの状態で作業をすすめる
- プロジェクト側で
bundle update mygem
する
(bundle update
した後も、意図しない他のdependencyのgemがアップグレードされないように注意もしないといけない。最近だとjquery-rails
は2.1.4と2.2系でjQuery自体のアップグレードになりプロジェクトが壊れる可能性がある)
その他
余談で、Rails界隈のすごい人たちが長い間議論してきて、いろいろなアプローチ、提案があったことをIssueから見て取れて面白いFeatureだと感じた。