Yesterday I wrote about Continuous code quality measurement with NDepend and TeamCity where I looked at nightly builds that assessed code quality using the very excellent NDepend. These reports are great and it’s easy to configure but you need to make both a dollar investment in the software and an education investment to really understand the metrics and how they relate to code quality.
What’s nice about StatSVN is that it’s free and it doesn’t take a lot of thinking to use it. Rather than analysing your codebase, like NDepend, StatSVN analyses your Subversion repository and reports on how your app has changed over time. In a way, it’s kind of chewing gum for the brain (lots of interesting metrics without a whole lot of substance), but there’s bit of value in understanding more about how your project is structured. And hey, it’s free!Getting everything installed
There are a few little bits and pieces required to make StatSVN work. Each of these needs to be installed on the build server:
First up, you’ll need StatSVN. We’ll go and grab the latest version and extract the zip into the program files directory. There’s no installer and the whole things consists of nothing more than a readme file and because it’s all written in Java, you also get a .jar file.
So that we can do something useful with the .jar file, we’ll also need to install Java.
Finally, we’ll need to perform a command line query against Subversion so we’ll need access to svn.exe. Because I’ve got VisualSVN Server on my demo TeamCity server I’ll just add a path to “C:\Program Files\VisualSVN Server\bin” in the environment variables of the machine but otherwise you can always go and grab the latest binary installer of SVN.Running StatSVN
To execute StatSVN, we need to perform three separate tasks:
- Check the repository out into a working directory
- Run an “svn log” to export the repository history out into a log file
- Run the StatSVN tool against the log file to generate the report
We’re going to automate all of this within a new build against the project I set up in my five part series about “You’re deploying it wrong”. Let’s start off with a brand new build:
The only notable point of interest here is the artifact path. As we did with NDepend yesterday, we need to tell TeamCity where to find the output of this particular build. We’ll come back to this path shortly.
Moving on to the VCS settings:
The VCS root will be the same as all the other builds (once again, don’t forget the checkout rule if you have a trunk), but the checkout mode is going to be a bit different. Every other build I’ve created so far has used the default “Automatically on server” option. The reason we’re going to use “Automatically on agent” is that this will effectively do an svn checkout which keeps the files associated to the repository rather than an svn export which pulls them out and breaks the association. As you’ll see from step 1 further up, StatSVN requires this before going any further.
Before we go and configure a build runner, we need to tackle how we’re going to execute the other two commands. I want to make this as easy as possible and I also want to centralise it so I can use it across other builds in the future. As such, I’m going to wrap up the two commands into a single .bat file we can call from the command line build runner.
Let’s start with svn log:
svn log --xml --non-interactive -v > StatSvnLog.xml
The purpose of this command is to dump each of the VCS transactions into an XML file. For interest sake, they look kind of like this.
<logentry revision="9"> <author>troy</author> <date>2010-11-19T10:07:53.824726Z</date> <paths> <path kind="file" action="M">/trunk/Web/Default.aspx</path> </paths> <msg>Updated text on the homepage.</msg> </logentry>
Often these logs will have many path entries but this gives you the idea. What the switches on the statement are saying is:
- --xml: save the log in XML format
- --non-interactive: disables all interactive prompting (more on that later)
- -v: verbose mode includes information about the paths that were changed in each revision
- > StatSvnLog.xml: the name of the file to dump the log into
Next up is the StatSVN command which is going to look like this:
"C:\Program Files\Java\jre6\bin\java.exe" -jar "C:\Program Files\statsvn- 0.7.0\statsvn.jar" StatSvnLog.xml %1 -output-dir StatSvnOutput -disable-twitter-button
Here’s what it’s doing:
- java.exe: executes the Java executable and passes in the .jar file for StatSVN
- StatSvnLog.xml: references the log file we created earlier
- %1: we’re going to pass this in from TeamCity – it’s the path to the working directory
- -output-dir: where we want the report placed (this was earlier referenced as an artifact)
- -disable-twitter-button: because I don’t want people automatically tweeting about my internal codebase!
I’m going to put both these commands into a file called “RunStatSvn.bat” and drop it into the folder I installed StatSVN into, in this case it’s “C:\Program Files\statsvn-0.7.0”. Now we can call it from the build runner:
This is all pretty self-explanatory, the checkout directory passed in via the command parameters is our working directory which will be passed to StatSVN so it knows where to find the codebase.
Now, there’s one little diversion I need to briefly take; it’s essential that the TeamCity Build Agent Service runs under an account which has rights to read from the VCS repository. I configured this back in part five of my previous TeamCity series and the reason is the same here; we don’t want to store plain text credentials on the server so let’s execute commands under the identity of the current user, in this case, the TeamCity Build Agent Service.
The last thing we want to do is make a nice tab on the build page to surface the report so we’ll head back over to Administration –> Server Configuration –> Reports tabs and create a new entry like so:
Let’s kick it off and see how it looks:
The stats look a little uninspiring for this project as it’s only a test deployment project I’ve been working on, but you get the idea. The main thing is the process is right and it’s ready to be scheduled to run each night right alongside NDepend.
Summary (and dramas)
I mentioned earlier that I’d come back to why the svn log command is running in non-interactive mode. To be honest, I had a bunch of dramas getting this to run. The problem centred on the identity the command was executing under and whether it was trusted to connect to Subversion. I searched desperately for answers as to why exactly what I had configured above was always being denied access and one of the things that made the search a little easier was to ensure the command runner wasn’t just sitting there waiting for a username and password, hence the non-interactive mode which in my case, simply tells you you’ve screwed up immediately.
Ultimately, after many days of frustration and many changes to the configuration, the setup above just started working. This was on a dedicated build machine and when I went to write this blog and configure it all again in my test VPC, exactly the same thing happened again! I don’t know why this was a problem and I don’t know what fixed it other than sheer stubbornness on my behalf. What I do know is that the configuration looks good and it definitely works. On two different machines!
Anyway, the end result is pretty neat and there’s now some nice statistics to go with the code quality measures from NDepend as well as the built-in FxCop and duplicates finder in TeamCity. This is a really nice suite of metrics which gives you a great view of what’s happening in your code. The fact that it does it without any prompting, every day and sits there waiting for you each morning is just what you want out of automated code metrics. Couldn’t be easier than that!