There's an echo in my head

日々のメモ。

分割したGemfileを読み込むときにはeval_gemfileを使う

https://r7kamura.com/articles/2022-06-13-eval-gemfile で紹介されているとおりなんだけど、 Gemfile を複数ファイルに分割して読み込むときには eval_gemfile を使うと良い。

例えば

your-app
├── gemfiles
│    └── Gemfile.common.rb # 複数 Gemfile 間で共通の gem が宣言されている
└── Gemfile # Gemfile.common.rb に加えて追加の gem が宣言されている

みたいな構成をしているとき、 your-app/Gemfile には次のように記述できる。

eval_gemfile "gemfiles/Gemfile.common.rb" # 相対パスで指定できる

gem "foo"

これは次のような eval を使った書き方とほぼ同一である。

eval File.read(File.expand_path("../gemfiles/Gemfile.common.rb", __FILE__))

gem "foo"

ただし、 dependabot を利用している場合には eval_gemfile を使う必要がある。これは、 dependabot が読み込むファイルをリストアップする際に eval_gemfile を使って依存関係を辿る(今回だと Gemfile.common.rb の存在を検知する)*1ためである。

もし eval_gemfile を使っていない場合には、このリストアップ対象から除外され、 dependabot の処理対象から除外されて次のようなエラーが発生する。

Bundler::Dsl::DSLError with message: [!] There was an error parsing `Gemfile`: No such file or directory @ rb_sysopen - dependabot_tmp_dir/gemfiles/Gemfile.common.rb. Bundler cannot continue.
このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。