Need a hand with debugging build.xml logic - ant

Below is the code snippet from my build.xml file, when the Beta target fails it's expected to rerun the same beta target, but the control isn't going to the retry logic upon beta failure, not sure what i am missing here
<!-- US Beta Target -->
<target name="test-integration-assert-beta">
<test-environment country="US" stage="Beta" host.name="URL Goes Here" emailid="" password="" company="" invalidpassword="" materialset=""/>
<echo message="integTest.failure = ${integTest.failure}" />
<echo message="failedTests = ${failedTests}" />
<condition property="failedTests">
<and>
<istrue value="${integTest.failure}" />
<available file="${integ.test.dir}/testng-failed.xml" />
</and>
</condition>
<antcall target="test-integration-assert-beta-rerun">
</antcall>
</target>
<!-- US Beta Target (Re-run) -->
<target name="test-integration-assert-beta-rerun" description="Rerunning Failed Beta Tests" if="failedTests">
<echo message="Running Failed Integration Tests..." />
<echo message="rerunFailedTests.failure = ${rerunFailedTests.failure}" />
<copy file="${output.dir}/brazil-integ-tests/testng-failed.xml"
tofile="${output.dir}/testng-failed.xml" />
<test-environment country="US" stage="Beta" host.name="URL Goes Here" emailid="" password="" company="" invalidpassword="" materialset=""/>
<echo message="rerunFailedTests.failure = ${rerunFailedTests.failure}" />
<fail message="Tests Failed on rerun">
<condition>
<istrue value="${rerunFailedTests.failure}" />
</condition>
</fail>
</target>

<antcall> can be useful at times, but it has a lot of pitfalls that can make scripts difficult to reason about. In particular, <antcall> conflicts with the normal dependency flows of Ant.
Instead of <antcall>, consider using <target depends="..."> along with a <macrodef>:
The depends attribute of <target> enables conditional logic.
<macrodef> enables code reuse and reduces code duplication.
The following build.xml gives an example:
<project name="ant-macrodef-retry" default="run">
<macrodef name="my-test-environment">
<attribute name="try"/>
<sequential>
<echo>Call test-environment here.</echo>
<!-- The following <condition> tasks are just for testing purposes. -->
<!-- The real <test-environment> would set these properties. -->
<condition property="integTest.failure" value="true">
<and>
<equals arg1="#{try}" arg2="1"/>
<isset property="failTry1"/>
</and>
</condition>
<condition property="rerunFailedTests.failure" value="true">
<and>
<equals arg1="#{try}" arg2="2"/>
<isset property="failTry2"/>
</and>
</condition>
</sequential>
</macrodef>
<target name="try1">
<my-test-environment try="1"/>
<echo message="integTest.failure = ${integTest.failure}" />
<condition property="failedTests">
<istrue value="${integTest.failure}" />
</condition>
</target>
<target name="try2" if="failedTests">
<echo message="Running Failed Integration Tests..." />
<my-test-environment try="2"/>
<echo message="rerunFailedTests.failure = ${rerunFailedTests.failure}" />
<fail message="Tests Failed on rerun">
<condition>
<istrue value="${rerunFailedTests.failure}" />
</condition>
</fail>
</target>
<target name="run" depends="try1,try2"/>
</project>
Output
Below are various tests of the above Ant script. It shows how the script behaves in the various failure scenarios...
=================================
Test command line: ant
try1:
[echo] Call test-environment here.
[echo] integTest.failure = ${integTest.failure}
try2:
run:
BUILD SUCCESSFUL
=================================
Test command line: ant -DfailTry1=true
try1:
[echo] Call test-environment here.
[echo] integTest.failure = true
try2:
[echo] Running Failed Integration Tests...
[echo] Call test-environment here.
[echo] rerunFailedTests.failure = ${rerunFailedTests.failure}
run:
BUILD SUCCESSFUL
=================================
Test command line: ant -DfailTry1=true -DfailTry2=true
try1:
[echo] Call test-environment here.
[echo] integTest.failure = true
try2:
[echo] Running Failed Integration Tests...
[echo] Call test-environment here.
[echo] rerunFailedTests.failure = true
BUILD FAILED
C:\ant\build.xml:35: Tests Failed on rerun

