Freeze (vendor, unpack) a single Ruby gem with and without Bundler
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.
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.
rake gems:refresh_specs will not do anything. Here is what you need to do:
- Copy the gem from
vendor/gems/foolib-1.2.3. Make sure the folder name actually ends in
cdto the gem. Check if a
foolib.gemspecexists. If it doesn't, run
gem build foolib.gemspec. This will create a
foolib-1.2.3.gempackage in the current directory.
gem specification foolib-1.2.3.gem > .specification. This will extract the YAML metadata from the gem package and create the missing
- We no longer need the gem package:
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')
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.
gem unpack since the gemspec will be missing. Use this instead:
rake gems:unpack GEM=cucumber_factory RAILS_ENV=test