Integrating Apache Ant and Subversion

Posted by buildmeister on July 17th, 2007
Filed under:  build scripting  java  version control  tools 
There are 1 comments on this article.
Bookmark and Share

Introduction

Subversion is an open source version control tool and was designed as a replacement for CVS. There are a number of integration libraries that can be used to integrate Ant and Subversion and which are summarised as follows:

  • The “official” Subversion Ant library – the default integration library with support for Subversion via an “antlib” library that wraps the svn command line executable. The library is available in Ant's own Subversion source repository, and works with Ant 1.7. At the time of writing you still need to check out and build this library for yourself.
  • SvnAnt - The SvnAnt project at Tigris is an Ant task that integrates to Subversion. It uses a JNI (Java Native Interface) binding to Ant if possible for speed, falling back to the Subversion command line if not.
  • StatSvn – The StatSvn project at SourceForge is a library that generates a set of statistical reports and graphs from Subversion metadata. An Ant task is available for integrating the execution of StatSvn into your build process.

Currently, I recommend the use of SvnAnt and StatSvn. In this article I will therefore be describing how to use these tools as part of your Ant build process.

Installing SvnAnt

Although SvnAnt is available to download as a binary, at the time of writing a new binary has not been released for a while and is significantly out of date with respect to the source code. I therefore recommend that you rebuild this project from the source code to get the most up-to-date features. Although this is obviously a risk, the library is small enough that the risk is limited. To download the source you will need a working Subversion command line (the svncommand). I will assume that you have already set this up, if not visit the Subversion website for instructions on how to download Subversion for your environment.

The Subversion command you need to execute to initiate the download is as follows:

svn co >http://subclipse.tigris.org/svn/subclipse/trunk/svnant/ svnant
  --username guest --password ""

This will create a svnant directory in you current directory, navigate into this directory and start the build, specifying the version of the Java Development Kit (JDK) that you are running. For example, if you are running JDK 1.4 then you would execute the following:

>cd svnant
>ant -DtargetJvm=1.4

Once the build has completed you should copy the following files to a directory inside your project:

build/lib/svnant.jar
lib/svnClientAdapter.jar
lib/svnjavahl.jar
lib/svnkit.jar

I typically create a lib directory at the top-level of my project’s build directory to contain libraries such as these. However you could also copy them to your Ant home directory (%ANT_HOME%\lib).

Using SvnAnt – creating or updating a workspace

SvnAnt executes most Subversion commands via a single Ant task. However, before you can execute this task you need to make sure that it can be located from within your build script. To achieve this, youcan add the following lines to your build script:

<taskdef name="svn" classname="org.tigris.subversion.svnant.SvnTask">
  <classpath>
    <fileset dir="${dir.lib}">
      <include name="**/svn*.jar"/>
    </fileset>
  </classpath>
</taskdef>

This example creates a new task called <svn> which can be used to access the library. Now that this task is available, to create a new workspace you could implement a target similar to the following:

<property name="svn.url-base"
    value="https://hoteldejava.svn.sourceforge.net/svnroot/hoteldejava"/>
<property name="svn.url"
    value="${svn.url-base}/trunk/"/>
<property name="svn.dir" value="hoteldejava"/>

<target name="svn-checkout" description="checkout a project from Subversion">
  <svn username="${svn.username}" password="${svn.password}">
    <checkout url="${svn.url}" destPath="${svn.dir}"/>
  </svn>
</target>

This example will create a new workspace (a Subversion working copy) in the directory hoteldejava. It will download the latest files from the URL specified by the svn.url property and using the login credentials specified by the ${svn.username} and ${svn.password} properties. Login credentials are not always required to checkout a project, however if you need to supply them then the best approach to use is to add the properties to your personal build.properties file, for example:

svn.username=guest
svn.username=password

To update an existing workspace you could implement a target similar to the following:

<target name="svn-update" description="update a project from Subversion">
  <svn username="${svn.username}" password="${svn.password}">
    <update dir="${svn.dir}"/>
  </svn>
</target>

The update approach is really only acceptable if you create a workspace specifically for building in or releasing from.

Using SvnAnt – committing changes

In controlled build environments, it is likely that files will get changed or generated as part of the build process and which you want committed to version control. Although I don’t recommend adding intermediate files such as Java classes to version control, you might want to add built libraries for sharing and reuse. If you need to add new files into the repository then you could implement a target similar to the following:

