How do I vendorize gems for Rails3/Bundler
In Rails 2.X, I could simply copy gems into vendor/gems/gem_name
, or use the rake command rake gems:unpack
. Since Rails3 uses bundler, it doesn't appear to work anymore. I have found the command bundle package
, but it doesn't work the same way.
Edit:
So, just to elaborate a bit on this:
The way that rails 2 worked, I could easily grep to find stuff in vendor/gems
. If they are bundled up in .gem
files, that isn't possible. Also, when developing a gem/plugin, it's very helpful to have it placed within a rails application to test it out in context. How would I do such things with bundler/rails3? Is my workflow inherently broken somehow?
Solution 1:
Answering the second part of your question, developing a plugin/gem and shipping it with the rails app without making the gem publicly available, you may do this
Gemfile
gem 'my_private_gem', :path => "vendor/gems/my_private_gem-VERSION"
assuming you performed a gem unpack my_private_gem --target vendor/gems
note: bundle package unpacks all gems (as many as in Gemfile.lock). I wouldn't want those in git.
Solution 2:
The Bundler equivalent is bundle package
. It packages all of the .gem files specified in the Gemfile into vendor/cache
so that future installs get the gems from this cache rather than from http://rubygems.org/
Solution 3:
The correct Bundler equivalent is bundle install --deployment
. This will install the gems, in their unpacked state, in vendor/bundle
.
Solution 4:
This is what worked for me:
gem unpack <GEM_NAME> [-v <VERSION>] --target vendor/gems
gem specification <GEM_NAME> [-v <VERSION>] --ruby > vendor/gems/<GEM_NAME>[-<VERSION>].gemspec
For example:
gem unpack sidekiq-pro -v 2.1.4 --target vendor/gems
gem specification sidekiq-pro -v 2.1.4 --ruby > vendor/gems/sidekiq-pro-2.1.4.gemspec
The first command unpacks the gem into the vendor/gems directory. However, that doesn't contain the gemspec. The second command creates the associated gemspec. It's noteworthy that another poster mentioned something similar. This solution correctly writes the gemspec in ruby format instead of in yaml.
You can then update your Gemfile to point to the vendored gem:
gem '<GEM_NAME>', '<VERSION>', :path => "vendor/gems/<GEM_NAME>-<VERSION>"
For example:
gem 'sidekiq-pro', '2.1.4', :path => "vendor/gems/sidekiq-pro-2.1.4"