Bundler 2.5.10(2024年5月リリース)で導入された auto_install 設定をオンにすると、 bundle exec などのコマンドが自動的に足りない gem をインストールするようになる。有効にする方法は以下の通り:
# .bundle/config にプロジェクト固有設定を書き込む
bundle config auto_install true
# or ~/.bundle/config にグローバル設定を書き込む
bundle config --global auto_install true
# or 環境変数で制御する
export BUNDLE_AUTO_INSTALL=1
設定を有効にするかスクリプトの shebang 行で環境変数をセットするようにすれば、表題のような自動インストールが実現できる:
#!/usr/bin/env -S BUNDLE_AUTO_INSTALL=1 bundle exec ruby
Dir.chdir(__dir__) do
# ↑一時的に Gemfile があるディレクトリに移動する
# 今回はスクリプトと同じディレクトリにある想定
# 場所が違うなら __dir__ の部分を適切なパスに変えること
Bundler.require
end
# 以降の処理……
何らかの理由で shebang 行が変更できない場合か、 env が -S オプションをサポートしていない環境では、以下のようにも書ける。
#!/usr/bin/env ruby
require 'bundler'
# これがないと `Bundle.auto_install` を呼んでも何も起きない
ENV['BUNDLE_AUTO_INSTALL'] = '1'
Dir.chdir(__dir__) do
Bundler.auto_install
Bundler.require
end
# 以降の処理……
さらに Ruby バージョンマネージャのひとつである rv を shebang 行で使えば、指定したバージョンの Ruby を自動でインストールするところから行ってくれる。
#!/usr/bin/env -S BUNDLE_AUTO_INSTALL=1 rv run --ruby=4.0 bundle exec ruby
Dir.chdir(__dir__) do
Bundler.require
end
# 以降の処理……
補足
Bundler が生成する binstub は上記の chdir ブロックを使わず require 'bundler/setup' 1行で済ませている。これでもほとんど問題はないが、カレントディレクトリが Gemfile のある場所かその子孫ディレクトリでしか動かないという制約がある。