Converting Mike’s Capistrano Cadillac into a Camero

Mike Clark made a recent post on his blog about how to handle Rails versions with Capistrano. Very nice stuff. I’ve put his code samples to immediate use with an app I’m preparing to convert to Rails 1.2.1.

I’ve run into some trouble this week, though, as I want to update one of my client projects that still runs version 1.1.6 of Rails. Mike’s Capistrano task takes a revision number so checking out a fresh copy with his script looks something like this.

rake deploy_edge REVISION=5990 RAILS_PATH=/path/to/shared/rails

This checks out 1.2.1 into the specified directory. After spending a few minutes trying to find the revision number for 1.1.6 (and chatting briefly with my Campfire peeps about the best way to proceed) I’ve decided that it’s safer to use tags instead of revisions. Deploys now look like this:

rake deploy_edge TAG=rel_1-1-6 RAILS_PATH=/path/to/shared/rails

Much more readable. The only downside, of course, is losing revision granularity. I’m essentially tied to the whim of the Core team as to when they decide to create new tags. But on the other hand, most of my projects aren’t currently running on Edge so this is suitable for my needs at the moment.

I’ve included my rewrite of the task below. Just drop it in common.rake or wherever you prefer to put your custom tasks. Reading Mike’s post would be a good idea too since he explains how to get this working with a remotely deployed Rails application.

desc "freeze rails edge"
task :deploy_edge do
  ENV['SHARED_PATH'] = '/var/www/apps/shared' unless ENV['SHARED_PATH']
  ENV['RAILS_PATH'] ||= File.join(ENV['SHARED_PATH'], 'rails')

  export_path   = "#{ENV['RAILS_PATH']}/#{ENV['TAG']}"
  symlink_path  = 'vendor/rails'

  unless File.exists?(export_path)
    puts "checking out rails tag #{ENV['TAG']}"
    get_framework_for export_path do |framework|
      system "svn export http://dev.rubyonrails.org/svn/rails/tags/#{ENV['TAG']}/#{framework}/lib " <<
             "#{export_path}/#{framework}/lib --quiet"
    end
  end
  
  puts 'linking rails'
  rm_rf   symlink_path
  mkdir_p symlink_path

  get_framework_for symlink_path do |framework|
    ln_s File.expand_path("#{export_path}/#{framework}/lib"), "#{symlink_path}/#{framework}/lib"
  end
  
  touch "#{symlink_path}/TAG_#{ENV['TAG']}"
end

def get_framework_for(*paths)
  %w( railties actionpack activerecord actionmailer activesupport activeresource actionwebservice ).each do |framework|
    paths.each { |path| mkdir_p "#{path}/#{framework}" }
    yield framework
  end
end

2 thoughts on “Converting Mike’s Capistrano Cadillac into a Camero

  1. Lately we’ve been developing against edge via svn externals. It hasn’t been a problem. You lock the externals to a revision and tag it when you deploy, then point it back to head for development.

  2. Nice enhancement, Matthew! I experienced differences between a Rails tag and the Subversion revision that corresponds to it and Mike pointed me to your solution.

    I merged your solution and Mike’s, so that you can specify either a tag or a revision number. Here’s what I came up with: http://pastie.caboo.se/116805

    WDYT?

    Ed

Comments are closed.