Running with scissors: overriding latest_revision SVN check in Capistrano

Ruby as a language sometimes feels like you are running with scissors. Its great to get from A to B quickly with your scissors, but there is a chance you may trip and impale yourself!

Today I was struggling with overriding what revision Capistrano uses when checking code out of Subversion as a hack to get around the lack of support for svn+ssh:// connectivity. Be default Capistrano makes a check from your local box for the latest revision, and then uses that to check out content on the remote box. However I wanted to skip the check from my local box and just pass in “HEAD” as the revision name.

My first solution was just to hack up the Subversion class and hard code the @latest_revision to be “HEAD”. But I realized what an ugly solution tweaking my gem was!

After banging my head a bit, I realized that Ruby is a dynamic language, and I can do all sorts of magic that maybe I shouldnt be doing. It was time to use instance_variable_set!

I added :before_update_code that allows me to manually set the revision in my deploy.rb and therefore bypass the check:

task :before_update_code, :roles => [:web, :app] do  revision = "HEAD"  puts "Revision to be deployed is #{revision}"  source.instance_variable_set("@latest_revision",revision)end

It does kind of make me wonder if all those OOP rules about encapsulation no longer apply!