SVN post-commit hook

58 views
Skip to first unread message

Jay

unread,
Mar 29, 2012, 3:39:13 PM3/29/12
to VersionOne-dev
I was looking for an integration between SVN and V1 and the one
published on the community site polls SVN every n seconds and then
does work. That seems a bit silly since SVN has a built in post-
commit hook. Look as I might I couldn't find anyone that had written
a post-commit script so I wrote my own. Feel free to use it anyway
you see fit.

Step 1: the post-commit.bat file

@echo off
rem %1 = directory
rem %2 = revnum

setlocal
rem Remove forward slashes
set dirRepo=%1
call set dirRepo=%dirRepo:/=\%

rem Change to hooks dir
cd /d %dirRepo%
cd /d hooks

rem create a file in the temp dir with the commit info.
svnlook log -r %2 %1 >> %temp%\%2
echo. >> %temp%\%2
svnlook date -r %2 %1 >> %temp%\%2
echo. >> %temp%\%2
svnlook changed -r %2 %1 >> %temp%\%2
echo. >> %temp%\%2
svnlook author -r %2 %1 >> %temp%\%2


SVNIntegration.exe %1 %2 "%temp%\%2" "<version1 URL>" "<version 1
username>" "<version 1 password>" "<websvn URL>"

endlocal


STEP 2: the code for the EXE:

public class SVNPostCommit
{
public const string FileName =
"V1.SVNIntegration.SVNPostCommit"; //used for debugging and logging
only
private readonly string _directoryName;
private readonly int _revNum;
private readonly string _commitComment;
private readonly string _v1URL;
private readonly string _v1Username;
private readonly string _v1Password;
private readonly string _websvnURL;

public SVNPostCommit(string[] args)
{
/*
for (var i = 0; i < args.Length; i++ )
{
Console.WriteLine(string.Format("arg {0} = {1}", i,
args[i]));
}
*/
_directoryName = new DirectoryInfo(args[0]).Name;
_revNum = Convert.ToInt32(args[1]);

//EventLog.WriteEntry(FileName, "_directoryName = " +
_directoryName);
//EventLog.WriteEntry(FileName, "_revNum = " + _revNum);

var tempFileName = args[2];
_v1URL = args[3];
_v1Username = args[4];
_v1Password = args[5];
_websvnURL = args[6];

try
{
using (var reader = new
StreamReader(File.OpenRead(tempFileName)))
{
_commitComment = reader.ReadToEnd();
}
File.Delete(tempFileName);
}
catch (Exception ex)
{
EventLog.WriteEntry(FileName, string.Format("Unable to
get commit comment from file {0} with error: {1}", tempFileName,
ex.Message));
}

//EventLog.WriteEntry(FileName, "_commitComment = " +
_commitComment);
}

public void CheckAgainstV1()
{
var matches = Regex.Matches(_commitComment, @"([a-z]-
\d{5})", RegexOptions.IgnoreCase);
var displayIDs = new List<string>();
foreach (Match m in matches)
{
displayIDs.Add(m.Value);
}

if (displayIDs.Any())
{
var fullURL = string.Format("{0}/revision.php?
repname={1}&rev={2}", _websvnURL, _directoryName, _revNum);
var csURL = string.Format("<a target=\"_blank\" href=
\"{0}\">{0}</a>", fullURL);
var fullComment = csURL + "<br/><br/>" +
_commitComment.Replace("\n", "<br/>");

var referenceComment = (_commitComment.Length > 100) ?
_commitComment.Substring(0, 100) + "..." : _commitComment;

//don't connect to v1 unless we have to
var v1 = new V1Instance(_v1URL, _v1Username,
_v1Password);
var cs = v1.Create.ChangeSet("CS-" + _revNum,
referenceComment);
cs.Description = fullComment;
foreach (var id in displayIDs)
{
var uc = id.ToUpper();
//EventLog.WriteEntry(FileName, "getting story " +
uc);
var story = v1.Get.StoryByDisplayID(uc);
if (story != null)
{
cs.PrimaryWorkitems.Add(story);
}
}
if (cs.PrimaryWorkitems.Any())
{
cs.Save();
//EventLog.WriteEntry(FileName,
string.Format("Added commit info to {0} tickets!",
cs.PrimaryWorkitems.Count));
}
}
}
}

Enjoy!
Reply all
Reply to author
Forward
0 new messages