When you need to patch an existing gem, one way is to "vendor" the gem by copying it into the vendor/gems
directory of your Rails project. You can then make any changes you require and Rails will use the vendored version of the gem after a server restart. Unfortunately you need to perform some additional steps to marry Rails and the copied gem. This notes describes what to do.
With Bundler
This is super-painful. If you just copy the gem to vendor/gems
, Rails will complain:
Unpacked gem foolib in vendor/gems has no specification file. Run 'rake gems:refresh_specs' to fix this.
Unfortunately, rake gems:refresh_specs
will not do anything. Here is what you need to do:
- Copy the gem from
/usr/lib/ruby/gems/1.8/gems/foolib-1.2.3
tovendor/gems/foolib-1.2.3
. Make sure the folder name actually ends in...-1.2.3
. -
cd
to the gem. Check if afoolib.gemspec
exists. If it doesn't, runrake gemspec:generate
- Run
gem build foolib.gemspec
. This will create afoolib-1.2.3.gem
package in the current directory. - Run
gem specification foolib-1.2.3.gem > .specification
. This will extract the YAML metadata from the gem package and create the missing.specification
file. - We no longer need the gem package:
rm foolib-1-2-3.gem
Now that you have a working gem in vendor/gems
, you need to tell Bundler about it. In your Gemfile
, change the gem's line to:
gem 'foolib', :path => File.join(File.dirname(__FILE__), '/vendor/gems/foolib-1.2.3')
Now run bundle install --local
to update your Gemfile.lock
. It should work now.
Fun fact: Our install-gems-remotely script is aware of vendored gems and will scp-copy them to the remoty server.
Without Bundler
Don't use gem unpack
since the gemspec will be missing. Use this instead:
rake gems:unpack GEM=cucumber_factory RAILS_ENV=test