Introducing CaptainHook - A Subversion Hook Framework For .NET

UPDATE: CaptainHook is now an Open Source project on SourceForge.

Hook Logo One potent tool for team communications on a project, especially one with distributed developers, is the simple commit email. Setting up Subversion to send out an email when a developer commits changes to the repository is fairly easy. The Subversion distribution comes with a PERL script (commit-email.pl) that works quite well for this purpose.

At least it did for me until we changed mail servers to one that did not allow SMTP relay. Try as I might, I could not get the script to authenticate with our SMTP credentials. I downloaded various other PERL modules that were supposed to be able to authenticate with no luck. I read the RFC 2554 (seat of your pants reading) and authenticated manually via telnet and compared that to the SMTP logs for the components and realized that for some reasons, these scripts were doing the wrong thing.

That’s when it occurred to me that I could probably write a simple .NET app in a minute that could send out the commit email. As I got started though, I realized that it might be nice to write something that would allow others to easily handle other Subversion hooks. Hence CaptainHook was born.

Hooks in Subversion are scripts (or executables) that are triggered by an event in the subversion version control life cycle. The following are the five hooks supported by Subversion. For a short discussion on how to install the hooks, read this post by Pete Freitag.

Note that (except for post-commit and post-revprop-change) the return value of the script controls whether or not the commit should continue. If the script returns 0, the commit continues. If it returns anything other than 0, the commit is stopped.

Script Name Triggered By Arguments Notes
start-commit Before the commit transaction starts Repository Path and username Can be used for repository access control.
pre-commit After the commit transaction starts but before the transaction is commited Repository Path and transaction name Often used to validate a commit such as checking for a non-empty log message.
post-commit After the commit transaction completes Repository Path and the revision number of the commit Can be used to send emails or backup repository.
pre-revprop-change Before a revision property is changed Repository Path, Revision, Username, name of the property Revision Property’s new value is passed into standard input. Can be used to check permission.
post-revprop-change After a revision property is changed Repository Path, Revision, Username, name of the property Can be used to email or backup these changes.

My goal was to provide a nice strongly typed interface and a few useful service methods for accessing Subversion. Thus handling a Subversion hook is as easy as implementing an abstract base class and calling methods on a Subversion wrapper interface.

Setup

To setup CaptainHook, simply unzip the exe file and its related assemblies into the hooks folder on your Subversion server. The distribution includes a plugins directory with a single plugin already there. The plugins directory is where CaptainHook looks for other hook handlers. Be sure to update the config file with settings that match your environment.

The next step is to rename the .tmpl file for the hook events you wish CaptainHook to handle. CaptainHook comes with some sample batch files you can use instead, one for each hook. Just copy the ones you want to use from the SampleBatchFiles directory into the hooks directory.

Flow

Now when a commit occurs, Subversion will call the post-commit.bat file which in turn calls CaptainHook with the post-commit flag. This flag indicates to CaptainHook which plugins to load. CaptainHook then looks in the plugins directory for any assemblies with types that implement the PostCommitHook abstract class. It then instantiates instances of these types and calls the Initialize method and then the HandleHook method.

Note that for the time being, CaptainHook is an executable so it has to incur the cost of searching the plugin assemblies every time which may seem like overkill (and it is). However my focus was on the model for CaptainHook. At some point it will evolve to use remoting as a Server Activated Singleton or it may become a Windows Service which fit the model better. Either way, there are ways in which we can incur this cost only once. But for now, this will do and performs well enough.

Assemblies and Classes

Captain hook contains serveral assemblies.

Assembly Purpose
CaptainHook This is the main console exe and is the starting point for the application.
CaptainHook.Interfaces Contains the interface definitions. This is the only assembly you need to reference when writing a plugin.
CaptainHook.SubversionWrapper This is potentially useful as a stand-alone library. It includes the SubversionRepository class which allows running commands against Subversion and receiving the output as a string. This is useful for running straight commands against Subversion. This assembly also includes the SubversionTranslator class. This class wraps the SubversionRepository class and provides an object oriented means to calling the Subversion commands.
Velocit.Hook.Plugins Contains the PostCommitEmailHook plugin that started this whole ordeal as well as the RequireLogMessageHook which is a pre-commit hook that demonstrates how to reject a commit if no log message is specified.

