複数のプロジェクトでGemfileを共有する方法
require 'pathname' instance_eval (Pathname(__FILE__)+"another_project/Gemfile").read)
などとします。
なんでこんなことやりたいの?
Railsのプロジェクトをテストするためのプロジェクトを用意して、そっちでもRailsのモデルを読みたいのです*1。さらに、テストプロジェクトのためのライブラリがあって、そっちはRailsのほうのGemfileには含めたくない*2。
具体的には、FrankのテストをRailsとわけて管理したくて、さらにテストの方でiOSシミュレータの起動のためにsim_launcherが必要。
最初こうしました
load "another_project/Gemfile"
これはうまく行きません。loadすると、普通のトップレベルと同じ扱いになるので、gemとかのメソッドがないと言われます。
ではinstance_evalだ
instance_eval Pathname("another_project/Gemfile").read
これでひとまずはうまくいきます。
もう一つ落とし穴
実はテストの中で、
system("cd another_project && bundle exec rails server")
している場所がありました。
これがなんかうまく行かない。どうも、bundle execされたRailsがカレントディレクトリ(Railsプロジェクト)のGemfileではなく、テストプロジェクト(一個上のディレクトリ)のGemfileを読んでいるように見えます。
こういうわけで最初の形に落ち着きました。
バグじゃねーの?
ばぐってんじゃねーの?と思って、先日のHeroku MeetupでTerence Leeに聞いたのですが、これが意図された挙動なのだそうです。bundlerは、上のディレクトリまでGemfileを探しにいって、一番上のGemfileを使います。(しかし本当に便利なのかなこれ。)
Gemfileを指定するには、
system("BUNDLE_GEMFILE='./Gemfile' bundle exec rails server")
などとして指定すればokです。