Categories
client hooks tortoise svn

Tortoise SVN Client Hooks

Hello,

Been a while and a move (to warm Toronto from cold Vancouver) a new job, place to live, adventure etc. As a game programmer/ technical artist I have an interest in improving pipeline tasks and automating any repetitive tasks. Needless to say working on a computer a lot it sometimes takes a bit of thinking to know where you can improve time and where you need to spend it. For any home project I do (be it big or small) I usually like to keep track of my changes, and spend a lot of time looking at subversion logs.

I use TortoiseSVN as a subversion
client for a while (though I still like the old command line Subversion for Linux)
and I will be looking at some of the other (mostly free) version control systems in
a later post. Tortoise is great in that it is simple to use and is smoothly embedded in the Windows Explorer window/menu system once it has been installed. I don’t usually spend much time on the server side (although I imagine that will eventually change) and work with VisualSVN standard server for setting up a simple svn server on my home machine (it would be really good to have something at a different machine though).

Anyway, I thought there were lots of client side svn hooks I would like to hookup (updating a wikipage, trigger a test build, and formatting svn messages). In order to do this I started from the example at the tortoise svn source website: Pre-Commit Hook Example. Thanks to YNot for the SyntaxHighlighter tip.

// License: This code is free software and can be modified, updated, commented 
//and sold verbatim without constent.   
// The code has no warranty and the author accepts no liability for any issues 
//or damage this code may cause, including: hardware, software, wetware, financial,
// psychological, emotional, mental or physical. 
//
// Author: Michael Hubbard
//
// This script is a client side tortoise svn pre-commit hook script.
// The script creates a commit message of the following format:
// The FolderDirectory structure is not the whole path and 
// splits on the SplitFolderPath (currently set to "Scripts/").
//
// "_FolderDirectory/SubDirectory(s)_"
// "- Message1"
// "- Message2"
// " ... "
// "- MessageN"
//
// To use the script set the TortoiseSvn->Settings->Hook Scripts->Add
// Set client hook scripts to a pre-commit hook 
//(this will set the four command line arguments):
// Set the Command line to Execute to: "WScript 
//absolutePathToThisScript/SvnFormatMessageHook.js" 
//(the WScript is important (Windows Script Host))
// Check the "Wait for the script to finish" checkbox.
// 
// Code based on tortoise svn examples at:
// http://code.google.com/p/tortoisesvn/source/browse/branches/1.6.x/
// contrib/hook-scripts/client-side/PreCommit.js.tmpl

// The root path of the scripts (remove any path information 
//before this path when formatting directories).
var SplitFolderPath = "Scripts/";

// The minimum number of characters for a title description.
var MinTitleLength = 3;

// Read the file at path into an array .
function ReadPaths(path)
{
 var retPaths = new Array();
 var fs = new ActiveXObject("Scripting.FileSystemObject");
 if (fs.FileExists(path))
 {
  var file = fs.OpenTextFile(path, 1, false);
  var i = 0;
  while (!file.AtEndOfStream)
  {
    var line = file.ReadLine();
    retPaths[i] = line;
    i++;
  }

  file.Close();
 }

 return retPaths;   
}

// Write the formatted message to the message path.
function WriteFormattedMessage(formattedMessage, formatMessagePath)
{
 var fs = new ActiveXObject("Scripting.FileSystemObject");
 if (fs.FileExists(formatMessagePath))
 {
  var file = fs.OpenTextFile(formatMessagePath, 2, false);
  file.write(formattedMessage);
  file.Close();
 }
}

// Check if the message is already in the formatted type.
function IsValidMessage(commitMessages)
{
 if(null == commitMessages || 0 == commitMessages.length)
 {
  return false;
 }

 var titleMessage = commitMessages[0];
 if(titleMessage.length  {
  return false;
 }

 return '_' == titleMessage.charAt(0) && '_' == titleMessage.charAt(titleMessage.length -1);
}

// Get the formatted message.
function GetFormatMessage(commitMessages, formattedDirectories)
{
 if(null == commitMessages || null == formattedDirectories)
 {
  return null;
 }

 //  Make sure the title has _ before and after the title it.
 var title = "_" + formattedDirectories[0] + "_\n";
 for(var i = 0; i  {
  if("- " != commitMessages[i].substring(0,2))
  {
   title += "- ";
  }

  title += commitMessages[i] + "\n";
 }

 return title;
}

// Get the formatted directories.
function GetFormattedDirectories(commitFiles)
{
 var formattedDirectories = new Array();

 // The files to commit.
 for(var i = 0; i  {
  formattedDirectories[i] = GetDirectoryName(commitFiles[i]);
 }

 return formattedDirectories;
}

// Get the formated sub directory name  (not including the file name). 
function GetDirectoryName(file)
{
 var splitIndex = file.indexOf(SplitFolderPath);
 if(splitIndex == -1)
 {
  return file;
 }

 // Get the subdirectory (after SplitFolderPath).
 var subDirectory = file.substring(splitIndex + SplitFolderPath.length);

 // Remove the file (just keep the subdirectory).
 subDirectory = subDirectory.substring(0, subDirectory.lastIndexOf("/"));
 return subDirectory;
}

// Write a valid message from the commit files (Quit with 0 for success, 1 for error).
function Main()
{
 // The script command line arguments from tortoise.
 var objArgs = WScript.Arguments;

 // Check the number of script arguments is valid or exit.
 if (objArgs.length != 4)
 {
  WScript.Echo("Usage: [CScript | WScript] 
SVNFormatMessageHook.js path/to/pathsfile depth path/to/messagefile path/to/CWD");
  WScript.Quit(1);
 }

 var commitFiles = ReadPaths(objArgs(0));
 var commitMessages =  ReadPaths(objArgs(2));

 // Get the formatted directories.
 var formattedDirectories = GetFormattedDirectories(commitFiles);

 if(!IsValidMessage(commitMessages))
 {
  var formattedMessage = GetFormatMessage(commitMessages, formattedDirectories);
  WriteFormattedMessage(formattedMessage, objArgs(2));
 }

 WScript.Quit(0);
}

// Entry point to the program.
Main();

Bye for now,
Michael Hubbard

michaelhubbard.ca

2 replies on “Tortoise SVN Client Hooks”

hello, I don’t get many comments but am more than happy to help (if I can). Yes I believe the script should wor in XP, please let me know if you have any issues with it, and I will try it in XP with the latest tortoise svn soon and fix any issues.

Leave a Reply to Michael Hubbard Cancel reply

Your email address will not be published.