Wednesday, November 7, 2007

Include NAnt in your source control

I like to put NAnt in source control and NEVER install it. I've had too many problems upgrading NAnt and having projects break because of whatever reason, and I have even more issues with custom tasks I write. It helps to keep your dev machine clean, your build machine clean, and leads to faster dev machine setup time. Here's my current favorite source tree structure:

Put your build file in your solution

I like to create a solution folder to hold extra project-related files, like my build scripts. When they're in the solution, it makes it easier to load them up and edit them. Since ReSharper supports many features for NAnt and MSBuild scripts, it makes sense to have them easy to get to.

I already talked about this earlier, but solution folders are a great way to create logical organization in your solution that doesn't have to correspond to the physical organization on disk.

Create a NAnt bootstrap batch file

I can't stand typing in "nant -buildfile:blahblahblah", especially when I execute the NAnt version that's in my source tree (not the one installed). I like to create a one-line batch file called "go.bat" that bootstraps NAnt and my build file:

@tools\nant\NAnt.exe -buildfile:NBehave.build %*

The @ symbol tells cmd.exe not to echo the command text out, then I specify the location of NAnt and the build file. The last part, "%*", just tells cmd.exe to append all commands after "go.bat" to the "nant.exe" program. For example, I can now do this:

go clean test deploy

The "clean test deploy" commands are targets in my NAnt build script. Any other NAnt command line options can be typed in after "go". I put this batch file at the project root level.

Use the "description" attribute to document public targets

As Jason mentioned, the "-projecthelp" NAnt switch will output a list of targets in your NAnt script. By providing a description in your target, you can provide some better information in the help output. Here's what NBehave's help looks like:

The targets are separated into Main and Sub Targets. Main Targets are targets with descriptions, and Sub Targets are those without. I can still provide internal documentation with XML comments in the build script. By only providing descriptions on targets that I need to call often, I can create some level of encapsulation in my build file.

I'm sure there are a dozen better tips out there, but these are the ones I make sure to use on every project I'm involved with.

About Me

I'm a senior consultant at Headspring Systems in Austin, TX. My focus is using .NET technologies together with Agile methodologies. Back in 2005, I drank the Agile punch and haven't looked at a waterfall the same since.
My blog has moved to http://jimmybogard.lostechies.com, so head over there to see the new content.