Smart Model, Dumb Controller

On the Rails project I'm currently working on, the team decided to use Vlad for deployment. If you're not familiar with Vlad, it's just like Capistrano with 2 big architectural differences.

(1) Vlad uses the command line ssh client instead of using net/ssh.
(2) Vlad uses Rake for tasks, and Capistrano has its own task system.

Deploying from a subversion tag using Capistrano is pretty easy: all you have to do is set the repository to the tag you want to deploy from. We can use the same approach in Vlad, but we need an additional step.

Before we get there, the first step is to write a task to prompt for the tag to use.

namespace :vlad do
  task :set_repository do
    tag = Readline.readline("tag to deploy (or trunk): ")
    if tag == "trunk"
      set :repository, "http://repo/trunk/"
    else
      set :repository, "http://repo/tags/#{tag}"
    end
  end
end

We then need to make the update task depend on the set_repository task.

namespace :vlad
  remote_task :update => %w[set_repository]
end

Due to how Vlad checks out the code, there's one more step. Vlad makes deployments faster by having an scm directory where the code is checked out. It does a checkout to the scm directory and exports from there to a release directory. The problem is if we had previously deployed trunk, but are now trying to deploy a tag, Vlad will try to checkout the tag on top of the trunk checkout, which subversion complains about.

svn: '.' is already a working copy for a different URL

We can fix this by modifying the update task to do an svn switch on the scm directory.

namespace :vlad do
  namespace :svn do
    remote_task :switch, :roles => [:app] do
      run "if [[ -d #{scm_path}/.svn ]]; then cd #{scm_path} && svn switch #{repository}; fi"
    end
  end
  
  remote_task :update => %w[set_repository svn:switch]
end

The if statement is there so that this task doesn't fail on the very first checkout to the scm directory.

I looked through the code, but couldn't find a built-in way to make this easier. But perhaps I overlooked something. This is using Vlad 1.2.0.