bundle-exec
- バンドルのコンテキストでコマンドを実行する
bundle exec
[--keep-file-descriptors] command
このコマンドは、Gemfile(5)
で指定されたすべてのgemをRubyプログラムでrequire
できるようにして、コマンドを実行します。
基本的に、通常rspec spec/my_spec.rb
のように実行するものを、Gemfile(5)
で指定され、bundle install(1)でインストールされたgemを使用したい場合は、bundle exec rspec spec/my_spec.rb
を実行する必要があります。
bundle exec
は、実行ファイルがシェルの$PATH
上に存在することを要求しません。
--keep-file-descriptors
bundle install(1)で--binstubs
フラグを使用すると、バンドル内のgemから利用可能なすべての実行ファイルを含むディレクトリ(デフォルトはapp_root/bin
)が自動的に作成されます。
--binstubs
を使用した後、bin/rspec spec/my_spec.rb
はbundle exec rspec spec/my_spec.rb
と同一になります。
bundle exec
はシェル環境にいくつかの変更を加えた後、指定したコマンドを完全に実行します。
bundle exec
によって呼び出されたコマンド内からbundle
にシェルアウトできることを確認します($BUNDLE_BIN_PATH
を使用)。rails
、rspec
、rackup
など)を含むディレクトリを$PATH
に追加します。Gemfile
を使用することを確認します(BUNDLE_GEMFILE
を設定)。$RUBYOPT
に-rbundler/setup
を追加します。これにより、サブシェルで呼び出されたRubyプログラムがバンドル内のgemを参照できるようになります。また、Rubygemsも変更します。
Gem::LoadError
を発生させるように変更します。Gem.refresh
を無操作とし、システムのgemが環境に漏れるのを防ぎます。Gem.bin_path
をオーバーライドし、システムの実行ファイルが機能するようにします。最後に、bundle exec
は、lockファイルとGemfileが一致しない場合、Gemfile.lock
を暗黙的に変更します。バンドラーは、gemのグループ、autorequire
、プラットフォームなどの情報を決定するためにGemfileを必要とし、その情報はlockファイルには保存されていません。bundle exec
を正常に実行するには、Gemfileとlockファイルが同期している必要があるため、bundle exec
は事前にlockファイルを更新します。
デフォルトでは、RubyのShebangを持つファイルにbundle exec
を実行しようとすると、BundlerはKernel.exec
を使用する代わりに、そのファイルをKernel.load
します。ほとんどの場合、これはパフォーマンスの向上になります。まれに、これにより微妙な副作用($0
または__FILE__
の正確な内容への依存など)が発生する可能性があり、disable_exec_load
設定を有効にすることで最適化を無効にできます。
サブシェルを開くRubyコード(system
、バッククォート、または%x{}
など)は、自動的に現在のBundler環境を使用します。現在のバンドルに含まれていないRubyコマンドにシェルアウトする必要がある場合は、ブロックを使用してwith_unbundled_env
メソッドを使用します。ブロック内で作成されたサブシェルには、Bundlerがアクティブになる前の環境が与えられます。たとえば、HomebrewコマンドはRubyを実行しますが、バンドル内では機能しません。
Bundler.with_unbundled_env do
`brew install wget`
end
別のバンドルにシェルアウトする必要がある場合も、with_unbundled_env
を使用する必要があります。サブシェルで実行されるバンドラーコマンドは現在のGemfileを継承するため、別のバンドルのコンテキストで実行する必要があるコマンドもwith_unbundled_env
を使用する必要があります。
Bundler.with_unbundled_env do
Dir.chdir "/other/bundler/project" do
`bundle exec ./script`
end
end
Bundlerはsystem
とexec
をラップする便利なヘルパーを提供しており、次のように使用できます。
Bundler.clean_system('brew install wget')
Bundler.clean_exec('brew install wget')
現在、Rubygemsプラグインシステムは、Rubyコードがrubygems.rb
をrequireすると、インストールされたgemのロードパス上のすべてのrubygems_plugin.rb
という名前のファイルを必要とします。これには、rails
、rackup
、rspec
など、システムにインストールされた実行ファイルが含まれます。
Rubygemsプラグインには任意のRubyコードを含めることができるため、通常はそれ自体またはその依存関係をアクティブ化します。
たとえば、gemcutter 0.5
gemはjson_pure
に依存していました。このバージョンのgemcutterがインストールされている場合(この問題のない新しいバージョンもインストールされている場合でも)、Rubygemsはgemcutter 0.5
とjson_pure <latest>
をアクティブ化します。
あなたのGemfile(5)にもjson_pure
(またはjson_pure
に依存するgem)が含まれている場合、システム上の最新バージョンはGemfile(5)内のバージョン、またはGemfile.lock
のスナップショットバージョンと競合する可能性があります。
これが発生した場合、バンドラーは次のように表示します。
You have already activated json_pure 1.4.6 but your Gemfile
requires json_pure 1.4.3. Consider using bundle exec.
この状況では、問題のあるgemプラグインを持つ基になるgemを削除する必要があります。一般的に、これらのプラグインの作者(この場合はgemcutter
gem)は、より注意深いプラグインを持つ新しいバージョンをリリースしています。
gemプラグインを含むすべてのgemのリストは、次を実行して見つけることができます。
ruby -e "puts Gem.find_files('rubygems_plugin.rb')"
少なくとも、各gemプラグインの最新バージョンを除くすべてを削除し、使用していないgemプラグイン(gem uninstall gem_name
)もすべて削除する必要があります。