rubygems-bundlerのしくみ
https://github.com/mpapis/rubygems-bundler
rubygems-bundlerを入れると、bundle exec
がいらなくなるということを知りました。
どうやってbundle exec
を省略できるようにしてるのかわからなかったので、調べてみました。
結論としては、gem
がインストールした実行ファイルの shebang を書き換えることで、フックしてます。
たとえば rbenv を使ってて、rakeをインストールすると、 /home/hoge/.rbenv/versions/2.1.1/bin/rake
のようなパスに実行ファイルが作られます。
このファイルのshebangは、通常
#!/usr/bin/env ruby
なんですが、gem regenerate_binstubs
を実行すると、これらのファイルのshebangだけを
#!/usr/bin/env ruby_executable_hooks
と書き換えてしまいます。
この ruby_executable_hooks
というのが各Gemの中に lib/rubygems_executable_plugin.rb
というのを探して、あればそれを実行します。
rubygems-bundler
の rubygems_executable_plugin.rb
は、カレントディレクトリからルートにむかって Gemfile
を探し、あればそのファイルを使って Bundler.setup
を呼び出します。
こうして bundle exec
をつけずに rake を実行しても、 bundle exec
をつけて呼び出したのと同様の効果を実現してます。
gem regenerate_binstubs
コマンドを提供している executable-hooks
は、Gemがインストールされるときにフックを走らせることで、以後は、実行ファイルを提供するGemがインストールされるごとに、自動で shebang を書き換えます。