withオプションで特定環境でだけgemをinstallさせる
February 18, 2017
bundler
には with
というオプションがあります。
これは v1.10 から追加されたオプションです。
それより前から、指定グループの gem のインストールをスキップさせるために without
というオプションがありました。
with
はその逆で、指定のグループをインストールさせたいときに使います。
例えば、
source 'https://rubygems.org'
gem 'aws-sdk'
group :test do
gem 'faker'
end
group :ci, optional: true do
gem 'rugged'
end
という Gemfile を考えてみます。
ci
グループには optional: true
という引数がついていますが、一旦気にせずに先に進みましょう。
bundle install
すると、
$ bundle install --path=vendor/bundle
Fetching gem metadata from https://rubygems.org/............
Fetching version metadata from https://rubygems.org/.
Resolving dependencies...
Installing aws-sigv4 1.0.0
Installing jmespath 1.3.1
Installing i18n 0.8.0
Using bundler 1.14.4
Installing aws-sdk-core 2.7.11
Installing faker 1.7.3
Installing aws-sdk-resources 2.7.11
Installing aws-sdk 2.7.11
Bundle complete! 3 Gemfile dependencies, 8 gems now installed.
Bundled gems are installed into ./vendor/bundle.
となります。aws-sdk
はもちろん、 test
グループの faker
もインストールされます。
しかし、ci
グループの rugged
のインストールはスキップされます。
では、次に--with ci
オプションでインストールしてみましょう。
$ bundle install --path=vendor/bundle --with ci
Fetching gem metadata from https://rubygems.org/............
Fetching version metadata from https://rubygems.org/.
Using aws-sigv4 1.0.0
Using jmespath 1.3.1
Using i18n 0.8.0
Installing rugged 0.25.1.1 with native extensions
Using bundler 1.14.4
Using aws-sdk-core 2.7.11
Using faker 1.7.3
Using aws-sdk-resources 2.7.11
Using aws-sdk 2.7.11
Bundle complete! 3 Gemfile dependencies, 9 gems now installed.
Bundled gems are installed into ./vendor/bundle.
今回は、rugged
もインストールされました。
つまり、optional: true
のグループの gem は、with
オプションの指定がある時のみインストールされます。
どこで使うか?
いろいろユースケースはあると思うのですが、私はCI環境で特定の gem をインストールするために使っています。
例にあげた rugged
というのは ruby から git を使うためのライブラリです。
CIによるビルド処理の中で、git log を解析してバグが起きやすそうなファイルをPRのコメントで指摘する仕組みを運用しているのですが、その中で使われています。
つまり、rugged
はCI環境でしか使われません。
rugged
をインストールするには CMake
が必要です。
OS X環境であれば、brew install cmake
の実行が必要となります。
rugged
はCI環境でしか使われないのにも関わらず、単純に Gemfile に追加すると、開発環境に一つ依存関係を追加してしまうのです。
これを避けるために、optional: true
で開発環境でのインストールを回避しています。
参考までに、circleci でもし with
オプションを使いたいなら、
dependencies:
pre:
- bundle config --local with ci
としましょう。