Ant Script Library Design Principles
Overview
The design of the Ant Script Library (ASL) is based on a number of principles. It helps to understand what these are, as it makes it easier to follow what they do, and how to use these principles in other scripts.
Orthogonal Modules
The ASL is composed of a number of files, each containing a relatively small number of targets. The targets are named in relatively generic terms. The purpose is to allow alternate scripts to be imported if a different implementation is required. For example, if you like to use Apache Ivy to manage your dependencies in a repository, you can import the Ivy targets as follows:
<import file="ant-script-library/asl-repo-ivy.xml"/>
This import will then make the following targets available in your script:
repo-cleancache
, repo-report
, repo-resolve
,
repo-retrieve
.
If you later decided that you didn’t want to use Ivy, but rather the Maven Ant Tasks instead, you could replace the previous import with the following:
<import file="ant-script-library/asl-repo-maven.xml"/>
With this one change, your build script then changes to use a completely different repository management tool. Because this different module provides targets with the same names, no other changes would be required in the script (though in this case, you would have to replace the ivy.xml file with an equivalent pom.xml).
Small Targets
Each ASL module is composed
a number of top level targets public targets (these have descriptions, and
so are described when you type `ant -p
`), as well as a number
of private targets (these are prefixed with a '-
' to ensure
that they can’t accidentally be invoked from the command line). Looking over
the scripts, you will not that no target is more than 5 - 10 lines long, and
does at most one or two tasks. The are a number of reasons for this:
- It becomes much easier to understand and maintain the scripts, because there is nothing really complex in any one target
- It becomes very easy to override specific targets to give different functionality. This is especially important when you are writing library scripts - it is almost certain that some targets will need to be overridden in the main script (by some users, at least).
Convention Over Configuration
The ASL has a number of built in configuration defaults, such as the location of the source directory, the location of the test source directory, and so on. If your application conforms to these expected default, your build script can become incredibly simple. The simplest possible script might be:
<project name="my-project" default="dist">
<import file="ant-script-library/asl-java.xml"/>
</project>
In general, the ASL scripts tend to expect your project conforms to the Maven standard directory layout.
Configuration Over Overriding
Not everyone has their project laid out in exactly the way, and it’s not always easy to change this. In these cases, it’s usually just a matter of defining specific properties with the actual values for your project before importing the ASL scripts. For example:
<project name="my-project" default="dist">
<property name="java-build.src-dir" location="src"/>
<property name="java-test.src-dir" location="test"/>
<import file="ant-script-library/asl-java.xml"/>
</project>
The properties that can be set to control the behaviour are documented on the reference pages (or just look inside the library scripts themselves).
Overriding Over Reimplementation
In cases where you need to do something complete different to what the ASL scripts are doing, you can override specific targets in the top level build script. Just those targets will be overridden, and everything will work without change. For example:
<project name="my-project" default="dist">
<import file="ant-script-library/asl-java.xml"/>
<!-- *******************************************
* target override: copy-resources
******************************************** -->
<target name="copy-resources"
depends="asl-java-build.copy-resources"
description="Copies resources in preparation to be packaged">
<copy todir="${java-build.classes-dir}">
<fileset dir="resources"/>
</copy>
</target>
</project>
In this case, the copy-resources
target from the module
asl-java-build
is being overridden. Note that the new target
still has a dependency to the original target of that name, meaning that
both the original and this new target will be called. Using this
technique, any target can become an extension point. The alternative is to
not declare a dependency on the original target, in which case the new
copy-resources
target completely replaces the original.
Is there a problem or mistake on this page? Do you want to contribute some changes? Send me an email at joe@exubero.com.