Related

How to check two properties in an if condition of an Ant task?

It is possible to execute an Ant target conditionally by specifying an if or unless clause. As far as I can see this clause accepts only one property. How can I check for two properties?
This is an example:
<project default="test">
<property name="a" value="true"/>
<property name="b" value="true"/>
<target name="test-a" if="a">
<echo>a</echo>
</target>
<target name="test-b" if="b">
<echo>b</echo>
</target>
<target name="test-ab" if="a,b">
<echo>a and b</echo>
</target>
<target name="test" depends="test-a,test-b,test-ab"/>
</project>
If I run it, the test-ab target generates no output:
$ ant -f target-if.xml
Buildfile: target-if.xml
test-a:
[echo] a
test-b:
[echo] b
test-ab:
test:
BUILD SUCCESSFUL
Total time: 0 seconds
How to specify an and expression for the two properties?
Unfortunately, no. From the ant Targets manual:
Only one propertyname can be specified in the if/unless clause. If you
want to check multiple conditions, you can use a dependend target for
computing the result for the check:
<target name="myTarget" depends="myTarget.check" if="myTarget.run">
<echo>Files foo.txt and bar.txt are present.</echo>
</target>
<target name="myTarget.check">
<condition property="myTarget.run">
<and>
<available file="foo.txt"/>
<available file="bar.txt"/>
</and>
</condition>
</target>
This is my example with the use of the condition element:
<project default="test">
<property name="a" value="true"/>
<property name="b" value="true"/>
<target name="test-a" if="a">
<echo>a</echo>
</target>
<target name="test-b" if="b">
<echo>b</echo>
</target>
<condition property="a-and-b">
<and>
<equals arg1="${a}" arg2="true"/>
<equals arg1="${b}" arg2="true"/>
</and>
</condition>
<target name="test-ab" if="a-and-b">
<echo>a and b</echo>
</target>
<target name="test" depends="test-a,test-b,test-ab"/>
</project>

How to emulate if-elseif-else in Ant without using Ant-contrib?

I need an if-elseif-else conditional statement in Ant.
I do not want to use Ant-contrib.
I tried the solution here
<target name="condition.check">
<input message="Please enter something: " addproperty="somethingProp"/>
<condition property="allIsWellBool">
<not>
<equals arg1="${somethingProp}" arg2="" trim="true"/>
</not>
</condition>
</target>
<target name="if" depends="condition.check, else" if="allIsWellBool">
<echo message="if condition executes here"/>
</target>
<target name="else" depends="condition.check" unless="allIsWellBool">
<echo message="else condition executes here"/>
</target>
But I will have to set properties inside the if and else targets which will not be visible in the calling target.
Is there any other way out using conditions?
Move the dependencies out of if and else into a new target that depends on all of the other targets:
<project name="ant-if-else" default="newTarget">
<target name="newTarget" depends="condition.check, if, else"/>
<target name="condition.check">
<input message="Please enter something: " addproperty="somethingProp"/>
<condition property="allIsWellBool">
<not>
<equals arg1="${somethingProp}" arg2="" trim="true"/>
</not>
</condition>
</target>
<target name="if" if="allIsWellBool">
<echo message="if condition executes here"/>
</target>
<target name="else" unless="allIsWellBool">
<echo message="else condition executes here"/>
</target>
</project>

Ant build.xml phpunit

