I consider myself a casual user of Subversion (SVN). So every now and then I get surprised by what you can do with it. One of the cooler features of SVN is hook scripts. These are scripts that run based on SVN events, such as committing a file. As you can imagine this is a pretty powerful tool as it lets you have finer control and additional monitoring of your SVN repository. So naturally the first thing I thought this morning was - How can I get ColdFusion hooked up to this?
Hook scripts are text files stored in the repository. To start using them you simply create the file. SVN provides samples for each of the events. On a Windows machine (where I was), you need to use actionname.bat or .exe for your file name. I wanted to write something that would fire after a commit action, so I created a file named post-commit.bat.
Now the question is - how do you run ColdFusion from a command prompt? Unfortunately there is no direct way of doing this. I took Ashwin’s suggestion and downloaded Curl. Curl is a command line tool to download a URL.
Each hook script has different parameters passed to it. The post-commit script is passed the repository URL and revision number. In a bat file you can use these attributes as %1 and %2. Here is the bat file I used:
So to recap - when I check a file into this repository, SVN will automatically fire off my bat file and pass in the repo URL and revision number.
So what did my ColdFusion script do? I could have simply sent an email with the information I was passed (repository and revision), but that isn’t very helpful. I used SVN’s command line tool to grab more information about the revision. Using CFEXECUTE I ran this command:
svn log file:///#repository# -r #revision# -v --xml
The log command simply returns the information about the revision. The -r attribute sets the revision to examine. The -v attribute tells SVN to verbose. Finally, and this is the coolest part, the –xml tells SVN to return the result in XML. Once I had the XML I had everything I needed to send out an email with the information about the commit action.
Before I paste the full ColdFusion code I used - a few notes. First off - Rob Gonda has some very cool Subversion wrapper code in ColdFusion. I bug him about once a week to release it as a project on RIAForge. :) I point it out to make the point that the code I used could have been done simpler with his API. (I know this as I use it at RIAForge and it has been very simple to use.) Secondly - SVN can return even more information then just a list of files. I could have also shown the diff in the email as well. Don’t think you are limited to what I showed. Enjoy. If you actually use this code, let me know!
<cfparam name="url.repos" default="">
<cfparam name="url.rev" default="">
<cfif len(url.repos) and len(url.rev)>
<cfset url.repos = trim(url.repos)> <cftry> <cfset svnexe = "c:\progra~1\subversion\bin\svn.exe"> <cfset svncommand="log file:///#url.repos# -r #url.rev# -v --xml"> <cfexecute name="#svnexe#" arguments="#svncommand#" variable="result" timeout="30" /> <cfset resultXML = xmlparse(result)> <cfset author = resultXML.log.logentry.author> <cfset msg = resultXML.log.logentry.msg> <cfset files = arrayNew(1)> <cfloop index="x" from="1" to="#arrayLen(resultXML.log.logentry.paths.path)#"> <cfset thefile = resultXML.log.logentry.paths.path[x].xmlText> <cfset arrayAppend(files, thefile)> </cfloop> <cfmail to="firstname.lastname@example.org" from="email@example.com" subject="SVN Commit"> Repository: #url.repos# Revision: #url.rev# Message: #msg#
Files:<cfloop index=”x” from=”1” to=”#arrayLen(files)#”> #files[x]#</cfloop> </cfmail>
<cfcatch> <cfmail to="firstname.lastname@example.org" from="email@example.com" subject="SVN HandlerError" type="html"> <cfif isDefined("result")> result=#htmlcodeformat(result)# </cfif> <cfdump var="#cfcatch#"> </cfmail> </cfcatch> </cftry>