2010/09/18

Gemfileにおけるgemspec指定

BundlerのGemfileにはgemspecという指定ができるらしいので動作を調べてみた。


ソースでの定義を読んでみると、どうやらGemfileと一緒においてあるgemspecファイルから依存関係を読み込んで、あたかもGemfileのその場にgemメソッドによる宣言がかかれているかのように振る舞ってくれるらしい。


つまりは、Gemfileに

gemspec name: 'foo'

とあり、同じディレクトリに foo.gemspec があって

Gem::Specification.new do |s|
:
  s.add_dependency 'nokogiri'
  s.add_development_dependency 'rspec', '~> 2.0.0.beta20'
:
end

などと書いてあれば、Gemfileに

gem 'foo'
gem 'nokogiri'
group :development do
  gem 'rspec', '~> 2.0.0.beta20'
end

と書かれたのと同じ意味になるということだ。DRY万歳!


指定できるオプションは

name:
gemspecの拡張子を除いたもの。省略すると * を指定したことになる。複数のファイルが該当するとエラーになってしまうので、1つだけ置いてある場合は省略してもよいが、何らかの理由で複数のgemspecが置いてあるときは明示的に指定するべき。
path:
gemspecが置かれているディレクトリ。省略すると . を指定したことになる。相対パスで指定した場合はGemfileを基点として解決される。
development_group:
開発環境とみなすべきグループ名。省略すると :development を指定したことになる。add_dependencyで指定されているものはグループ指定なし、add_development_dependencyで指定されているものはここで指定したグループに属する。


このうちdevelopment_groupオプションには、RSpecを使う場合に1つ問題がある。(Bundler 1.0.0の時点で)

Rails3では、config/application.rbの冒頭で

Bundler.require(:default, Rails.env)

という処理を行っており、Rails環境(production, development, test, etc.)をBundlerのグループ名として指定しているのだが、RSpecはdevelopment環境で使うジェネレータと、test環境の両方で必要になるため、何らかの方法でgroupを2つ指定する必要があるのだ。

ところが、development_groupオプションはBundlerのgroupメソッドにそのまま渡されるため、配列を指定することができない。

0 件のコメント:

Archives