WEBサービス創造記

WEBサービスを作ったり保守したりしてる人のメモブログです。

bundlerを利用したgemの管理

      2015/06/13

bundlerとは

よくRailsアプリを開発中に、”bundle install”などで利用しているbundlerは、RubyGemsのラッパーである(RubyGemsはRubyのパッケージ管理システムでPerlでのCPAN・PHPでのPEARに相当する)。
つまり、Gemを管理するためのGemがbundlerであるといえる。

bundlerはアプリケーションが利用するGemパッケージの依存関係を再帰的に解決してくれる。
また、アプリケーション毎に独立してGemをインストールしてシステムのGemと分けることができる(環境を汚さない)。

Rails3で新規にプロジェクトを作成した場合、自動的にbundlerでGemを管理するようにようになっている。
試したことはないが、Railsアプリケーション以外でも使えるらしい。

bundlerには0.9系(stable)と1.0系(beta)があって、それぞれ使い方が異なる(0.9では”gem bundle”コマンドで動作させるなど)。
特に理由がなければ1.0系がおすすめ。

bundlerがまだインストールされていない場合は、下記コマンドで最新版をインストールできる。

$ gem install bundler --pre

bundlerの使い方

Gemfileとbundle install

Railsアプリのルートには、Gemfileというファイルがある。

“bundle install”を実行すると、bundlerがGemfileに記述されているgemの依存関係を解消し、その結果をGemfile.lockに出力し、その上で必要なパッケージをインストールしてくれる。

Gemfileをテキストエディタで開いてみると、以下のような書式になっている。

source 'http://rubygems.org'

gem 'rails', '3.1.0'

# Bundle edge Rails instead:
# gem 'rails',     :git => 'git://github.com/rails/rails.git'

gem 'sqlite3'
〜以下省略〜

“source URL”でgemファイルのソースを取得するリポジトリを指定する。
sourceで最低一箇所はリポジトリを指定しなければいけない。Rails3.1でのデフォルトのsourceは上記の通り。

gem から始まる1行では、以下のような書式でインストールするgemを指定している。

gem 'gem名', 'バージョン'

バージョンは省略することができる。
省略した場合は、最新のバージョンをインストールされる。

なお、RailsではGemfile.lockに記載されたgemのみを利用することになり、Gemfile.lockに記載がない gem を require しようとしてもできないようになっている。

“bundle install”実行後はWEBrickやApacheを再起動する必要がある。

bundlerでインストールしたgemの管理

下記コマンドでインストールしたgemファイルの一覧を確認できる。

$ gem list
$ echo $GEM_HOME
/home/hoge/.rvm/gems/ruby-1.9.2-p290@rails3

このコマンドで表示されるGemは、$GEM_HOME という環境変数が指定した場所にインストールされているものである。
これは所謂”システムにインストールされたGem”である。

通常、”bundle install”コマンドを使うと、 Gemfile に書かれたgemは $GEM_HOME 以下にインストールされる。
すべてのGemを $GEM_HOME 以下にインストールすると、管理するRailsアプリが増えてきた場合などに、システムのgemとごっちゃになって管理が煩雑になる。

それを避けるため、”bundle install”するときに、引数でインストール先のパスを指定するといい。
例えば、railsアプリのルートディレクトリで”bundle install –path vendor/bundler”を実行すると、vendor/bundler 以下にgemがインストールされる。

$ cd /path/to/railsapp
$ bundle install --path vendor/bundler

一度上記コマンドのようにインストールディレクトリを保存すると.bundle/configというファイルに設定が保存され、以降は”bundle install”でパスの指定をしなくてもvendor/bundlerにインストールされるようになる。

cat .bundle/config
---
BUNDLE_PATH: vendor/bundler
BUNDLE_DISABLE_SHARED_GEMS: '1'

ちなみに、このようにvendor/bundlerにgemをインストールするように指定した場合で、インストールするgemがすでに$GEM_HOME以下にインストールされている場合は、インストールはスキップされる。
これを回避するには”–disable-shared-gems”オプションを付加する。

$ bundle install --path vendor/bundler --disable-shared-gems

また、bundlerでインストールしたgemを利用してrubyを実行したい場合は、以下のように”bundle exec”を接頭辞につける。

$ bundle exec ruby your-script.rb

 - Ruby , ,