I have an Ant XML file which I use for build.
I have 3 properties. I want to break the build if these properties does not contain any value. Also I want to break the build if the value is empty.
How can I do this in Ant?
I a using Ant and not Ant-contrib.
You can use conditions using the <fail>
task:
<fail message="Property "foo" needs to be set to a value">
<condition>
<or>
<equals arg1="${foo}" arg2=""/>
<not>
<isset property="foo"/>
</not>
</or>
</condition>
This is equivalent to saying if (not set ${foo} or ${foo} = "")
is pseudocode. You have to read the XML conditions from the inside out.
You could have used the <unless>
clause on the <fail>
task if you only cared whether or not the variable was set, and not whether it has an actual value.
<fail message="Property "foo" needs to be set"
unless="foo"/>
However, this won't fail if the property is set, but has no value.
There's a trick that can make this simpler
<!-- Won't change the value of `${foo}` if it's already defined -->
<property name="foo" value=""/>
<fail message="Property "foo" has no value">
<condition>
<equals arg1="${foo}" arg2=""/>
</condition>
</fail>
Remember that I can't reset a property! If ${foo}
already has a value, the <property>
task above won't do anything. This way, I can eliminate the <isset>
condition. It might be nice since you have three properties:
<property name="foo" value=""/>
<property name="bar" value=""/>
<property name="fubar" value=""/>
<fail message="You broke the build, you dufus">
<condition>
<or>
<equals arg1="${foo}" arg2=""/>
<equals arg1="${bar}" arg2=""/>
<equals arg1="${fubar}" arg2=""/>
</or>
</condition>
</fail>
Building on the other answers, this is my preferred form, as a Macro:
<!-- Macro to require a property is not blank -->
<macrodef name="prop-require">
<attribute name="prop"/>
<sequential>
<fail message="Property "@{prop}" must be set">
<condition>
<not>
<isset property="@{prop}"/>
</not>
</condition>
</fail>
<fail message="Property "@{prop}" must not be empty">
<condition>
<equals arg1="${@{prop}}" arg2=""/>
</condition>
</fail>
</sequential>
</macrodef>
To Be used as:
<target name="deploy.war" description="Do the war deployment ;)">
<prop-require prop="target.vm" />
<prop-require prop="target.vip" />
<!-- ... -->
For brevity you can collapse the two fail elements into one by using an <or>
, but I prefer my error messages to treat me like I cannot think for myself ;)
You could try using conditions... or creating a target with unless
With Ant addon Flaka you may use patterns like :
<property name="foo" value="bar"/>
...
<fl:unless test="has.property.foo">
...
</fl:unless>
...
<fl:when test="has.property.foo">
...
</fl:when>
Concrete check for emptyness :
<fl:when test=" empty '${foo}' ">
<fail message="Houston we have a problem!!"/>
</fl:when>
A complete example, also using some equals check with 'eq' (opposite would be 'neq'):
<project xmlns:fl="antlib:it.haefelinger.flaka">
<!-- some if/then/else construct -->
<fl:choose>
<!-- if -->
<when test=" '${buildtype}' eq 'prod' ">
<!-- then -->
<echo>..starting ProductionBuild</echo>
</when>
<when test=" '${buildtype}' eq 'test' ">
<!-- then -->
<echo>..starting TestBuild</echo>
</when>
<!-- else -->
<otherwise>
<fl:unless test="has.property.dummybuild">
<fail message="No valid buildtype !, found => '${buildtype}'"/>
</fl:unless>
<echo>.. is DummyBuild</echo>
</otherwise>
</fl:choose>
</project>
output with ant -f build.xml -Dbuildtype=prod
or
ant -f build.xml -Dbuildtype=prod -Ddummybuild=whatever
[echo] ..starting ProductionBuild
output with typo => ant - build.xml -Dbuildtype=testt
BUILD FAILED
/home/rosebud/workspace/AntTest/build.xml:21: No valid buildtype !, found => 'testt'
output with ant -f build.xml -Ddummybuild=whatever
[echo] .. is DummyBuild
I'm on an older version of Ant, so isset wasn't available. Instead I used the following notation with the double $ in the equals.
<target name="xxx">
<echo message="${contextRoot}" />
<if>
<!-- check if the contextRoot property is defined. -->
<equals arg1="${contextRoot}" arg2="$${contextRoot}" />
<then>
<!-- it isn't set, set a default -->
<property name="contextRoot" value="/WebAppCtx" />
</then>
</if>
<echo message="${contextRoot}" />
</target>