I have a ant build.xml (below). I am able to run phpunit fine from the command line as follows:
D:> phpunit --verbose --testdox-html logs\today.html runtest
This runs all my phpunit tests within the folder d:\runtest.
My problem is when I run my build.xml as 'ant build' it tries to execute a file called runtest.php the output from ant is below:
D:\>ant build
Buildfile: D:\build.xml
check_os:
if_windows:
if_unix:
prepare:
phpunit:
[exec] PHPUnit 3.6.11 by Sebastian Bergmann.
[exec]
[exec] Cannot open file "runtest.php".
BUILD FAILED
D:\build.xml:48: exec returned: 1
Total time: 2 seconds
My Build.xml is as follows:
<!-- This project launches the test generator and execute all phpunit selenium tests -->
<project name="proj" default="build" basedir="">
<!--Get environment variables -->
<property environment="env" />
<property name="logFolder" value="${basedir}\logs"/>
<property name="testFolder" value="${basedir}\runtest"/>
<property name="test" value="**" />
<condition property="pattern" value="runtest/*.php">
<os family="windows" />
</condition>
<tstamp/>
<!-- Check Operating system to set phpunit path-->
<target name="check_os">
<condition property="isWindows">
<os family="windows" />
</condition>
<condition property="isLinux">
<os family="unix" />
</condition>
</target>
<target name="if_windows" depends="check_os" if="isWindows">
<property name="exe.phpunit" value="C:\\Program Files\\PHP\\phpunit.bat"/>
</target>
<target name="if_unix" depends="check_os" if="isLinux">
<property name="exe.phpunit" value="${env.PHP_HOME}/includes/PHPUnit-3.2.0/PHPUnit" />
</target>
<target name="prepare" depends="if_windows, if_unix">
<mkdir dir="${logFolder}"/>
</target>
<target name="phpunit">
<!-- Check if folder empty -->
<fileset id="fileset.test" dir="${testFolder}">
<include name="*.*"/>
</fileset>
<fail message="Files not found">
<condition>
<resourcecount refid="fileset.test" when="less" count="1"></resourcecount>
</condition>
</fail>
<!-- Execute phpunit tests -->
<exec executable="${exe.phpunit}" failonerror="true" dir="runtest">
<arg line="--verbose --testdox-html '${logFolder}\phpunit-report-${TODAY}.html' runtest" />
</exec>
</target>
<target name="build" depends="prepare,phpunit"/>
</project>
The problem was I specified dir="runtest" once I removed this from the Execute line it worked.
<target name="phpunit" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit">
<exec executable="${phpunit}" failonerror="true" dir="${basedir}/classes/tests/" resultproperty="result.phpunit">
${phpunit} - needs Path of phpunit installation, you can get it from where is phpunit command in linux
dir="${basedir}/classes/tests/" - Need only the folder path where your php application is present
<arg line="UserTest ${basedir}/classes/tests/userTest.php" />
line="UserTest ${basedir}/classes/tests/userTest.php" - Here UserTest is class name and ${basedir}/classes/tests/userTest.php it is path of test class file
<arg value="--configuration"/>
<arg path="${basedir}/classes/tests/UnitTest.xml"/>
path="${basedir}/classes/tests/UnitTest.xml" - Path of xml file
</exec>
<property name="phpunit.done" value="true"/>
</target>

How to read properties file in ant

