Docs header transparent bg

推奨されるワークフローとその根拠に関心がない場合は、下のまとめにスキップしてください。

Bundlerの目的と根拠

まず、アプリケーションのルートにあるGemfileというファイルにこれらの依存関係を宣言します。それは以下のようになります。

source 'https://rubygems.org'
gem 'rails', '4.1.0.rc2'
gem 'rack-cache'
gem 'nokogiri', '~> 1.6.1'

このGemfileはいくつかのことを示しています。まず、Bundlerはデフォルトでhttps://rubygems.orgで宣言されたgemを探す必要があることを示しています。一部のgemをプライベートなgemサーバーから取得する必要がある場合、これらのgemについてはデフォルトのソースを上書きできます。

次に、いくつかの依存関係を宣言します

  • railsのバージョン4.1.0.rc2
  • rack-cacheの任意のバージョン
  • nokogiri>= 1.6.1かつ< 1.7.0のバージョン

最初の依存関係のセットを宣言したら、Bundlerにそれらを取得するように指示します。

$ bundle install    # 'bundle' is a shortcut for 'bundle install'

Bundlerはrubygems.org(および宣言したその他のソース)に接続し、指定した要件を満たす必要なgemのリストをすべて見つけます。Gemfile内のすべてのgemには独自の依存関係があるため(そしてそれらの一部には独自の依存関係がある)、上記のGemfilebundle installを実行すると、非常に多くのgemがインストールされます。

$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Using rake 10.3.1
Using json 1.8.1
Installing minitest 5.3.3
Installing i18n 0.6.9
Installing thread_safe 0.3.3
Installing builder 3.2.2
Installing rack 1.5.2
Installing erubis 2.7.0
Installing mime-types 1.25.1
Using bundler 1.6.2
Installing polyglot 0.3.4
Installing arel 5.0.1.20140414130214
Installing hike 1.2.3
Installing mini_portile 0.5.3
Installing multi_json 1.9.3
Installing thor 0.19.1
Installing tilt 1.4.1
Installing tzinfo 1.1.0
Installing rack-test 0.6.2
Installing rack-cache 1.2
Installing treetop 1.4.15
Installing sprockets 2.12.1
Installing activesupport 4.1.0.rc2
Installing mail 2.5.4
Installing actionview 4.1.0.rc2
Installing activemodel 4.1.0.rc2
Installing actionpack 4.1.0.rc2
Installing activerecord 4.1.0.rc2
Installing actionmailer 4.1.0.rc2
Installing sprockets-rails 2.0.1
Installing railties 4.1.0.rc2
Installing rails 4.1.0.rc2
Installing nokogiri 1.6.1
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

必要なgemが既にインストールされている場合、Bundlerはそれらを使用します。必要なgemをシステムにインストールした後、BundlerはインストールしたすべてのgemとそのバージョンのスナップショットをGemfile.lockに書き込みます。

Bundlerを使用するためのアプリケーションの設定

Bundlerは、RubyがGemfile内のすべてのgem(およびそのすべての依存関係)を見つけられるようにします。アプリケーションがRailsアプリケーションの場合、デフォルトのアプリケーションには、Bundlerを呼び出すために必要なコードが既に含まれています。

別の種類のアプリケーション(Sinatraアプリケーションなど)の場合、gemをrequireする前にBundlerを設定する必要があります。アプリケーションがロードする最初のファイル(Sinatraの場合は、require 'sinatra'を呼び出すファイル)の先頭に、次のコードを記述します。

require 'bundler/setup'

これにより、Gemfileが自動的に検出され、Gemfile内のすべてのgemがRubyで使用できるようになります(技術的には、gemを「ロードパスに追加」します)。これは、require 'rubygems'にいくつかの追加機能を追加することと考えることができます。

コードがRubyで使用できるようになったので、必要なgemをrequireできます。たとえば、require 'sinatra'とできます。多くの依存関係がある場合は、「Gemfile内のすべてのgemをrequireする」ということができます。これを行うには、require 'bundler/setup'の直後に次のコードを記述します。

Bundler.require(:default)

この例のGemfileでは、この行は以下と完全に同等です。

require 'rails'
require 'rack-cache'
require 'nokogiri'

このような小さなGemfileの場合、Bundler.requireをスキップして、gemを手動でrequireすることをお勧めします。はるかに大きなGemfileの場合、Bundler.requireを使用すると、大量のrequireの繰り返しをスキップできます。

コードをバージョン管理にチェックインする

アプリケーションをしばらく開発したら、アプリケーションをGemfileおよびGemfile.lockスナップショットとともにチェックインします。これで、リポジトリには、アプリケーションが最後に確実に動作したことがわかっているときに使用したすべてのgemの正確なバージョンの記録があります。Gemfileには3つのgemのみがリストされていますが(バージョン厳密度の程度は異なります)、依存関係の暗黙的な要件をすべて考慮に入れると、アプリケーションは数十のgemに依存していることに注意してください。

