tl;dr
- Bundler v1.10.0からBUNDLED WITHのsectionが導入された。
- restore_bundled_withを使うことで、Bundler開発チームの精神を逸脱して(!)、異なるversionのBundlerとBUNDLED WITHをうまく取り扱う。

Bundler v1.10 とBUNDLED WITH
Bundler v1.10.0からBUNDLED WITH
というsectionにbundle update
を実行したBundlerのversionを
記録するようになった。
日本語詳細はこちらが詳しい。
Ruby - BUNDLED WITH で Gemfile.lock が更新されてしまう件 - Qiita
挙動の確認
Bundler v1.10.2でbundle update
して、BUNDLED WITHにversionを記録しておく。
$ cat Gemfile.lock
GEM
remote: https://rubygems.org/
specs:
actionmailer (4.1.11)
actionpack (= 4.1.11)
(snip)
unicorn-worker-killer
webmock
BUNDLED WITH
1.10.2
Bundler v1.9.9で bundle update
BUNDLED WITHのsectionごと消える。悲しい。
$ bundle update
(update)
$ git diff
(snip)
@@ -289,6 +290,3 @@ DEPENDENCIES
unicorn
unicorn-worker-killer
webmock
-
-BUNDLED WITH
- 1.10.2
Bundler v1.10.4(新しい)で bundle update
BUNDLED WITHの記録を更新する。
$ bundle update
(update)
$ git diff
(snip)
@@ -291,4 +292,4 @@ DEPENDENCIES
webmock
BUNDLED WITH
- 1.10.2
+ 1.10.4
Bundler v1.10.1(古い)で bundle update
Warning出しつつ、BUNDLED WITHは更新しない。
$ bundle update
Warning: the running version of Bundler is older than the version that created the lockfile.
We suggest you upgrade to the latest version of Bundler by running `gem install bundler`.
(snip)
$ git diff
(no diff)
正しい解
まずは、Bundlerのversionをv1.10系の最新版に上げる。 そして、依存ライブラリのバージョンを上げていくと同時にBundlerも最新版が出るたびに上げていく。
現実解?
- そうは言っても、localではpreとかv2とか新しすぎるものも使いたい。
- 実際にproductionで実行するBundlerのversionと離れてしまいかねないのはいつか問題になりそう。
- Gemfileの中はBundler管轄だけど、Bundler自体はそこで管理してないわけで、lockの記述に引きずられるのはどうなんだろう(私見)
- minimalなbundlerのmini_bundler(仮)が薄くいて、bundle execなどのコマンドはその内側でバージョン管理されたbundlerで実行すればいい?(私見)
などの理由から、Bundler開発チームの精神を逸脱して(!)、restore_bundled_withというgemのrestore-bundled-with
コマンドを使う。
restore_bundled_with
Gemfile.lock
のBUNDLED WITHにリポジトリとdiffがある状態で、restore-bundled-with
コマンドを実行する。
つまり、bundle update
したあと、commitする前に、restore-bundled-with
する。
すると、リポジトリからBUNDLED WITHのsectionを取り出してきて、そこだけ元に戻る。
Bundler v1.9なら、消えたsectionが戻る。 より新しいBundler v1.10なら、使った記録がそこだけ戻る。
Example
Newer Bundler Case
$ cat Gemfile.lock
(snip)
unicorn-worker-killer
webmock
BUNDLED WITH
1.10.2
Execute bundle update
by Bundler v1.10.3.
$ bundle update
(update)
$ git diff
(snip)
@@ -291,4 +296,4 @@ DEPENDENCIES
webmock
BUNDLED WITH
- 1.10.2
+ 1.10.3
Then, execute restore-bundled-with
.
$ restore-bundled-with
(restore BUNDLED WITH section)
$ git diff
(no diff)
There is no diff, because this restores BUNDLED WITH
from git repository.
まとめ
Bundler開発チームの精神を逸脱するので、あまり推奨はしない。 最新版を使って、もし壊れていたらみんなで直していくのが、アプリケーションを健全に保つ一番痛みが少ない方法なのです!
詰まったら聞いてください。このサイトやREADMEなどに反映します。 ruby-restore_bundled_withにスターください!