複数Gemfileを使いたいときのDual Boot
Railsで書かれたWeb applicationなりgemなりを書いているとGemfileを複数扱いたいシーンが出てくる
これを実現するテクニックをDual Bootと呼んでいる
Gemfile の Dual Boot 方法
Gemfile 内で切り替える
各環境の Gemfile を用意する
どちらも一長一短あるとしたうえで以下のパターンを紹介
Gemfileのsymlinkをつくる
Getting Ready for Rails 6.0: How to Dual Bootで紹介されている方法
$ ln -s Gemfile Gemfile.next で新バージョンのGemfileのsymlinkをつくる
Gemfile内で自身のファイル名を見て分岐させる
code:Gemfile
def next?
File.basename(__FILE__) == "Gemfile.next"
end
source 'https://rubygems.org'
if next?
gem 'rails', '~> 6.0.0'
else
gem 'rails', '~> 5.2.3'
end
lock ファイルは Gemfile.next.lock になる
Gemfile だけで一元管理できる
bootboot gemを使う
https://github.com/Shopify/bootboot
基本的にはsymlinkの方式と類似するが、symlinkを使わずにbundler pluginを使う
DEPENDENCIES_NEXT環境変数が与えられたときだけGemfile_next.lockを生成したり使ったりする
code:Gemfile
if ENV'DEPENDENCIES_NEXT'
gem "rails", "~> 5.2.0"
else
gem "rails", "~> 5.1.0"
end
単純にプラットフォームで分岐させたいならbundler install_ifでもよい
事例
https://github.com/sorbet/sorbet/issues/4119#issuecomment-1575418375
Ubuntu Linux on ARM64 (aarch64) でSorbetが動かない問題のため、ローカルでのみインストールさせてDocker環境ではインストールさせないというeval_gemfileで回避策をとっている
https://speakerdeck.com/mtsmfm/canary-release-in-studysapuri
ちょっと違うけどアプリケーションのディレクトリ自体をsymbolic linkにして楽をしていた