これは重要です:Gemfile.lockは、アプリケーションを、独自のコードと、最後に確実にすべてが動作したときに実行されたサードパーティコードの両方の単一のパッケージにしますGemfileで依存するサードパーティコードの正確なバージョンを指定しても、gemは通常依存関係のバージョンの範囲を宣言するため、同じ保証は提供されません。

同じマシンで次にbundle installを実行すると、Bundlerは必要な依存関係がすべて既に存在することを確認し、インストールプロセスをスキップします。

.bundleディレクトリまたはその中のファイルはチェックインしないでください。これらのファイルは特定の各マシンに固有のものであり、bundle installコマンドの実行間でインストールオプションを永続化するために使用されます。

bundle packを実行した場合、バンドルに必要なgem(git gemを除く)はvendor/cacheにダウンロードされます。必要なすべてのgemがそのフォルダーに存在し、ソース管理にチェックインされている場合、Bundlerはインターネット(またはRubyGemsサーバー)に接続せずに実行できます。これはオプションの手順であり、ソース管理リポジトリのサイズが増加するため、推奨されません。

他の開発者とアプリケーションを共有する

共同開発者(または別のマシンのあなた)がコードをチェックアウトすると、最後に開発したマシンでアプリケーションが使用したすべてのサードパーティコードの正確なバージョン(Gemfile.lock内)が付属します。彼らbundle installを実行すると、BundlerはGemfile.lockを見つけて、依存関係解決手順をスキップします。代わりに、元のマシンで使用したのと同じgemがすべてインストールされます。

言い換えれば、インストールする必要がある依存関係のバージョンを推測する必要はありません。これまで使用してきた例では、rack-cacherack >= 0.4への依存関係を宣言していますが、rack 1.5.2で動作することを確実に知っています。Rackチームがrack 1.5.3をリリースした場合でも、Bundlerは常に1.5.2をインストールします。これは、動作することがわかっているgemの正確なバージョンです。これにより、すべてのマシンが常にまったく同じサードパーティコードを実行するため、アプリケーション開発者からの大きなメンテナンス負担が軽減されます。

依存関係の更新

もちろん、ある時点で、アプリケーションが依存している特定の依存関係のバージョンを更新したい場合があります。たとえば、rails4.1.0の最終バージョンに更新したい場合があります。重要なことは、1つの依存関係を更新しているからといって、すべての依存関係を再解決し、すべての一番新しいバージョンを使用する必要はないということです。この例では、依存関係は3つしかありませんが、この場合でも、すべてを更新すると複雑になる可能性があります。

例を挙げると、rails 4.1.0.rc2 gemはactionpack 4.1.0.rc2 gemに依存し、これはrack ~> 1.5.2(つまり、>= 1.5.2および< 1.6.0)に依存します。rack-cache gemはrack >= 0.4に依存します。rails 4.1.0の最終gemもrack ~> 1.5.2に依存しており、rails 4.1.0のリリース以降、Rackチームがrack 1.5.3をリリースしたと仮定します。

Railsを更新するためにすべてのgemを単純に更新すると、rails 4.1.0rack-cacheの両方の要件を満たすrack 1.5.3が得られます。ただし、rack-cacheを更新するように特に要求したわけではありません。これはrack 1.5.3と互換性がない可能性があります(理由は何であれ)。rack 1.5.2からrack 1.5.3への更新はおそらく何も壊しませんが、同様のシナリオで、さらに大きなジャンプが発生する可能性があります。(詳細については、下の[1]を参照してください)

この問題を回避するために、gemを更新するとき、Bundlerは、別のgemがそれに依存している場合、そのgemの依存関係を更新しません。この例では、rack-cacheは引き続きrackに依存しているため、Bundlerはrack gemを更新しません。これにより、railsを更新しても、誤ってrack-cacheが破損することはありません。rails 4.1.0の依存関係であるactionpack 4.1.0rack 1.5.2との互換性が維持されているため、Bundlerはそれをそのままにし、rack-cacherack 1.5.3との非互換性に直面しても引き続き機能します。

元々rails 4.1.0.rc2への依存関係を宣言していたため、rails 4.1.0に更新する場合は、Gemfilegem 'rails', '4.1.0'に更新して、以下を実行します。

$ bundle install

上記のように、bundle installコマンドは常に保守的な更新を実行し、Gemfileで明示的に変更していないgem(またはその依存関係)の更新を拒否します。これは、Gemfilerack-cacheを変更しない場合、Bundlerはそれをとその依存関係rack)を単一の変更不可能なユニットとして扱うことを意味します。rails 4.1.0rack-cacheと互換性がない場合、Bundlerは、スナップショットされた依存関係(Gemfile.lock)と更新されたGemfileの間の競合を報告します。

