What is the best approach to write hooks for Subversion in Windows? As far as I know, only executable files can be used. So what is the best choice?
I’ve just spent several days procrastinating about exactly this question. There are third party products available and plenty of PERL and Python scripts but I wanted something simple and a language I was familiar with so ended up just writing hooks in a C# console app. It’s very straight forward:
public void Main(string[] args)
{
string repositories = args[0];
string transaction = args[1];
var processStartInfo = new ProcessStartInfo
{
FileName = "svnlook.exe",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
Arguments = String.Format("log -t \"{0}\" \"{1}\"", transaction, repositories)
};
var p = Process.Start(processStartInfo);
var s = p.StandardOutput.ReadToEnd();
p.WaitForExit();
if (s == string.Empty)
{
Console.Error.WriteLine("Message must be provided");
Environment.Exit(1);
}
Environment.Exit(0);
}
You can then invoke this on pre commit by adding a pre-commit.cmd file to the hooks folder of the repo with the following line:
[path]\PreCommit.exe %1 %2
You may consider this overkill but ultimately it’s only a few minutes of coding. What’s more, you get the advantage of the .NET language suite which IMHO is far preferable to the alternatives. I’ll expand my hooks out significantly and write appropriate tests against them as well – bit hard to do this with a DOS batch file!
BTW, the code has been adapted from this post.
We've got complex requirements like:
#5 is huge for us, there's no better way to know you're not gonna break commits moving forward than to be able to push all previous commits through your new hook. Making the hook understand that 1234 was a revision and 1234-1 was a transaction and making the appropriate argument changes when calling svnlook, etc. was the best decision we made during the process.
For us the nut got big enough that a fully unit testable, regression testable, C# console exe made the most sense. We have config files that feed the directory restrictions, parse the existing httpd_authz file to get "privileged" users, etc. Had we not been running on Windows with a .NET development work force, I would have probably written it all in Python, but since others might need to support it in the future I went .NET over .BAT, .VBS, Powershell silliness.
Personally I think Powershell is different enough from .NET to be mostly useless as a "scripting" language. It's good if the only cmd line support for a product comes via PS (Exchange, Windows 2k8), etc. but if all you want to do is parse some text or access regular .NET objects PS just adds a crazy syntax and stupid Security Iron Curtain to what could be a quick and easy little .NET app.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With