アプリケーション本体や自動テストを実行するのに必要なgemは、開発者全員が同じものをインストールするべきだ。しかし、pry-*などの開発支援系のgemについては、開発者全員が同じものを使う必要はないのではないか1。
Bundlerの作法に従うと、自分が使いたい開発支援系のgemとGemfileに登録されているgemが食い違っている場合には、Gemfileを編集してbundle install
することになる。この操作を複数のプロジェクトで繰り返すのは面倒だ。また、自分好みの設定は手元だけで使いたいこともあるだろう。GemfileやGemfile.lockをVCSで管理しているときには、誤って変更をコミットしないように気をつけなければならない。
ここでは主に、bundle exec --
によるgemのバージョン固定の恩恵を受けながら、特定のgemだけはGemfileに登録せずに使う方法について解説する。
Bundler開発メンバーの見解
プロジェクト内で共有されるGemfileのほかに、個人的に使うgemを指定するGemfileが欲しいというissue(#183)が出されたことがある。多くの+1が集まったが、開発チームにはそのような複雑な機能を実装する余力はないとしてcloseされた。
解決方法
環境変数BUNDLE_GEMFILE
を使う
ruby - How to use gems not in a Gemfile when working with bundler? - Stack Overflowの回答を参考にした。
次のようなファイルをGemfile
と同じディレクトリに用意しておく。
# デフォルトのGemfileを読み込む
eval_gemfile "Gemfile"
# 自分が使いたいgemを宣言する
gem "pry-rescue"
gem "byebug"
BUNDLE_GEMFILE
を使って、bundlerにGemfile.local
をGemfileとして読み込ませる。
$ export BUNDLE_GEMFILE="Gemfile.local"
$ bundle install # Gemfile.local.lock が作られる(つまりGemfile.lockとは衝突しない)
$ set -u BUNDLE_GEMFILE bundle install # Gemfile.localを使いたくないときはこうする
Gemfile.local
とGemfile.local.lock
をcore.excludesfile
や.git/info/exclude
でgitの管理対象から除外すれば、リポジトリに自分用のGemfileやその痕跡が記録されることはない(参照: gitignore(5))。
デフォルトではBundlerはディレクトリを遡ってGemfile
を探索してくれるが、BUNDLE_GEMFILE
で指定するとFile.absolute_path(ENV['BUNDLE_GEMFILE'], Dir.pwd)
に相当するパスしか見てくれないことに注意。
関連
いずれも動作確認はしていない。
-
Local gems in your Gemfile - Antonio's ramblings - コマンドの実行前に
Gemfile.lock
がカレントディレクトリに存在するか確認して、BUNDLE_GEMFILE
を適当に設定してくれる。zsh依存のシェルスクリプト。- デフォルトの
Gemfile
を読み込ませたい場合は、Gemfile.local
がないサブディレクトリでbundle
を実行するか、env -u BUNDLE_GEMFILE bundle update
などとすればよさそう。
- デフォルトの
- Gemfile tools
Gemfile
から個人用のGemfileを読み込む
上記のスレッドではGemfile
から個人用のGemfile.local
を参照するという解決策も紹介されている。この方法だとGemfile.local
がGemfile.lock
に影響するので、Gemfile.lock
をVCSで管理している場合には適さない。
tDiary, Redmine, fluentdなどで採用されている(参考: Gemfile を編集せずに任意の gem を追加して開発する方法 - Gemfile.local メソッド - sonots:blog)。
pry-debundle
Gemfileに指定されていないgemをrequireできるようにするpryのプラグイン。このプラグインのコードそのものを.pryrc
に突っ込めばGemfileにpry-debundle
を追加しなくても使える。
上記の方法と違って、使いたいgemをgem install
するだけで済む。ただし、bundle exec
から起動するコマンドなど、pryのREPLを経由しないものは対象外。
git update-index --assume-unchanged
git update-index --assume-unchanged <files>
でファイルが変更されていないことにできる。
自分が使うgemを追加するだけならこれでも問題ないが、コミットしたい変更もあるときにはあまり役に立たない。
$ git update-index --assume-unchanged Gemfile Gemfile.lock # 変更されていないことにする
$ git update-index --no-assume-unchanged Gemfile Gemfile.lock # 戻す
そのほか
-
Adan Alvarado : Use pry with Bundler without having it on your Gemfile - irb AlternativesをGemfileに登録せずに使う方法。
bundler exec
を使わずにpryなどを起動して、後からBundler.setup
を使ってbundlerを有効にする。 -
Gemfile を編集せずに任意の gem を追加していじる2つの方法 - sonots:blog
- Gemfileを適当に書き換えたものを/tmpに置いて、それを
bundle --gemfile=...
やBUNDLE_GEMFILE
で参照する。 - 追加したいgemをrubyのsite_dirにインストールして、
RUBYOPT
を使って$LOAD_PATH
に追加する。
- Gemfileを適当に書き換えたものを/tmpに置いて、それを