Bundlerを使用したバージョンの管理

rakeアップデートは最近、バージョン0.8.7からバージョン0.9.0にリリースされました。これにより、コミュニティで多くのノイズが発生し、再びバージョン管理の問題が明らかになりました。 Bundler 1.0のリリース中に既に述べた主なポイントを繰り返し、状況を明確にしたいと思います。 最初に、単純な作業ルールについて説明し、次に詳細をもう少し詳しく説明します。



シンプルなバージョン管理



  1. bundle



    実行したら、Gemfile.lockをリポジトリに追加します。
  2. Gemfileを変更した後は、必ず最初にbundle install



    ください。これにより、Gemfile.lockが「保守的に」更新されます。 Gemfileで変更したgemのみが変更されます。 それ以外はすべてそのまま残ります。
  3. 「保守的な」更新が不可能な場合、Bundlerは、 bundle update [somegem]



    を行うように提案します。 このコマンドは、指定されたgemとそれに必要なすべての依存関係のみを更新します。 残りの宝石はそのまま残ります。
  4. すべての依存関係を最初から再解決する必要がある場合は、 bundle update



    を行う必要があります。
  5. 実行可能ファイルを実行するときは、 常に bundle exec [command]



    してこれを実行します。 ドキュメントからの引用: 場合によっては、このファイルがシステムにインストールされ、バンドルと競合する可能性のある依存関係をロードしないgemの一部である場合、 bundle exec



    なしでファイルを起動することができます。
    ただし、この方法は非常に信頼性が低く、多くの問題の原因です。 すべてが機能しているように見えても、明日または別のサーバーで機能するという事実ではありません。 次のセクション「実行可能ファイル」はこれについてです。
  6. 古いGemfile.lockをgit checkout Gemfile.lock



    または他のSCMの同様のgit checkout Gemfile.lock



    いつでも返すことができることに注意してください。




実行可能ファイル



gemをインストールすると、Rubygemsはgemに付属するすべての実行可能ファイルのラッパーを作成します。 ラッパーが起動すると、Rubygemsが起動し、標準のアクティベーションメカニズムを使用してgem自体が接続されます。 Rubygemsは、Gemfile.lockで別のバージョンが指定されている場合でも、システムインストールされている gemの最新バージョンを起動します。 さらに、Gemfile.lockで他のバージョンが指定されている場合でも、すべての gem 依存関係最新の(互換性のある)バージョンがアクティブ化されます。



これは、単純なコマンドとして実行可能ファイルを実行すると、Bundlerとそのすべての依存関係を単にバイパスすることを意味します。 開発者はすべてのgemの適切なバージョンを持っている可能性が高いため、これは問題ではない場合があります。 Gemfile.lockのほとんどはバージョン0.8.7にロックされていたため、Rakeは「正しい」バージョンを備えたそのようなgemの優れた例でした。



その結果、実行可能ファイルの直接起動はBundlerと互換性があり、それを使用して依存関係を解決するという誤解がありました。 Gemfile.lockからコンパイルされたgemsetは、本質的に環境のすべての実行可能ファイルが必要な依存関係バージョンで機能することを意味するため、問題が発生した場合、RVMのgemsetを使用することをお勧めします。



残念ながら、この松葉杖のため、人々はドキュメントからのアドバイスを無視し続けて、常にbundle exec



使用します。



コンソールでrake foo



と入力することでBundlerサンドボックスコードを実行すると信じる理由はありません。実際には、それはどのような方法にも関与せず、どこからも開始されないからです。 Bundlerは、ダウンロードの最初にアクティブにし、Gemfile.lockに規定されているgemの必要なバージョンをスリップすることでブートローダーを置き換えることができます。 実行可能ファイルを直接起動することで、Bundlerが依存関係接続プロセスに介入する前にルビーコードを実行します。 その結果、あなたが頼りにしているコードはまったく接続されていません。 これが発生すると、すべてが非常に予測不能になります。



bundle install --binstubs





bundle exec



でこれらすべてのダンスを何らかの形で容易にするために、Bundler 1.0は特別なフラグ--binstubs



提供します。これは、アプリケーションで使用されるすべてのgemの実行可能ファイルを入れるbinディレクトリを作成します。 したがって、たとえばbin/cucumber



実行することは、 bundle exec cucumber



コマンドと同等です。



binディレクトリは、実行可能ファイル用の「ポータブル」ラッパーを作成するため、リポジトリに安全に追加できます。



rails



チーム



上記の規則の唯一の例外はrails



コマンドです。 バージョン3.0以降、このコマンドは最初に現在のディレクトリからscript/rails



を実行しようとします。 そして、 script/rails



、最初にバンドラーを開始します

 #This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands'
      
      







boot.rb



ファイルの内容は、かなり重要です。

 require 'rubygems' # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
      
      







要するに、 rails



実行可能ファイルは、Bundlerサンドボックススタートアップロジックが最初からトリガーされ、 Kernel#exec



を使用して、gemがまだロードされている場合に現在のプロセスをオーバーロードすることを保証するために、可能な限りすべてを実行します。

この振る舞いはほとんどのアプリケーションgemにとって不可能であり、このハックを使用する価値があるかどうか、またbundle exec



を混乱させずにrails



を実行できるという事実bundle exec



さらに複雑かどうかという疑問が残ります。



All Articles