Copacetic

I’ve always had an Ant target called “copacetic” that I’d fire off before a check in. It would run compile and test my work. This has become the working name of my continuous integration system, which I’ll tell you a bit about.

I’ve got a standard project structure now, inspired by the abilities of Ivy, that creates however many libraries a particular project might imply. It’s changed the nature of some of my projects. Each project is a collection of artifacts. Each artifact is compiled separately. There are no circular dependencies between artifacts. The leads so a collection of small JARs, rather than one large one.

All of my Java projects follow this structure. I check them out into the same directory. Certian projects build on other projects, so now I can integrate the builds. I can change directory into a project and run a commad like “compile.siblings” which compiles the dependencies, prior to compling the current project.

This sibling setup makes it simple to create an automatic continuous integration build. Simply run svn status -u on an integration checkout, and if anything is out of date, run svn update, change directory to project with the most depenencies, and run an Ant task. This is a shell program, of course, so I’m going to add it to my crontab once I’m comfortable with it.

The build is pure Ant, with Ivy and one other handrolled Ant task. Ivy does the work of publishing, and retrieving each project’s artifacts as they are built, and there you get the integration.

I am using Groovy now, to generate coverage reports. Groovy allows me to run JUnit over and over for each Java package, to ensure that the JUnit tests for each package cover that particular package.

This is something that would have required Ant Contrib or generated Ant (XSLT 2.0) to create otherwise. I see no benefit to Pure Ant for build targets that are really dedicated to development. The line count in Groovy is dramatically reduced, and that can be nothing but good.

Moving forward, I’m probably going to implement the integration script in Ruby, as part of a drive to do more system administration in Ruby. Groovy will play a larger role in the development builds, but I’m going to stick to raw Ant for core tasks, clean, compile, test, and publish.

All in all, this means I’m able to checkout and publish an update to Think New Orleans directly, with an Ant target or two. This includes hot deploying a freshly constructed WAR to Jetty, so it’s end to end, from Eclipse on my laptop, to my Java application server in Virgina.

Leave a Reply