BUNDLED WITH
って何?
bundler 1.10.0
以降で作成された Gemfile.lock
では、BUNDLED WITH
というセクションがあって、使用された bundler
のバージョンがトラックされるようになっている [3485] 。
例えば bundler 1.9.0
で作成された Gemfile.lock
のあるプロジェクト上で、 最新の bundler 1.10.3
を使用して bundle install --path vendor/bundle
すると、 Gemfile.lock
には以下の差分ができる。
+
+BUNDLED WITH
+ 1.10.3
これをもう一度 1.9.0
で bundle install
すると、上の文字はきれいさっぱり消える。
BUNDLED WITH
の何が困るか
多人数で開発するときには、この変更は微妙に邪魔で、意図しない Gemfile.lock
変更が出てしまうことで Gemfile.lock
にコンフリクトが出たり、本番環境の bundler
とのバージョン違いが顕在化してデプロイが失敗したり、あるいはローカルで bundle install
したせいで git pull
ができなかったりしそうに見える。まあ git checkout -- Gemfile.lock
すればいいけど、逐一やらねばならなくなってめんどくさい。
で、この変更が原因で、本家の issue がプチ炎上することになってしまったのだけど、その本家の issue を見ると今回の変更の意味がよくわかった。
本家が伝えたかったこと
- まず、
bundler
開発者としては、ユーザがどのバージョンでbundle install
したのかという情報は、大昔からトラックしたかったものだった。今回、多大な努力のうえでようやく実装することができた - 本家としては、以下のようなユースケースのフローを想定している
-
bundle install
すると、Gemfile.lock
内のBUNDLED WITH
を更新する(ただし、より新しい場合のみ) - 更新したら、他の
gem
をアップデートした場合とまったく同じように、Gemfile.lock
の更新をコミットする -
BUNDLED WITH
よりも古いバージョンのbundler
を使っている人は、BUNDLED WITH
の記述を更新しない。が、bundler
を更新するように注意書きが出る
-
- …というフローを想定していたが、現在は移行期のため以下のような問題が出ている
-
1.9.9
以前のbundler
ではGemfile.lock
内のBUNDLED WITH
を削除してしまう - だから
1.9.9
以前の人と1.10.0
以後の人とでgit
のやり取りをしていると、しょっちゅうファイルの変更が衝突してしまう - この問題は、全員が
1.10.0
以降になれば起こらなくなる
-
- 今回の変更はワークフローにこそ影響はあるかもしれないものの、
bundler
それ自体としては互換性を失う変更をしていないし、SemVerにも反していない - bundler開発者はめっちゃ頑張って開発者のためになるよう作り込んでるわけで、今回それで迷惑かけちゃってごめんね?
-
1.9
系のアップデートは出さない。出したところで1.10.X
以降にアップグレードしたほうが根本的解決になるから、1.9
系を利用し続ける意味はない - これでもなお問題となるものがあるようであれば、きちんとした形で教えてほしい
おこでした。
あ、ちなみに、『BUNDLED WITH
で指定されたバージョンの bundler
を起動する』機能は実装される可能性があるらしい。できたらめっちゃ素敵。
@suu_g の推奨対応
bundle install
に --frozen
オプションをつけよう。役に立つわりに長年ほとんど注目されることもなかった不遇のオプション1だが、ここに来てようやく報われるときが来たようだ。レリゴーだ。
bundle install
に --frozen
オプションをつけると、その手元では Gemfile.lock
を変更することはなくなる。このオプションは .bundle/config
に保存されるので最初の一回だけ指定すればいい。
凍結されたディレクトリでは、Gemfile.lock
に変更は行われないし、行われるような変更を許容しなくなるので、確実に Gemfile.lock
を適用したいというとき(デプロイ時)には非常に便利。
この状態で Gemfile
を変更しようとすると、「フリーズさせているので Gemfile.lock
が更新できません」と言ってくるようになる。開発環境では Gemfile
を変更したときには凍結を解除しなければならない、のだけど、その手段はちゃんと準備されていないのでちょっと不便。
You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.
If this is a development machine, remove the Gemfile freeze
by running `bundle install --no-deployment`.
上は Gemfile
に変更を加えて bundle install
を試したときの公式のメッセージ。 bundle install --no-deployment
でいいと書いているが、これは大嘘。素直に従ってこれを実行すると、以前に設定してあった BUNDLE_PATH
などのオプションをガン無視して system ruby 上に gem を install してしまう。危険。
だからこの場合は、.bundle/config
に書かれた設定を手動で削除するのがベストな方法だ。
---
BUNDLE_BIN: ".bundle/bin"
BUNDLE_FROZEN: '1' ## この行を消す
BUNDLE_PATH: ".bundle/gems"
BUNDLE_DISABLE_SHARED_GEMS: '1'
コマンドで設定を削除することもできる。こっちの方が簡単か。
$ bundle config --delete frozen
それと、 bundler
のバージョンを可能な限り 1.10
以降に上げよう。現在問題が起きているのは 1.9
以前と 1.10
とが混在しているからなので、それをすべて上げてしまえば問題は起こらなくなる。
1.10
で追加された BUNDLED WITH
だけど、これは 1.9
以前を通すと消えてしまう。それで編集コンフリクトが多発し、問題が大きく見えていたってだけのことだった。…というのは先述の通り。
さて、それでは開発者や本番環境に対して適用するべき具体的なものは何か、以下で説明していく。
各開発者のするべき対応
-
bundle install
時にはとにかくgem update
をする - 他の人のアップデートを見たら自分もアップデートする
-
Gemfile.lock
のBUNDLED WITH
行でコンフリクトしたらgit checkout -- Gemfile.lock; gem update bundler
する -
Gemfile.lock
のコミットには気を使う。git add .
とかせず、コミット単位を分けておく -
Gemfile.lock
は、内容をアップデートする意思のあるとき以外は極力変更しない。変更する気のないときは、手元環境でもbundle install
に--frozen
オプションをつけておく -
frozen
させたGemfile.lock
を変更するときは手動。.bundle/config
内にあるBUNDLE_FROZEN
の行を削除する
みんながこれやれば平和な開発チームになる。
本番環境でとるべき対応
-
bundle install
に--frozen
オプションを追加する
これに限る。無駄な更新をデプロイ先で行わせないこと、大事。
bundler
のオプション一覧を見ると --deployment
も気になるかもしれない。これは --frozen
と --path
とを組み合わせたオプションで、つまり以下のような挙動をしている:
-
vendor/bundle
以下に gem をインストールする(--path=vendor/bundle
) -
Gemfile.lock
を変更しないようになる(--frozen
)
初回ならこれを使っていくので問題ないが、 --path
指定を上書きされてしまう点には注意が必要。2
個人的な感想
BUNDLED WITH
に書かれたバージョンは増えこそすれ巻き戻ることはない仕様だそうなので、世の中の bundler がすべて 1.10.0
以降になれば状況はまた変わるでしょう。いまは狭間のタイミングだから混乱が起きているわけで。
それに、デプロイ先に --frozen
を使うようにすれば、現状これはほとんど問題にならなくなる。みんな手元の bundler をアップデートしたうえでデプロイ先では --frozen
しよう。Gemfile.lock
should never bother you anymore.
あとソフトウェア製作者への応援大事だし、自分の期待通りに動かなくなったからといってOSS作者に不満や修正要求をぶつけちゃダメ。自分で直してプルリク作ろう。まじ本家issue読んでると作者たちかわいそうになる。
そんな感じ。誰か私も応援してください。わぁいストック。
著者紹介
@suu_g
。バンドラーの記事をたまに書く人。まれに無線とかする。