Let me know if you find this useful. It is definitely a work in progress as not every command is implemented in the SubversionTranslator class. If it turns out that several people find this useful and want to contribute to the code, I am willing to put the code on SourceForge.

Download CaptainHook from my company’s tools site.

The zip archive contains both the source code and the binaries. I also compiled an x64 version of the exe for you 64bit kids.

What others have said

Requesting Gravatar... John Morales Jul 27, 2006 6:53 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Great job, We had created a c# subversion hook that disallowed updates to a sql schema update scripts directory. I just today thought of generalizing it and making available to the public. Glad I read this post. :)

Definitely will check out.
Requesting Gravatar... Jason Kemp Jul 27, 2006 9:41 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Awesome!

I've recently set up a CCNET build for our components at work, so this type of thing is right up my alley. My brain is bubbling with ideas for this project.

Nice work!
Requesting Gravatar... John Morales Jul 28, 2006 12:42 AM
# Ideas, Ideas, Ideas
I realized that an idea is worth crap unless you fully intend to make it happen. About a month ago, Jonathan
Requesting Gravatar... Haacked Jul 27, 2006 9:49 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Hey John, Jason. If you find it useful, I am more than willing to start a SourceForge project so that we can all work on it together. There's plenty left to do.

I wanted to post it out there to see if there's any interest before I went to that step.

Phil
Requesting Gravatar... Stuart Celarier Jul 27, 2006 10:55 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Just FYI, you might want to be aware of four additional hook scripts: pre-lock, post-lock, pre-unlock, and post-unlock. Details in the nightly build of Version Control with Subversion @ http://svnbook.red-bean.com/nightly/en/svn.reposadmin.create.html#svn.reposadmin.create.hooks.
Requesting Gravatar... Haacked Jul 27, 2006 10:58 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Thanks Stuart! Looks like we have some more work to do.
Requesting Gravatar... James Gregory Jul 28, 2006 12:26 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
I think I love you! One more tool to my belt for selling Subversion over Source Safe.
Requesting Gravatar... John Morales Jul 28, 2006 7:52 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Putting it on sourceforge sounds great. Maybe having a page where ppl can download plugins as well might be helpful?
Requesting Gravatar... Community Blogs Jul 28, 2006 2:13 PM
# VelocIT Tools Site
My colleague Jon Galloway has been on a spree of unleashing useful tools lately. I released a few of
Requesting Gravatar... ozgur alaz Jul 28, 2006 3:13 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Awesome
I dugg the story
Please add your diggs
http://digg.com/programming/A_Subversion_Hook_Framework_For_NET
Requesting Gravatar... Cullen Jul 31, 2006 9:17 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Why not host it on CodePlex? You wanted to play with TFS, here's the answer to your needs. This is a relatively small, easy to manage project, and will give you the chance to play with TFS.

I realize the irony of hosting a subversion tool on TFS, but that just makes it better.
Requesting Gravatar... Haacked Jul 31, 2006 9:30 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Cullen, that was actually my first impulse, but as you pointed out, the target users for this would be Subversion users and I didn't want to force them to use yet another source control system.

I figure, anybody interested in this is already using Subversion so might as well host it on a subversion server. ;)

Although the Next project I start will be on CodePlex. ;)
Requesting Gravatar... Jasolution Aug 06, 2006 4:09 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
This sounds like exactly what I've been looking for! I tried to download it from Sourceforge today, but it says that no files have been posted yet.

Where can I download?

Thanks!
Requesting Gravatar... Haacked Aug 06, 2006 5:03 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
The link to the download is at the bottom of the post: I'll repeat it here.
Requesting Gravatar... Jasolution Aug 06, 2006 5:45 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
When I follow that link, it takes me to the Captain Hook download page on your corporate website. The download link there now points to the SourceForge repository. But when you click the download link on SourceForge, you get this message:

No File Packages Defined
This project has not yet created any file release packages.
Requesting Gravatar... Jasolution Aug 06, 2006 10:03 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Argh, I've overcome my bout of foggy head and pulled down the files from the SVN repository. Guess I just had it in my head that I was looking for a zip file. :)
Requesting Gravatar... Haacked Aug 07, 2006 1:18 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
No problem. Since I just started the project, there have been no official releases except what I linked to.

