Gemfileについて調べてみた
Gemfileについてよくわかってなかったので調べてみた。
そもそもGemfileって?
Bundler用の設定ファイル。
BundlerはGemfileの記述にしたがって、gemの依存関係を示したGemfile.lockを生成する。
じゃあ、Bundlerって何さ?
アプリケーションで使用するgemのバージョン管理を行うプログラム。
「お前が書いたコード動かないんだけど?」
「ハァ? 俺の環境では動いてるし。バージョン違うんじゃねーの? 死ねよ」
ってならないためのツール。
Railsをはじめ、SinatraやRubyMotionでも使われている。*1
ちなみに、Bundlerの公式サイトにはこう書いてある。
The best way to manage your application's dependencies
ベストらしいので使わない手はない。
source
gemが置いてある場所を指定する。
Bundlerはこのsourceにgemのコードを取りに行く。
普段、Railsを使っていると自動挿入されるのであまり意識しないが、Gemfileには最低1つのsourceが指定されていないといけない。
ちなみに、RailsデフォルトのGemfileだとこう。
source 'https://rubygems.org'
さらに、これはURL文字列以外にもシンボルで書くことができる。*2
String | Symbol |
---|---|
http://rubygems.org | :rubygems |
http://gems.rubyforge.org | :rubyforge |
http://gemcutter.org | :gemcutter |
ruby
アプリケーションを実行するRubyのバージョンを指定できる。
ruby '1.9.3'
ハッシュの{key: value}記法を使っている場合などは指定しておいたほうがいいかもしれない。
ちなみに、引数にハッシュを渡すことによって、Ruby処理系を指定することができる。
ruby '1.9.3', engine: "jruby", engine_version: "1.6.7"
gem
gemコマンド*3で使用するgemを指定する。
例えば、アプリケーションでnokogiriを使いたい場合、次のように書く。*4
gem 'nokogirl'
バージョン管理
Bundlerはただのgemインストーラではなくバージョン管理ツール*5なので、このgemコマンドは第2引数にバージョンを取れる。
gem "nokogiri" # 最新版を入れる gem "rails", "3.0.0.beta3" # 3.0.0.beta3で固定 gem "rack", ">=1.0" # 1.0以降のバージョンに制限 gem "thin", "~>1.1" # 1.1以降2.0以前のバージョンに制限
他のオプション
gemコマンドは他にもいろいろなオプションをハッシュで渡せます。
ソースの取得先を指定
gem "nokogiri", git: "git://github.com/tenderlove/nokogiri.git", branch: "1.4" gem "nokogiri", path: "~/sw/gems/nokogiri"
自動的に読み込むファイルを指定
gem "nokogiri", require: "nokogiri" # default gem "redis", require: ["redis/connection/giredis", "redis"] gem "wirble", require: false # autorequireしない
group
groupコマンドではgemをインストールする環境を指定できる。
group :development, :test do gem "rspec-rails" gem "cucumber" end
のように設定した上で本番環境で
$ bundle install --without development test
とすると、developmentグループ及びtestグループのgemを除いてインストールを行うことができる。
こうなると、
$ bundle install --only test
とかが欲しいところだが、そういったオプションは用意されていない模様。
その他Bundlerのオプション
よく使うのはこんな感じ。
bundle install --path dir_name
$ bundle install --path vendor/bundle
Bundlerによってインストールするgemをデフォルト($BUNDLE_PATHまたは$GEM_HOME)のディレクトリ以外にする。一度指定するとBundlerがそのディレクトリを覚えてくれるため、次回以降は指定不要。
bundle install --system
$ bundle install --system
上記の--pathの逆。システムのデフォルトディレクトリにgemをインストールする。
*1:Bundler公式サイトには書いてなかったけどPadrinoでも使ってるっぽい。
*2:ただし、引数が:rubygems, :rubyforge, :gemcutterのいずれかの場合、どれを指定してもhttp://rubygems.orgを参照する。
*3:コマンドと書いたが、実際にはBundler::Dslクラスのインスタンスメソッド。sourceコマンドなども同じ。
*4:nokogiriはnokogirlでも入ります。俺のためにHTMLをパースしてくれるnokogirlたん萌え。
*5:こう書くとGitとかと紛らわしい。なんと呼べばいいんですかね?
*6:ステキすぎて鼻血でそう。
*7:シンボルで書くと、エラーを吐かれます。
*8:グループごとにまとめる場合はgroupコマンドのブロックの中に書いたほうがキレイ
*9:「rakeのバージョンがおかしい」とか言われたときに使うと高確率で幸せになれる。
*10:足りないアタマを使ってGitHubのコードも読んでみた。
*11:Bundlerのサンプルコードには:ciとかあった。