Hi all these are the contents of my file.properties file and i want to print those platforms which have true valu and their installer location,it is sure that the platform which has true value will only have installer:
platform.win-x86=true
platform.win-x86-client=false
platform.win-x64=true
platform.linux-x86=false
installer-zip.win-x86=E:\\abc\\abc.jar
installer-zip.win-x64=E:\\def\\def.jar
tried many thing but could not one of the things i used was as
<propertyselector property="platform.list"
delim`enter code here`iter=","
match="platform\.([^\.]*)"
select="\1"
casesensitive="false" />
<propertyselector property="zip.list"
delimiter=","
match="installer-zip\.([^\.]*)"
select="\1"
casesensitive="false" />
<target name="print.name" >
<propertycopy name="platform.name" from="platform.${platform.id}" />
<if> <equals arg1="${platform.name}" arg2="true" />
<then>
<echo>PlatForm.Id====>${platform.id}</echo>
<echo message="${platform.name}" />
<echo file="platform.properties" append="yes">${new.platform-name}=Yes${line.separator}</echo>
</then>
</if>
</target>
<target name="print.zipname" >
<propertycopy name="zip.name" from="installer-zip.${zip.id}" />
<echo>zip.Id====>${zip.id}</echo>
<echo message="${zip.name}" />
</target>
<target name="first">
<foreach list="${platform.list}"
delimiter=","
target="print.name"
param="platform.id" />
<foreach list="${zip.list}"
delimiter=","
target="print.zipname"
param="zip.id" />
</target>
although it prints value for all true platforms but for installer it prints only 1,and then breaks..can you help please
This is not directly answering your question, but rather showing you how you could use the same properties to perform conditional targets in your build.
<project default="build">
<property file="platform.properties"/>
<condition property="build.win-x86">
<and>
<istrue value="${platform.win-x86}"/>
<isset property="installer-zip.win-x86"/>
</and>
</condition>
<condition property="build.win-x86-client">
<and>
<istrue value="${platform.win-x86-client}"/>
<isset property="installer-zip.win-x86-client"/>
</and>
</condition>
<condition property="build.win-x64">
<and>
<istrue value="${platform.win-x64}"/>
<isset property="installer-zip.win-x64"/>
</and>
</condition>
<condition property="build.linux-x86">
<and>
<istrue value="${platform.linux-x86}"/>
<isset property="installer-zip.linux-x86"/>
</and>
</condition>
<target name="build" depends="win-x86, win-x86-client, win-x64, linux-x86"/>
<target name="win-x86" depends="win-x86-build, win-x86-installer"/>
<target name="win-x86-client" depends="win-x86-client-build, win-x86-client-installer"/>
<target name="win-x64" depends="win-x64-build, win-x64-installer"/>
<target name="linux-x86" depends="linux-x86-build, linux-x86-installer"/>
<target name="win-x86-build" if="${build.win-x86}">
<echo message="executing win-x86-build"/>
</target>
<target name="win-x86-installer" if="${build.win-x86}">
<echo message="installer: ${installer-zip.win-x86}"/>
</target>
<target name="win-x86-client-build" if="${build.win-x86-client}">
<echo message="executing win-x86-client-build"/>
</target>
<target name="win-x86-client-installer" if="${build.win-x86-client}">
<echo message="installer: ${installer-zip.win-x86-client}"/>
</target>
<target name="win-x64-build" if="${build.win-x64}">
<echo message="executing win-x64-build"/>
</target>
<target name="win-x64-installer" if="${build.win-x64}">
<echo message="installer: ${installer-zip.win-x64}"/>
</target>
<target name="linux-x86-build" if="${build.linux-x86}">
<echo message="executing linux-x86-build"/>
</target>
<target name="linux-x86-installer" if="${build.linux-x86}">
<echo message="installer: ${installer-zip.linux-x86}"/>
</target>
</project>
The output based on your properties file is below. Note that only the win-x86 and win-64 targets were actually executed. The others were skipped because the required conditions were not satisfied:
win-x86-build:
[echo] executing win-x86-build
win-x86-installer:
[echo] installer: E:\abc\abc.jar
win-x86:
win-x86-client-build:
win-x86-client-installer:
win-x86-client:
win-x64-build:
[echo] executing win-x64-build
win-x64-installer:
[echo] installer: E:\def\def.jar
win-x64:
linux-x86-build:
linux-x86-installer:
linux-x86:
build:
BUILD SUCCESSFUL
Total time: 0 seconds

How to check if a property has value in Ant

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>
Try this.
<condition property="isPropertySet" value="true" else="false">
<and>
<isset property="my_property"/>
<length string="${my_property}" trim="true" when="greater" length="0"/>
</and>
</condition>
<fail unless="isPropertySet" message="The property my_property is not set."/>
Since Ant 1.9.1, it is possible to add if and unless attributes on all
tasks and nested elements using special namespaces.
In order to use this feature you need to add the following namespace declarations
xmlns:if="ant:if"
xmlns:unless="ant:unless"
The if and unless namespaces support the following conditions:
true - true if the value of the attribute evaluates to true
blank - true if the value of the attribute is null or empty
set - true if the specified property is set
Sample:
<project name="tryit"
xmlns:if="ant:if"
xmlns:unless="ant:unless">
<exec executable="java">
<arg line="-X" if:true="${showextendedparams}"/>
<arg line="-version" unless:true="${showextendedparams}"/>
</exec>
<condition property="onmac">
<os family="mac"/>
</condition>
<echo if:set="onmac">running on MacOS</echo>
<echo unless:set="onmac">not running on MacOS</echo>
</project>
From Ant manual "If And Unless"

Resources