Setting Properties with Ant Tasks
In this Ant tutorial installment, we'll take a closer look at setting properties. The combination of properties and conditional execution allows more robust build files that adapt to the computing environment. Start with this basic build.xml file.
<project default="set">
<target name="set">
<property name="status" value="false"/>
<echo message="the status is ${status}" />
</target>
<property name="status" value="true"/>
</project>
And then execute ant.
$ ant
Buildfile: build.xml
set:
[echo] the status is true
BUILD SUCCESSFUL
Total time: 2 seconds
This demonstrates two characteristics of the property task:
- Properties are immutable.
Once they are set,
they stay set
(with some inevitable exceptions).
If properties were mutable,
then the property assignment task
<property name="status" value="false"/> would result in the message the status is false. - Property tasks that are
direct children of the project are executed
before any target task is executed.
In this case,
the property assignment task
<property name="status" value="true"/> is a direct child of the project and is executed before the target set.
Now let's see how we can use the available task to set a property value. The available task can be used to test for the existence of a file or directory, test for the existence of a class in a classpath, and test for the existence of a system resource. We'll just work with the first option, please see the fine manual for the other choices. This build file tests for the presence of foo.
<project default="all">
<target name="init">
<available property="present"
file="foo"
/>
</target>
<target name="exists" depends="init" if="present">
<echo message="foo exists" />
</target>
<target name="all" depends="exists" />
</project>
Execute this build.xml file twice. Once with an empty directory and once after creating file foo with the touch command.
$ ls
build.xml
$ ant
Buildfile: build.xml
init:
exists:
all:
BUILD SUCCESSFUL
Total time: 3 seconds
$ touch foo
$ ant
Buildfile: build.xml
init:
exists:
[echo] foo exists
all:
BUILD SUCCESSFUL
Total time: 3 seconds
In the previous example, we only checked for the existence of foo. In this example, we will also identify whether it is a directory or a file. The available task's type="dir" attribute specifically tests for a directory and is used to set property isaDir. We could use the type="file" attribute to set property isaFile but we'll use the condition task instead. The condition task is the generalized method for setting parameters. Please see the manual for a complete list of the supported conditions.
<project default="all">
<target name="init">
<available property="present"
file="foo"
/>
<available property="isaDir"
file="foo"
type="dir"
/>
<condition property="isaFile">
<and>
<isset property="present" />
<not>
<isset property="isaDir" />
</not>
</and>
</condition>
</target>
<target name="exists" depends="init" if="present">
<echo message="foo exists" />
</target>
<target name="isFile" depends="init" if="isaFile">
<echo message="foo is is a file" />
</target>
<target name="isDir" depends="init" if="isaDir">
<echo message="foo is is a directory" />
</target>
<target name="all" depends="exists,isFile,isDir" />
</project>
Execute this build file three times. Once with an empty directory, once after creating directory foo, and once after removing directory and creating file foo.
$ ls
build.xml
$ ant
Buildfile: build.xml
init:
exists:
isFile:
isDir:
all:
BUILD SUCCESSFUL
Total time: 3 seconds
Ant/Setting 41 $ mkdir foo
mkdir foo
Ant/Setting 42 $ ant
ant
Buildfile: build.xml
init:
exists:
[echo] foo exists
isFile:
isDir:
[echo] foo is is a directory
all:
BUILD SUCCESSFUL
Total time: 3 seconds
$ rmdir foo
$ touch foo
$ ant
Buildfile: build.xml
init:
exists:
[echo] foo exists
isFile:
[echo] foo is is a file
isDir:
all:
BUILD SUCCESSFUL
Total time: 3 seconds
Disclaimer: I don't claim to be an expert on ant. Please send comments and corrections.