Darcs with Capistrano for Rails

I’ve used Darcs as my only version-control system for a while now. When I got into Rails, I naturally wanted to use Capistrano. Unfortunately, Darcs and Capistrano don’t get along too well. Darcs’ file-based repositories don’t mesh well with Capistrano’s assumption that the repository is accessed through a server, a la Subversion.

I ran into problems with cap deploy:update_code because Darcs couldn’t find the repository. After a discussion on the Capistrano mailing list I decided to go my own route.

I have two Darcs repositories, one on my development machine and one on the server. I darcs push patches from development to the server. Then I have my own custom Capistrano tasks to get the latest code from the server’s copy of the repository. This is adapted from the Capistrano sources:

namespace :deploy do
  task :update_code, :except => { :no_release => true } do
    on_rollback { run "rm -rf #{release_path}; true" }

    run("darcs get --partial /home/myapp/repo --repo-name=#{release_path}")
    run("rm -rf #{release_path}/_darcs")

    finalize_update
  end
end

I also had to write a custom finalize_update task to add the links to the shared Rails directories:

namespace :deploy do
  task :finalize_update, :except => { :no_release => true } do
    run <<-CMD
      ln -s #{shared_path}/log   #{latest_release}/log &&
      ln -s #{shared_path}/tmp   #{latest_release}/tmp &&
      ln -s #{shared_path}/data  #{latest_release}/data &&
      ln -s #{shared_path}/index #{latest_release}/index &&
      ln -s #{shared_path}/config/database.yml #{latest_release}/config/database.yml &&
      ln -s #{shared_path}/public/system #{latest_release}/public/system
     CMD
  end
end