If you would like to work on the code, let me know and I can get you Subversion access.
Requesting Gravatar... Marco Sep 27, 2006 5:08 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Nice!! I'm thinking about creating a plugin that will change the AssemblyFileRevision into the revision number of subversion..
Or does have anyone another solution? (except for nant or CC.NET)

Thanks
Marco
Requesting Gravatar... Eva Rossa Mar 20, 2007 8:26 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Hi

Do you have a sample of code on how to send email using CaptainHook on post-commit? The sample post-commit.bat that you have is not clear on how this is done.

Is it as simple as this?

c:\svn\hooks\CaptainHook.exe %~n0 %REPOS% /r %REV% myemail@email.com

(as in putting the email at the end of the line)

Eva
Requesting Gravatar... Haacked Mar 20, 2007 9:56 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Hi Eva,

I don't think you can pass in the email. You have to put a list of email addresses in a file named emails.lst in the same directory. Both CaptainHook.exe and this files should be in the "hooks" directory.

Also, create a batch file named post-commit.bat in the same directory. Here's mine.


@echo on

rem POST-COMMIT HOOK

set REPOS=%1
set REV=%2

c:\svn\hooks\captainhook.exe post-commit %REPOS% /r %REV% --debug > c:\svn\hooks\Output.txt

set REPOS=
set REV=


Note that last part outputs debug info into the output.txt file.
Requesting Gravatar... nagsen Apr 29, 2007 7:25 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
hi all,
I want to format java code after every commit in svn...it seems best option is do in post commit hook..but I dont know how to do this.
thanks in advance.
Requesting Gravatar... Brent Humphreys Jun 14, 2007 6:37 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
I got the latest and the post commit e-mail has all the functionality commented out.

When I uncommented it it wouldn't compile. Something about HostApplication not defined.

I am not a C# guy, but I was wondering if you have a working build?
Requesting Gravatar... Haacked Jun 14, 2007 12:36 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Hmmm, I haven't touched this in a while. I'll take a look when I get a chance. Sorry.
Requesting Gravatar... Sandeep Giri Jul 26, 2007 5:50 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
It seems that the code that sends email has been commented out.
I found it strange that the whole purpose the project is defeated because the idea was to have a way to send commit mails on windows.

Urgh! After two hours of checking-out, digging and compiling the code and finding how to get things done. I realized that the code does compile if u uncomment the mail-sender.

If you cant handle an open source why do you start. By this time I might have done writing my own email sender.

It is strange to find hardly any good open source .net projects.
Requesting Gravatar... Mikhail Diatchenko Aug 30, 2007 9:23 PM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
For those who run Subversion under Windows, I've written customizable pre-commit validator tool, which validates files being commited: SvnPreCommitValidator (SvnPCV). It's written in .NET 2/C# and is open source. Available from http://wiki.webgear.co.nz/SvnPCV.ashx
Requesting Gravatar... Brent Humphreys Sep 18, 2007 6:17 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
So are there any plans to get something that works?
Requesting Gravatar... chris hornung Nov 27, 2007 9:17 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
who was the real captian hook's name
Requesting Gravatar... Altern Dec 14, 2007 9:46 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Where can I donwload CaptainHook? veloc-it.com is down and sourceforge is empty.
Requesting Gravatar... Mike Jan 03, 2008 5:54 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
I've written a Subversion hook tool that allow the SVN administrator to configure, at a folder level, how to handle pre and post-commit hooks. These include of course sending out a nicely formatted commit e-mail, but also enforcing any number of commit comment regular expression requirements and locking down repro paths and file types.
You can check out the highlights at http://mckechney.com/SubversionNotifyForWindows and it's also hosted on SourceForge.net.
Requesting Gravatar... Nilesh Sep 09, 2008 4:41 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
My repository is hosted on a Linux machine. Can i still use CaptoonHook?
Requesting Gravatar... Adron Feb 05, 2009 5:43 AM
# re: Introducing CaptainHook - A Subversion Hook Framework For .NET
Sometimes I wonder how many tools besides just .NET & VS.NET do you guys at MS use? :)

What do you have to say?

(will show your gravatar)
Please add 8 and 1 and type the answer here: