Saturday, March 15, 2008

SVN hooks on Windows with Ruby

I'd been meaning to write a pre-commit hook to catch empty log messages for a while but hadn't got around to it for one reason or another. I had a spare 5 minutes so I got stuck in.

The SVN book mentions that on Windows the hook files extension basically has to be .exe, .com or .bat. Even though .rb is executable on my SVN server it was not being called. So, instead I just called the ruby script from the bat file as such:

pre-commit.bat
1 SET DIR=%1/hooks
2 set REPOS="%1"
3 set TXN="%2"
4
5 c:\ruby\bin\ruby.exe d:\svn\hooks\pre-commit.rb %REPOS% %TXN% %DIR%

It also mentions that for security reasons, the repository executes hook scripts with an empty environment—that is, no environment variables are set at all, not even $PATH or %PATH%. Because of this, it is necessary to specify absolute paths.

Setting DIR above is a bit of a trick for debugging purposes so you can write a log file into the hooks directory to check things out. The ruby script is as follows:

pre-commit.rb
 1 REPOS, TXN, DIR = ARGV[0], ARGV[1], ARGV[2]
 2 SVN_LOOK = "C:/Program Files/Subversion/bin/svnlook.exe"
 3
 4 log_msg = %x["#{SVN_LOOK}" log -t #{TXN} #{REPOS}].chomp.strip
 5
 6 if (log_msg.nil? || log_msg.size < 5)
 7   err = <<-EOE
 8     This commit has failed due to the absence of a meaningful log message.
 9     Please provide a message describing why you changed what you did and
10     then try committing again. Ta -- Dan
11   EOE
12
13   STDERR.puts err
14   exit(1)
15 end

Yeah, I'm a bit of a bastard setting the minimum length of the log message to 5 chars. The only tricky bit of the entire process was realizing that I needed to chomp a new line off the log message. That's where using DIR and writing to a log file helped out.

Tally, ho!

No comments: