This is my first blog post in several years. I figured I would start from the beginning and talk about build systems, specifically my experience writing a build system in Groovy, but before we get to that I’ll give you some background as to why I think it is a good fit.
ANT Build System
In the past large XML based ANT systems were the norm when dealing with Java projects and they felt very ‘Java-y’. At the beginning ANT felt like it helped because it could provide a consistent development environment across the development team but as time went on people started to try to make ANT do things it wasn’t very good at like conditional logic and remote copying. Trying to maintain a large ANT build started to feel very unnatural and time consuming.
Bash Build System
When writing the online payment system Jikiro (more about that later), a traditional legacy Java web application using Spring and Hibernate, I decided to try writing a custom build system in Bash. It was only designed to operate on Linux systems and the database was always going to be Postgres, why did I need to incur the overhead of dealing with all the different platform specifics built into something like ANT? Bash was also written with automation in mind and had decent support for looping, conditional logic, command line prompts and remote copying. The end script turned out to be smaller than a functionally equivalent ANT XML and worked pretty good. Applying database migration scripts using Bash was a bit of a pain but still manageable. Running the scripts was done with psql but storing audit data required some trickery to accomplish using just bash and psql.
I did go back and look at the script a few years later and still could reasonably understand it as well.
Groovy Build System
When I started the transaction system for Vogogo (known henceforth as VTX) I didn’t think I needed a build system other than what was in Grails. A simple grails prod war would do the trick and I would copy the war up to the production boxes and restart. Unfortunately the data migration in Grails wasn’t that good at the time. I tried several plugins that had me writing pseudo SQL so they could support a bunch of different databases. I tried to use them but the first issue I hit that I wasn’t sure what the plugin was doing or it couldn’t do what I needed it to do. I decided to drop the plugin and write my own in Groovy. Something that would have taken forever in ANT or slightly more complicated in Bash was relatively clean in Groovy.
The above code fragment of the build system would keep track of which database migration script has already been run in the current environment as well as keep track of some auditing data. file is a groovy script read from the project directory and injected with an SQL instance. Once we implemented our own encryption server for PCI compliance we added 1 line to the closure above: s.metaClass.cryptoClient = cryptoClient giving database migration script authors access to encrypted data stored in the database via the cryptoClient.
Executing system commands in Groovy is trivial. Not as trivial in Bash but definitely feels more natural than ANT. Doing things like logging a deployment are easy.
The current deploy script used at Redfall for products such as vogogo.com have evolved well past the point when I was actively working on it. A very talented Victor Louie has managed to build out the deployment to the point where checking out, branching, copying applying scripts and restarting the application servers happen with typing yes a few times.
I did have a look at http://gradle.org before and I’m sure it works great but I didn’t see the point of us having to work with anything other than a simple Groovy script.
When it comes down to it, Bash would have worked fine as well. Some of the higher level functions around manipulating configuration files based on the given environment would have become a bit mundane in Bash compared to Groovy, but this is more of a language difference than a case of Bash not being capable (which it clearly is). The important thing to take from this is if you are building a hosted application you should also be building a deployment system for it as well. Hopefully not in ANT :).