Ruby Subversion Bindings

Subversion has bindings for a variety of languages: Java, Perl, Python and Ruby. Of these I am most interested in the Ruby bindings as I’m building a Rails application. Unfortunately the documentation is completely lacking and bits of it are scattered throughout the web. This is an attempt to provide the code and how-to for the most common tasks.

Before we get to the code, validate you have the Ruby Subversion bindings installed correctly by running irb from a terminal:

irb(main):001:0> require ‘svn/client’
=> true

Onto the source code. Start it off by including the required svn modules:

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

Then setup the context with your subversion credentials:

ctx = Svn::Client::Context.new()
ctx.add_simple_provider
ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = 'username'
ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_PASSWORD] = 'password'

Now you can run any of the following commands on a remote subversion repository.

SVN Info

repos_uri = 'http://svn.website.com/project/trunk'
revision = 50
begin
  ctx.info(repos_uri, revision) do |path, info|
    puts("Url: #{info.url}")
    puts("Last changed rev: #{info.last_changed_rev}")
    puts("Last changed author: #{info.last_changed_author}")
    puts("Last changed date: #{info.last_changed_date}")
    puts("Kind: #{info.kind}")
  end
rescue Svn::Error => e
  # catch a generic svn error
  raise "Failed to retrieve SVN info at revision " + revision.to_s
end

SVN Checkout

repos_uri = 'http://svn.website.com/project/trunk'
output_dir '/home/billy/project_name'
revision = 50
begin
  ctx.checkout(repos_uri, output_dir, revision.to_i, nil)
rescue Svn::Error::CLIENT_UNRELATED_RESOURCES => e # revision doesn't exist
  raise "No such revision " + revision.to_s + " at " + repos_uri
end

SVN Log

repos_uri = 'http://svn.website.com/project/trunk'
ctx.log(repos_uri, 0, 'HEAD', 0, true, nil) do |changed_paths, rev, author, date, message|
  puts("Revision: #{rev}")
  puts("Author: #{author}")
  puts("Date: #{date}")
  puts("Message: #{message}")
  puts("---------------------------")
end

SVN List

repos_uri = 'http://svn.website.com/project/trunk'
ctx.list(repos_uri, "HEAD") do |path, dirent, lock, abs_path|
  if !path.blank?
    puts("Path: #{path}")
  end
end

That should get you started with the ruby bindings. If you want to know how to do anything else let me know in the comments.

Bash Basics

Bash is a shell scripting language included on most Linux and Mac computers. It’s useful for writing small scripts that don’t require another software language to be installed and are immediately portable. Good places to use bash scripts are when you want to write a cronjob, backup some files, or run an update task. Here are the basics to get you started.

Start your script with She-Bang header:
#!/bin/bash

Variables are assigned by a key-value pairing:
FILENAME="~/docs/input"

You can print to the console by using echo:
echo $FILENAME

An IF statement:
if [ ! -s $FILENAME ] ; then
  touch $FILENAME
fi

The bang ! negates the result, and the -s parameter checks if a file exists.

Example of a function:
function getFile
{
  # function contents here
  # the hash symbol makes the rest of this line a comment
}

Call this function by using its name:
getFile

You can pass a variable to a function:
getFile "/home/user/docs/file.txt"

And use it within the function by reference to $1
function getFile
{
  echo $1
}