3

I'm splitting a large application into multiple smaller ones. When doing this I realized that by creating a Gemfile.global and including it in both my main and sub applications I could clean up all of my Gemfiles. For example, all of my deployment gems go in the main Gemfile, and my rails goes in the Gemfile.global.

It works for pretty much all of my gems except one: Squeel.

My Gemfile in the root app starts off with:

gemfiles = [
  File.join('Gemfile.global'),
]
Dir.glob(File.join(File.dirname(__FILE__), gemfiles)) do |gemfile|
  eval(IO.read(gemfile), binding)
end

# gem 'squeel' # Let's try putting this in Gemfile.global

My Gemfile.global looks like:

source 'https://rubygems.org'
# rails and dependencies
gem 'squeel'

bundle install works great, as well as rails s and pretty much everything, the way you'd expect, with Squeel in the main Gemfile. Putting it in Gemfile.global, however, screws up the initialization process when using the default Squeel initializer:

Squeel.configure do |config|
end

rails s throws a uninitialized constant Squeel (NameError) even though bundle install reports Using squeel (1.0.13). Why does this method of composing my Gemfile mess up the rails runtime constants?

Chris Keele
  • 3,364
  • 3
  • 30
  • 52
  • After further inspection this totally screwed all of my gem's access to constants up. I'm back to the traditional way, but I'm curious as to why this happens/alternative approaches to composable Gemfiles. – Chris Keele Dec 09 '12 at 01:45
  • I strongly suspect that you and I are running up against slightly different manifestations of the same phenomenon... http://stackoverflow.com/questions/16554397/rake-build-is-operating-in-an-incorrect-context – Brad Werth May 16 '13 at 04:56
  • I think so. I'm about to dive into some of bundler's source this week, maybe I'll have an epiphany. – Chris Keele May 16 '13 at 17:51
  • Right on - good luck! – Brad Werth May 16 '13 at 20:43

2 Answers2

7

Use instance_eval instead of eval when loading Gemfile.global into your Gemfile. i.e. your project Gemfile should look like below (removing File.joins to avoid confusion):

gemfiles = [ 'Gemfile.global' ]
gemfiles.each do |gemfile|
  instance_eval File.read(gemfile)
end
Subhas
  • 14,290
  • 1
  • 29
  • 37
5

You can also use eval_gemfile:

gemfiles = [ 'Gemfile.global' ]
gemfiles.each do |gemfile|
  eval_gemfile gemfile
end
kross
  • 3,627
  • 2
  • 32
  • 60