Using Subversion Ruby bindings

I tried to do some subversion hacking from Ruby, very simple things like add/remove files,
commits and so, and realized that there’s no documentation at all out there, just blog posts
here and there.

I finally got something working, including user authentication (that is not as easy as you would
expect) and ignoring https certificates not signed by a trusted CA. Something like committing a file is not as simple as it would seem.

You have to make sure you have the latest version installed. In linux it means installing the subversion-ruby package. In OS X is more complicated, you need to remove the preinstalled subversion, install the newer one from Collabnet, and move some files around.

mv /Library/Ruby/Site/1.8/svn /Library/Ruby/Site/1.8/svn.bak
mv /Library/Ruby/Site/1.8/universal-darwin9.0/svn /Library/Ruby/Site/1.8/universal-darwin9.0/svn.bak
ln -s /opt/subversion/lib/svn-ruby/svn /Library/Ruby/Site/1.8/svn
ln -s /opt/subversion/lib/svn-ruby/universal-darwin/svn /Library/Ruby/Site/1.8/universal-darwin9.0/svn

Once you have it installed then you can call the svn libraries

  require "svn/core"
  require "svn/client"
  require "svn/wc"
  require "svn/repos"

  make_context("") do |ctx|
    # checkout
    ctx.checkout SVN_URL, "/tmp"
  end

  # Add a file and commit with a message
  make_context("Adding a file") do |ctx|
    ctx.add f
    ctx.commit f
  end

  # from http://svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/test/util.rb
  def make_context(log)
    ctx = Svn::Client::Context.new

    # Function for commit messages
    ctx.set_log_msg_func do |items|
      [true, log]
    end

    # don't fail on non CA signed ssl server
    ctx.add_ssl_server_trust_file_provider

    # username and password
    ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
      cred.username = "myusername"
      cred.password = "mypassword"
      cred.may_save = false
    end
    # setup_auth_baton(ctx.auth_baton)
    return ctx unless block_given?
    begin
      yield ctx
    ensure
      ctx.destroy
    end
  end