<target name="svn-add-dist">
  <svn username="${svn.username}" password="${svn.password}">
    <add dir="${dir.dist}" force="true">
      <fileset>
        <include name="**/*.jar"/>
      </fileset>
    </add>
  </svn>
</target>

This example will add the contents of Java libraries in the dir.dist directory into the repository.

If you have added files to the repository or are updating files already in version control then you could implement a target similar to the following:

<target name="svn-commit">
  <svn username="${svn.username}" password="${svn.password}">
    <commit dir="${svn.dir}" message="${svn.message}"/>
    <info target="${svn.dir}"/>
  </svn>
  <echo>
    Last Revision = ${svn.info.lastRev} by ${svn.info.author} on ${svn.info.lastDate}
  </echo>
</target>

In this example you would need to set svn.message to an appropriate value as it will be recorded in the repository. The example also runs the <info> task to get the latest information about the repository. Information from this command is placed in Ant properties, such as svn.info.lastRevision for the last repository revision. This information can be used and recorded for auditing purposes.

Using SvnAnt – creating a baseline

In Subversion, baselines are usually created by copying a repository directory on your trunk to the tags directory. This assumes that you are following the well known convention of creating a trunk, branches and tags directory at the top level of your repository. If so then to effectively create a new baseline for your build, you could implement a target similar to the following:

<target name="svn-copy">
  <fail message="Error: rel.num has not been set" unless="rel.num"/>
  <property name="svn.url-rel" value="${svn.url-base}/tags/${rel.num}/"/>
  <svn username="${svn.username}" password="${svn.password}">
    <copy srcurl="${svn.url}" desturl="${svn.url-rel}"
        message="${svn.message}"/>
  </svn>
</target>

This example requires the property rel.num to be set with an appropriate release number (for example 1.0.0). A check using the <fail> task has been implemented to ensure this is the case as you do not really want to risk creating random directories in your Subversion repository. Again, you would need to set svn.message to an appropriate value as it will be recorded in the repository.

Installing StatSvn

StatSvn is a metrics analysis tool for Subversion repositories. It can automatically generate a number of useful reports including:

  • Source Lines of Code timelines
  • Source Lines of Code for each developer
  • Developer activity
  • Developer activity per module
  • Developer most recent commits with links to ViewVc for web browsing

An example of a Source Lines of Code timeline is illustrated below.

StatSvn example

To install StatSvn simply download the binary Zip file from the SourceForge project website. Extract the Zip file and copy the Java library statsvn.jar to your lib directory.

Using StatSvn

StatSvn can be executed via a single Ant task. However, before you can execute this task you need to make sure that it can be located from within your build script. To achieve this, you can add the following lines to your build script:

<taskdef name="statsvn" classname=" net.sf.statsvn.ant.StatSvnTask">
  <classpath>
    <fileset dir="${dir.lib}">
      <include name="**/statsvn.jar"/>
    </fileset>
  </classpath>
</taskdef>

This example creates a new task called <statsvn> which can be used to access the library.

StatSvn relies on the execution of the Subversion log command to output information on the history of the repository and its changes. You therefore need to execute this command before executing the <statsvn> task. Unfortunately, the log command is not currently supported by SvnAnt so you will have to call the Subversion command line. To run both of these commands you could implement a target similar to the following:

<target name="svn-statreport">
  <property name="svnstat.log" value="svn.log"/>
  <property name="svnstat.dir" value="statsvn"/>
  <property name="svnstat.title" value="${ant.project.name} Report"/>
  <exec executable="svn" output="${svnstat.log}">
    <arg line="log ${svn.url} --xml -v"/>
  </exec>
  <statsvn path="." log="${svnstat.log}" 
      outputDir="${svnstat.dir}" title="${svnstat.title}"/>
</target>

In this example a Subversion log file called svn.log is first created using the Ant <exec> task to call the Subversion command line. The <statsvn> task is then executed to turn this log file into more useful metrics and graphs. The output is placed in the statsvn directory as HTML and PNG files. There will be an index.html file that you can open to navigate between all of the reports.

In practice, you should execute this task on a regular basis, maybe as part of a nightly build. You can then publish the results to an internal project Intranet. This information can then be used by all members of your project team.

References

Bookmark and Share

Comments

Posted by kermitfrog

[plug] Another good Subversion Ant library (that does not require JavaHL) is Svn4Ant. Located at antxtras.sf.net. Of particular interest would be the "svnbranch" and "svnretire" tasks which are designed to ease SCM-specific functions.

Posted on March 10th, 2008

Back to Top

Submit a new comment

All fields in bold are required.