Ruby
Rails
bundler

もう一度bundle install, update について考え直してみた

More than 3 years have passed since last update.


もう一度Bundlerについて考え直してみた

みなさんご存知の通りBundlerはRuby/Railsにおけるgemのバージョン管理ツールです。

開発時にうかつにbundle updateを行ってしまって不具合が出たことをきっかけに、もう一度Bundlerについて、自戒の意味も込めて振り返ってみることにしました。

現在Gemをホスティングしているのは、RubyGems.orgです。

gemをインストール、アップデートするためにアクセスするリモートは常にここになります。

RubyGems.org | your community gem host

Fetching gem metadata from https://rubygems.org/............


Bundle install


1. Gemfile.lockがない時

つまり開発環境構築時などの、最初のbundle installの時ですね。

デフォルトでは、Bundlerはgem installと同じ場所にGemをインストールします。

もしGemfile.lockがまだ存在しない場合は、bundle installによって全てのリモートからのgemのインストール、依存問題の解決を行った後、Gemfile.lockが作成されます。

その中に実際にインストールされたgemのバージョンが記載されます。

◎coffee-railsを例に取って見てみましょう。

▼ gem coffee-railsのgem依存関係


coffee-rails.gemspec

s.add_runtime_dependency 'coffee-script', '>= 2.2.0'

s.add_runtime_dependency 'railties', '>= 4.0.0', '< 5.0'

bundle install後のGemfile.lock


Gemfile.lock

coffee-rails (4.1.0)

coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)


2. Gemfileに新たにgemを追加したとき

まずインストールのためにbundle installを実行することになると思います。

この時に初回のbundle installと異なるのは、追加されたgemのみのインストールと、そのgemの依存関係の解決が行われることです。

更新されていないgemに関してはGemfile.lockの依存関係を使用し、Gemfileが更新されたor内容が追加されたgemに関しては依存関係の解決が行われます。


3. GemfileもGemfile.lockも変えずにbundle install

リモートからgem再インストール。

インストールするバージョンと依存関係は現在のGemfile.lockを使用します。

つまり何も変わりません。


Bundle update


1. 引数なしでbundle update

引数なしで行うと、それまでインストールされたgemのバージョン、つまりGemfile.lockを無視して、リモートで利用可能な最新のgemをinstallしてきて、依存関係の解決を行うことになります。

全てのgemに対して行う結果、相当数のgemのバージョンが変更されるので、今まで開発していたアプリケーションの挙動が変わってしまう可能性があります。

何の考えも無しにbundle updateを行うのはやめましょう!


2. 特定のgemの新しいバージョンがリリースされて、そのgemのみを更新したい

シチュエーション的にはこちらが最も多いケースだと思います。

決め撃ちするにはbundle update nokogiri。これだけです。

この場合はnokogiriと、nokogiriが依存しているgemのみがアップデートされます。

アプリケーションに与える影響を少なくしたいなら、こうするべきでしょう。


まとめ


  1. その環境で実際にインストールされて使用されるgemのバージョンは、Gemfile.lockに記載されたものであること。


  2. bundle installでは同ディレクトリのGemfile.lockを使用するので、環境が変わっても同じgemのバージョンをインストールして使用できること。

  3. Gemfileはこれからインストールしたいgemの管理、Gemfile.lockは実際にインストールされたgemのバージョンの管理を担当していること。

なので、 githubのレポジトリやプロダクション環境では必ず開発で使用した特定のGemfile.lockが必要であることが分かります。その点に関しては分かりやすく下記のリンク先にまとめられています↓

ちょっと待った! Railsでgitリポジトリから除外すべきでないファイル:Gemfile.lockとdb/schema.rb | TechRacho


参考

http://ruby.studio-kingdom.com/bundler/bundle_install#conservative_updating

http://ruby.studio-kingdom.com/bundler/bundle_update