Problem 1: It depends on Rails.
You have to manually install Rails before you can use rake gems:install. Ok, so this might not be that big of a deal, but consider this scenario:
- Your app is running in production on rails 2.3.4.
- You upgrade your app to rails 2.3.5, including the RAILS_GEM_VERSION.
- You deploy your app.
- Your deployment script calls rake gems:install to keep the dependencies up to date with each new release.
- That fails with something that looks like:
Problem 2: Sometimes, for some reason, it just doesn't work.
Sometimes (most times) you add a new config.gem command to environment.rb. The next deployment runs rake gems:install and it fails with the complaint that you are missing the very gem you are hoping it will install for you. For example, in a working Rails 2.3.5 project, add this line to environment.rb:
config.gem 'sanitize', :version => '1.2.1'
Then, run rake gems:install, and it fails with a "Missing these required gems:" message, e.g.:
WTF? It's telling me to run the command I just ran, to install the missing gem that's preventing that command from running.
Problem 3: It depends on your Rails environment.
This can create a circular dependency where some file (particularly vendored plugins/gems) can require a gem to be loaded before the task to install it runs. For example, consider that some file in your vendor directory does this:
require 'gdata'
Then naturally, you add this to environment.rb:
config.gem 'gdata'
The next time you run rake gems:install, it will fail with a "no such file to load" error, e.g.:
The Solution: rails_gem_install
I have created a new tool called rails_gem_install to help alleviate this problem. Use this instead of rake gems:install, and you should be much more successful at getting all your Rails app's dependencies installed without manual intervention.
To install:
gem install rails_gem_install
To use:
cd my_rails_appRAILS_ENV=production rails_gem_install
This will install all the gems required to run your app in the production environment, including Rails. Replace rake gems:install in your deployment scripts with rails_gem_install, and as you change config.gem requirements, those gems will be properly installed.
See the github project page for more details.
How It Works
The main principle behind this tool is that it does not depend on Rails. It creates its own module named Rails that provides some of the functionality from the real Rails that it needs, up until the point that Rails is installed. Then, it only loads some very specific parts of Rails that implement the gem dependency and installation mechanisms, without actually running the app's Rails::Initializer and loading all of its environment, plugins, etc.
First, it runs a simple rake -T to see if it complains about Rails missing. It parses the output of this, and if necessary, installs the indicated version of Rails.
Next, it parses out the config.gem statements and uses those to ensure all the listed gems requirements are met, and installs those that aren't. It does this without actually loading Rails or the app environment. This carries us most of the way.
Finally, it runs the rake gems command and parses its output to detect all the kinds of errors described above and install the corresponding gems. This step is repeated until rake gems does not complain anymore.