07 Aug 2011Antix - <if/> and <forEach/> tasks for Ant
A long time ago I was involved with the Ant project and part of the philosophy was that Ant was not executable xml. So this meant that <if/> and <for/> tasks were out. Implementing the equivalent functionality involved complex sets of tasks and properties to be defined.
Fast-forward many years and Ant still does not provide this functionality out of the box. I rarely use ant these days opting instead to use Buildr or Rake depending on the project. But when I do use Ant I find myself re-implementing the same set of tasks - usually <if/> and <forEach/>. A while ago I consolidated all the different implementations under one source tree, Antix on Github.
Someone asked me how to use them so here is a basic description...
Setup
The simplest way to install Antix is to download the jar and add a taskdef to your build file.
Jar: http://cloud.github.com/downloads/realityforge/antix/antix-1.0.0.jar
Benefits
The <if/> task
The <if/> is simple in that it has two child elements; conditions
and
sequential
. The sequential
has a a sequential list of tasks to
execute if all of the conditions evaluate to true.
e.g.
The <forEach/> task
The <forEach/> takes a list of white space separated values and invokes a nested sequential element for each value, setting a specific parameter to the value during the invocation.
e.g.
will print ..
[echo] Day = Mon [echo] Day = Tue [echo] Day = Wed [echo] Day = Thu [echo] Day = Fri
The <property-copy/> task
Ant properties are not allowed to be nested so you need to do some hackery to get get nested properties to work properly. The Antix library implements the approach recommended by the FAQ by implementing a property-copy task that will evaluate the property two layers deep and copy the value to another property.
This is typically used when you are selecting from a variety of different build configuration settings. i.e. Should you generate the EJB or web service generator.
e.g.
will print ..
[echo] service.generator=com.biz.WebServiceGen
The <dbgmsg/> task
The dbgmsg task will only print the specified message if the property named "debug" is set to a value. This is mostly used when debugging builds.
The <start-phase/> and <end-phase/> tasks
The start-phase and end-phase tasks are used to print the time it takes for various build phases. Each phase has a name and a timer starts when start-phase is executed and is stopped when end-phase executes. Both tasks echo a message at warning level (if the property named timing.check is set) or at the verbose level.
e.g.
will print ..
[echo] Starting phase 'integration-tests' at 18:15:39 ... [echo] Completing phase 'integration-tests' at 18:15:39 (Duration = 48ms)
The <toAscii/> task
Copy a file while replacing non-ascii characters with the character '?'.
e.g.
The <selectRegex/> task
The selectRegex task attempts to extract a value from a string based on a regular expression and assign that value to a property. Often I use this to extract out results from tests to do further processing.
will print ..
[echo] that=that
The <timer/> task
The timer task can either be a "start" or "stop" timer. A "start" timer sets a property to now indicating a start time. A "stop" timer sets a property to now that indicates an end time and it calculates the duration from the corresponding start time. Mostly this task is not not directly used but instead used by the start-phase and stop-phase tasks described above.
will print ..
[echo] Start: 1312706159383 [echo] Stop: 1312706159397 [echo] Duration: 14