タイトルの通りなのですが、普通にやると意図した動きしなかったのでメモ。
具体的な例
factory_bot が分かりやすいです。
- ルートディレクトリに Gemfile.lock がある
- ルートディレクトリで
bundle install
はしてある - ルートディレクトリから
gemfiles/6.0.gemfile
を使って "bundle install" したい- Kernel.#system を使って
具体的なコマンドは以下の通り。
$ git clone --depth 1 https://github.com/thoughtbot/factory_bot.git $ cd factory_bot $ bundle install $ bundle exec ruby -e 'system({ "BUNDLE_GEMFILE" => "6.0.gemfile" }, "bundle check", chdir: "gemfiles/")' Could not find zeitwerk-2.1.9 in any of the sources Run `bundle install` to install missing gems.
動くコマンド
bundler経由で実行すると RUBYOPT="-r/usr/local/lib/ruby/2.7.0/bundler/setup"
がセットされるので、これを上書きすると動く。
$ bundle exec ruby -e 'system({ "BUNDLE_GEMFILE" => "6.0.gemfile", "RUBYOPT" => ""}, "bundle check", chdir: "gemfiles/")' The following gems are missing * zeitwerk (2.1.9) * childprocess (2.0.0) * aruba (0.14.11) * simplecov (0.17.0) Install missing gems with `bundle install`
bundle install
する前なので、正しく 6.0.gemfile
を参照してる挙動になった。
追記
Bundler.with_clean_system を使う方法を Twitter で教えてもらった。
@sinsoku_listy https://t.co/ad4FKqHnV8
— はくどー (@HKDnet) 2020年1月18日
この記事なのですが、Bundler.with_clean_env/clean_system を使うのがいいんじゃないかなあと思いました
ref: https://t.co/SfW3Pqk7Y2
こっちの方がシンプルで、良いですね!