Saturday 24 September 2011

An Interface developer's guide to Ant

Apache Ant

I love Ant, it's kind of like building Java programs out of Lego (and we all like Lego).

Overview

Ant was made by the creators of Tomcat to automate it's build in a way that worked across OS's. With heritage like that it's not surprising that it takes the approach of keeping its config in an XML file. As most tags allowed in this file are well-written XML (tag names, attributes and nesting all in the right order) it's all pretty easy to see what everything is doing once you get the main principles.

Those principles

Inside the build file processes, called tasks, are grouped into targets. The sequence in which these targets are run is defined by their dependancies to each other. This mechanism is also really simple, each task will run any other tasks that are listed as dependancies before it runs it's own processes.

For example, this is a build file:

<project name="MyProject" default="init" basedir=".">
       <description>
              simple example build file
       </description>
       <property name="build" value="build"/>

       <!-- make the build folder -->
       <target name="setup">
              <echo message="Creating build folder"/>
              <mkdir dir="${build}" />
       </target>

       <!-- copy the files across -->
       <target name="init" depends="setup">
              <echo message="Moving all .js project files to build folder"/>
              <copy todir="${build}">
                     <fileset dir="./">
                            <include name="**/*.js"/>
                     </fileset>
              </copy>
       </target>
</project>

How it works

You will run the above build by entering this into your command-line/terminal:

ant

That's it, no options to set, Ant will default to the assumption that you want to use a file called build.xml which is located in the folder you are in when you run the command.

So it looks in build.xml and sees the XML above. The default attribute in the project tag specifies the init task as the one to start with & the basedir attribute that the build will execute in this folder (. means the current directory, in case you were wondering):

<project name="MyProject" default="init" basedir=".">

So Ant looks at the init target and sees that it is dependant on the setup task (see its depends attribute. As mentioned before, this means it executes the setup task before the contents of the init task.

So the setup task contains a single mkdir process to make the build folder we need for the main task.

<target name="setup">
       <echo message="Creating build folder"/>
       <mkdir dir="${build}" />
</target>

Now the main init task can run. This has a copy task that operates on files specified by its child fileset tag. This tag includes a child tag of its own that specifies a pattern files need to match to be used.

<target name="init" depends="setup">
       <echo message="Moving all .js project files to build folder"/>
       <copy todir="${build}">
              <fileset dir="./">
                     <include name="**/*.js"/>
              </fileset>
       </copy>
</target>        

A word about properties

You might have noticed the <property> tag being used. Anything in your build file that is referenced many times and stays the same should be kept in a property. This is good practice but also means if you need to change a property, you do it only once, not every time it is used in the file.

most properties are simple name:value pairs (with each set in an attribute on the property tag but they can hold a lot more

Also note that every build file has some properties already available so to avoid duplication, have a look.

So pretty straight forward really. Ant tasks are available for most things you will need to do from Apache with loads of others available from the open source community.

Good ideas

When you're writing build files it's a good idea to follow a few rules to keep it all nice and clean. To be honest, these apply to the writing of any program but I digress…

  • Keep any values you're using in multiple places as properties (like ${build} in the code above)
  • Use the echo task liberally. It is how you will know what your build is doing at each step
  • Comment your build file for clarity

What else can I do?

Everything really.

How you run it matters

You can run the ant command with a load of different options. To see all of them, type:
ant -help

You can use different build files, set properties that are used inside the build file and lots of other things that can change how the build runs.

Reducing duplication even more

Giving a tag an id attribute means you can use it as a reference in other targets. For example, tags like fileset can be given an id

       <fileset id="jsfiles" dir="./">
              <include name="**/*.js"/>
       </fileset>

…and referenced across your file instead of copying the same thing multiple times:

<fileset refid="jsfiles">
And

I'm not the biggest fan of Apache documentation but the Ant manual is worth a read for all the other things you can do with Ant. Try not to get too bogged down with all the Java bits (which is what spun my head out a bit at first).

Julien Lecomte of Yahoo has a nice post on using Ant for processes IDs would commonly use. You may not end up using all of his approach (it's quite tied into Yahoo's approach to development which may not match yours) but the good thing about Ant is you can grab the tasks you do want and just plug them in.

No comments:

Post a Comment