Groovy, Programming

Low Expectations for the Build

I attended the talk on Gradle by Hans Doktor tonight and while I found myself agreeing that Maven is wholly unsatisfactory I did end up thinking that actually our expectations of build tools in the Java space are really low. What kind of things does Gradle offer us? Proper event interception, genuine integration with the build lifecycle, build targets dynamically defined at runtime, a directed cyclic dependency graph.

Looking at the list some of things you can’t believe are not part of our standard build package. We should be able to know when a build starts and stops and be able to attach code to those events. We should have decent target resolution that avoids duplication of tasks.

Gradle is head and shoulders about the morass that is Maven and is clearly superior to the ageing but faithful Ant but that it manages to be so on so little functionality is a shame.

Standard
Groovy, Programming, Software

Using Gant to build Java Projects

I know I said I would be taking a step by step introduction to Gant in my last post on the subject but sometimes the devil drives and you need things done in a less systematic way.

Recently I have been building Java and Scala projects with Gant. I think it has been a successful exercise so I am just going to jump on and show you some example buildfiles. The first one is going to be a Java project. This project is obviously toy code but I think if you just download the sample project and start filling in your own code (it’s an Eclipse project, Intellij and NetBeans should both import it successfully) you will be happy with how little you have to change the build file.

First have a look at the Gant file itself and then I am going to talk about the things that I think make Gant such a powerful and productive tool. The first thing to point out is the line count, this represents a complete build file for a Java SE project in under 100 lines. That includes the Hello World target I’ve left in as an echo test. Gant might have a slightly weird syntax if you are unfamiliar with Groovy but it isn’t verbose.

Targets and dependencies were in the last post so this time the new thing is using AntBuilder. Any method call that starts with Ant is a invocation of an Ant task. These are nothing but thin wrappers around the normal Ant task (and in fact I usually write them using the Ant Task documentation). Things that are attributes in Ant XML become hash properties in the parameter list. Things that would normally be nested elements are calls to the enclosing builder.

One area where Gant wins big is the way you can mix normal variables, Groovy string interpolation and Ant properties. Declaring the directory paths as Groovy variables near the head of the file allows me to create new paths via interpolation and assign the variable to the properties of an Ant task. Ant XML has properties and macro interpolation but this is both clearer and easier.

I am also using the Gant built-in clean task and in the course of using it, Groovy’s operator overloading for lists. I’m not a huge fan of operator overloading but if it’s clear enough here then it is great to have a DRY list assignment.

I also like the way that the directories are created in the init task. This kind of closure looping over a list again shows some of the power and conciseness that can be achieved by a language rather than a configuration file. If you don’t read Groovy then the each method iterates over the list its attached to and each item resulting from the iteration is stored in the whimsical “it” local variable.

Standard
Java

Introduction to Gant

This post was started the day after a Geek Night, it was a very, very cool Night…

With every topic I wanted to talk more about it and I felt we didn’t have enough time to get all the buzz out but one thing that struck me was that not many people seem to have heard of Gant. This is a real shame as I have recently converted and therefore have all the zeal of the convert. This zeal leads me to try and convert those who have not seen the light (yet).

What is Gant? It is a Groovy wrapper around Ant tasks. Groovy comes with an Ant Wrapper so what’s the great shakes you might ask? When Gant handles all the target dependencies for the project. It is essentially the missing part of the puzzle that gives you all the Ant functionality and a lot more. Gant adds some methods to the base Groovy shell execution environment that allows you to say that a task A depends on task B.

Enough chat though let’s get on with some examples. Download the standalone gant installation and then invoke the gant script (for your environment) in a new empty directory. It will give you a moan about not being able to find a build.gant file. So let’s create one now.

My first gant file is on Pastebin, cut and paste into your build.gant (or retype it to really get the benefit).

Now when you call gant you should see Target A and Target B printed out in the order of their dependencies. Type gant b and just Target B should be printed.

To be honest this really is the core of Gant so it may seem trivial but it’s important to understand. After all if you have ever taken a crack at this Kata you will know that dependency resolution isn’t trivial.

So what should we take away from this small example? Well I think it is important to note that it is Groovy syntax, the attribute assignment in target is standard but note that we don’t need to quote the property on the left. The string is like the description attribute in standard Ant tasks.

The println call is not mapping onto Ant’s echo it is the Groovy println so all the normal stuff to do with GStrings (like interpolation) applies here. Similarly the block attached to the target is a normal closure.

Dependencies are listed by calling depends, why isn’t that in the target declaration like in Ant? Well because you can create a dependency at any point in the closure. That means you can dynamically define the dependency graph. Which when you think about it, is kind of mental.

I did not want to have a huge post so the next one is going to be about using that dynamic definition to DRY out my Gant file.

Standard