Yesterday at work, a coworker called and asked for some ideas on how to read the Subversion revision number of a sandbox from within an Ant build script. Doing this would allow that number to be stamped on files during the build, which can help down the road when you need to figure out exactly which version of the project is running in a dev, test or integration environment.
Thinking about how I would do this outside of Ant, my first answer was to have him run "svn info" and parse the output. As a reference for those who don't run it very often, if you were to open a terminal window and run this command in one of your sandboxes the output would look something like:
Path: . URL: svn+ssh://username@my.dev.server/data/repository/project/trunk Repository Root: svn+ssh://username@my.dev.server/data/repository/project Repository UUID: 5853ccd8-1d1d-0410-918b-9390590c579a Revision: 668 Node Kind: directory Schedule: normal Last Changed Author: adeveloper Last Changed Rev: 668 Last Changed Date: 2007-03-30 18:53:52 -0400 (Fri, 30 Mar 2007)
It turns out that this matches the format for a properties file in Java, so parsing this is pretty straightforward in Ant. All we need to do is pipe this out to a file and ask Ant to read it in during the build. At that point, the sandbox revision number will be available in the build as a property named Revision (note the capital R). The build file snippet below shows how all of this is done in Ant using the exec and property tasks.
<exec executable="svn" output="build/svn.properties">
<arg value="info" />
</exec>
<property prefix="svn" file="build/svn.properties"/>
<echo>Sandbox Revision: ${svn.Revision}</echo>
When run, this prints the expected output of "Sandbox Revision: 668".
This method works but has two problems. First, it counts on the fact that the svn executable is in the path of every system that will run this build file. Second, the actual implementation in Ant isn't exactly straightforward and it may not be clear what's going on to someone reading the build. Neither of these are major problems, but it still seemed like there should be a better way.
As luck would have it, there is. In addition to Subversion itself, the folks over at Tigris also have a library called SvnAnt, which is an Ant task that makes working with Subversion pretty easy. One of the commands, status, does exactly what we're after and sets an Ant property with the revision number of a given path. Using SvnAnt, our build snippet now looks like:
<taskdef resource="org/tigris/Subversion/svnAnt/svnAntlib.xml">
<classpath>
<fileset dir="${build.lib.dir}/svnAnt" includes="**/*.jar" />
</classpath>
</taskdef>
<svn>
<status path="${basedir}" revisionProperty="svn.revision" />
</svn>
<echo>Sandbox Revision: ${svn.revision}</echo>
This is much easier to read and I think solves the clarity problem of the first approach. As for the svn executable needing to be on the path, that may be solved too depending on the version of SvnAnt you are using. While the current stable release (1.0.0) of SvnAnt requires the svn executable or the javahl bindings, the latest development release (1.1.0-RC2) includes integration with SVNKit, which is a pure Java Subversion library. This means that if the build file runs on a system that is missing the native resources for javahl, the pure Java implementation will be used and everything will still work. Nice!
2 Comments
Leave a comment
0 TrackBacks
Listed below are links to blogs that reference this entry: SVN Revision Numbers in Ant.
TrackBack URL for this entry: http://www.nearinfinity.com/mt/mt-tb.cgi/521



Dare I ask whether they also have a plug-in for that other build tool we all know and "love?" (Maven2, of course)
FYI, "svn info" doesn't seem to do a great job of returning the sandbox revision. It seems to give the revision of the root directory itself - which never changes.
Mark