Wolfmans Howlings

A programmers Blog about Ruby, Rails and a few other issues

Allow a different local and remote subversion repository path for Capistrano

Posted by Jim Morris Wed, 15 Nov 2006 22:04:28 GMT

One of the things that bugs me about Capistrano is the requirement that access to the remote subversion repository have the same path from the local machine and the remote machine. This is never the case in my experience.

I have been getting around it by setting the path to svn://localhost/... and running ssh locally to port forward the SVN port to the remote host. This sucks as I usually forget to run ssh in another window first.

So I added an optional configuration variable to be set in deploy.rb called local_repository_path, so now you set the repository path as normal, which is the path the remote server uses to access the SVN repository, and you set the path that the local machine (your workstation) uses to access the same repository...

set :repository, "svn://localhost/#{application}/trunk"
set :local_repository_path, "svn+ssh://myremotehost.com/path/to/repostitory/#{application}/trunk"

Ideally one would patch the Capistrano distribution to achieve this, but thanks to the magic of ruby you can patch it from your own setup so I put the following into lib/tasks/patch_capistrano.rb


# Patch the svn scm to allow a local svn repository path as well as
# the remote one as most systems I use have a different path depending
# on whether you access svn from the local machine or remote machine

  module Capistrano

    # override the two scm methods that access svn from the local machine
    module SCM

      class Subversion
        # Return an integer identifying the last known revision in the svn
        # repository. (This integer is currently the revision number.)
        def latest_revision
          @latest_revision ||= begin
            configuration.logger.debug "querying latest revision..."
            match = svn_log(configuration[:local_repository_path]).scan(/r(\d+)/).first or
            raise "Could not determine latest revision"
            match.first
          end
        end

        # Return a string containing the diff between the two revisions. +from+
        # and +to+ may be in any format that svn recognizes as a valid revision
        # identifier. If +from+ is +nil+, it defaults to the last deployed
        # revision. If +to+ is +nil+, it defaults to HEAD.
        def diff(actor, from=nil, to=nil)
          from ||= current_revision(actor)
          to ||= "HEAD"
          `svn diff #{configuration[:local_repository_path]}@#{from} #{configuration[:local_repository_path]}@#{to}`
        end

      end
    end

  end

Then simply add this line to your config/deploy.rb...

require 'lib/tasks/patch_capistrano'

and everything works fine now.

Note there are only two scm methods that access SVN from the local machine, latest_revision and diff. I have patched both.

I'll tidy this up, make the default for local_repository_path be repository, and submit the patch to the Capistrano folks, who will hopefully commit it to the source code, as it won't affect existing users, but will make the rest of us a little happier.

Posted in  | Tags , ,  | 2 comments | no trackbacks

Comments

  1. Marcelo said 3 months later:

    Thanks a lot!

  2. Rob Dupuis said 11 months later:

    When reading variable xxx In capistrano 2.1 (poss 2.0 too?) the scm recipes check for a localxxx equivalent. So you can just use :localrepository if you need to configure a different local repo url.

Trackbacks

Use the following link to trackback from your own site:
http://blog.wolfman.com/articles/trackback/73

(leave url/email »)

   Comment Markup Help Preview comment