Installing gems with capistrano

Friday, March 16

Ever go to deploy a copy of your application and realize that you don’t have all the required gems installed? This is what I do to handle such a precarious situation via capistrano.


desc 'Installs required gems for this application'
task :install_gems, :roles => :app do
  # Add all gems required by your application here
  gems = %w(
    aws-s3
    libxml-ruby
    redcloth
    tzinfo
  )

  sudo "gem install -y --no-rdoc --no-ri #{gems.join(' ')}" do |channel, stream, data|
    print data if stream == :out
    channel.send_data($stdin.gets) if data =~ /^>\s/
  end
end

The channel.send bit is so you can respond to gems that have multiple versions available (i.e., mongrel). I’m also skipping rdoc and ri for this since I generally don’t care about having the documentation on the production server and it’s a bit faster when you skip them.

Oh, and if you wanted this to happen automatically after your cap setup, you could invoke it using (wait for it) the after_setup callback.

I’m sure there are improvements that could be made to this code, so suggestions are welcome.

Comments

Leave a response

  1. Anonymous CowardMay 05, 2007 @ 05:17 PM

    This is cool, I am gonna try this in my next project. What do you do if you need to specify a specific version, though? Or would you just do those manually. You might also run into problems if your were to need to pick a specific version of a gem. Sometimes a gem presents you with a menu? Or does this handle that?

  2. PackagethiefMay 05, 2007 @ 05:29 PM

    Coward—if you need to select a specific version, it will prompt you.

    Alas, I should mention that I’ve been informed by Charles Brian Quinn that a better solution that this one exists: it’s a Gem plugin for Capistrano, written by Niel Wilson. I couldn’t find a link on his site, but here’s a link to a code paste that I found: http://www.programmingishard.com/code/491