Gemfileを更新した場合、システムに必要な依存関係がすべて既に存在する場合、Bundlerはアプリケーションの起動時にGemfile.lockを透過的に更新します。たとえば、Gemfilemysqlを追加し、システムに既にインストールしている場合、bundle installを実行せずにアプリケーションを起動できます。Bundlerは「最後に既知の良好な」構成をGemfile.lockスナップショットに保持します。

これは、最小限の依存関係(データベースドライバー、wirbleruby-debug)を持つgemを追加または更新するときに役立ちます。依存関係が大きいgem(rails)、または多くのgemが依存するgem(rack)を更新すると、おそらく失敗します。透過的な更新が失敗した場合、アプリケーションは起動に失敗し、Bundlerはbundle installを実行するように指示するエラーを出力します。

Gemfileを変更せずにGemを更新する

Gemfileを変更せずに依存関係を更新したい場合があります。たとえば、rack-cacheの最新バージョンに更新したい場合があります。Gemfilerack-cacheの特定のバージョンを宣言しなかったため、rack-cacheの最新バージョンを定期的に取得したい場合があります。これを行うには、bundle updateコマンドを使用します。

$ bundle update rack-cache

このコマンドは、rack-cacheとその依存関係を、Gemfileで許可されている最新バージョン(この場合は、利用可能な最新バージョン)に更新します。他の依存関係は変更しません。

ただし、必要に応じて、他のgemの依存関係を更新します。たとえば、rack-cacheの最新バージョンがrack >= 1.5.2への依存関係を指定している場合、Bundlerはrack1.5.2に更新します。これは、rackを更新するようにBundlerに依頼していなくてもです。Bundlerが別のgemに依存しているgemを更新する必要がある場合、更新が完了した後に通知します。

Gemfile内のすべてのgemを可能な限り最新バージョンに更新する場合は、以下を実行します。

$ bundle update

これは、Gemfile.lockを無視して、依存関係を最初から解決します。これを行う場合は、git reset --hardとテストスイートをすぐに使えるように準備しておいてください。すべての依存関係を最初から解決すると、特に依存しているサードパーティパッケージの多くが最後に完全な更新を行ってから新しいバージョンをリリースしている場合、驚くべき結果になる可能性があります。

概要

シンプルなBundlerワークフロー

  • Railsアプリケーションを初めて作成すると、すでにGemfileが付属しています。別の種類のアプリケーション(Sinatraなど)の場合は、以下を実行します。

    $ bundle init
    

    bundle initコマンドは、編集可能なシンプルなGemfileを作成します。

  • 次に、アプリケーションが依存するgemを追加します。特定のgemのどのバージョンが必要かを気にする場合は、適切なバージョン制限を含めるようにしてください。

    source 'https://rubygems.org'
    gem 'sinatra', '~> 1.3.6'
    gem 'rack-cache'
    gem 'rack-bug'
    
  • まだシステムにgemがインストールされていない場合は、以下を実行します。

    $ bundle install
    
  • gemのバージョン要件を更新するには、まずGemfileを修正します。

    source 'https://rubygems.org'
    gem 'sinatra', '~> 1.4.5'
    gem 'rack-cache'
    gem 'rack-bug'
    

    次に、以下を実行します。

    $ bundle install
    
  • bundle installGemfileGemfile.lockの間の競合を報告する場合は、以下を実行します。

    $ bundle update sinatra
    

    これにより、Sinatra gemとその依存関係のみが更新されます。

  • Gemfile内のすべてのgemを可能な限り最新のバージョンに更新するには、以下を実行します。

    $ bundle update
    
  • Gemfile.lockが変更された場合は、常にバージョン管理にチェックインしてください。これは、アプリケーションを正常に実行するために使用したすべてのサードパーティコードの正確なバージョンの履歴を保持します。
  • コードをステージングまたは本番サーバーにデプロイするときは、まずテストを実行(またはローカル開発サーバーを起動)し、Gemfile.lockをバージョン管理にチェックインしていることを確認してください。リモートサーバーで、以下を実行します。

    $ bundle install --deployment
    

注記

[1] たとえば、rails 4.1.0rack 2.0に依存していた場合、そのgemはrack-cacheの要件(>= 0.4を依存関係として宣言)を満たします。もちろん、rack-cacheがオープンエンドのバージョンに依存するのは愚かだと主張できますが、これらの状況は(広範囲に)実際に存在し、プロジェクトはどのバージョンに依存するかを決定する際に板挟みになることがよくあります。依存関係をあまりにも制約すると(rack =1.5.1)、他の互換性のあるプロジェクトでプロジェクトを使用するのが難しくなります。制約が少なすぎると(rack >= 1.0)、Rackの新しいリリースがコードを壊す可能性があります。rack ~> 1.5.2のような依存関係を使用し、SemVerに準拠した方法でコードをバージョン管理することで、ほとんどの場合この問題は解決しますが、普遍的な準拠を前提としています。RubyGemsには10万を超えるパッケージがあるため、この前提は実際には成り立ちません。

エラーを見つけたり、何か不足していることに気づいた場合は、GitHubでこのドキュメントを編集してください