I'm looking for a way to exit a target and continue running the ant code without exiting the overall process. Something like the below but I get errors.
<target name="foo">
<some-task/>
<another-task/>
<condition property="should.exit">
(condition check here....)
</condition>
<exit if="should.exit" message="some message"/>
(skipped tasks if "should.exit" is true)
</target>
Errors I get:
Problem: failed to create task or type exit
[sshexec] [echo] Cause: The name is undefined.
[sshexec]
[sshexec] [echo] Action: Check the spelling.
[sshexec]
[sshexec] [echo] Action: Check that any custom tasks/types have been declared.
[sshexec] [echo] Action: Check that any <presetdef>/<macrodef> declarations have taken place.
[sshexec]
[sshexec] [echo] [sshexec]
[sshexec] [echo] ERROR Error error
<target name="foo">
<some-task/>
<another-task/>
<condition property="should.exit">
(condition check here....)
</condition>
<fail message="failing">
<condition>
<equals arg1="${should.exit}" arg2="true"/>
</condition>
</fail>
(skipped tasks if "should.exit" is true)
</target>
Related
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
When debugging a build.xml file, or an Ant task, I often want to execute one task without executing its dependencies. Is there a way to do this from the command line?
For example, with this build.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<target name="A" />
<target name="B" depends="A" />
</project>
is there a command that will execute task B but not task A?
You can make execution of any target conditional on a property using if or unless.
<project default="B">
<target name="A" unless="no.a">
<echo>in A</echo>
</target>
<target name="B" depends="A" >
<echo>in B</echo>
</target>
</project>
Output with no condition specified:
$ ant
Buildfile: C:\Users\sudocode\tmp\ant\build.xml
A:
[echo] in A
B:
[echo] in B
BUILD SUCCESSFUL
Total time: 0 seconds
Output with condition specified on command line:
$ ant -Dno.a=any
Buildfile: C:\Users\sudocode\tmp\ant\build.xml
A:
B:
[echo] in B
BUILD SUCCESSFUL
Total time: 0 seconds
Notes:
Ant console output will show that the target was "hit" even if entry was blocked by the condition.
The if and unless conditions do not do boolean check. They just check whether the property is defined or not.
You will have to restructure your Ant script to achieve this:
<target name="B">
<if>
<isset property="some.property"/>
<then>
<antcall target="A">
</then>
</if>
<!-- execute task B here -->
</target>
If some.property is set, then it will first execute A followed by B. Otherwise, it will skip task A and execute B by itself.
I have a property and target in my build.xml:
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
In the directory where build.xml is I run:
ant -Dprop="someVal" foo
This gets echoed:
[echo] someVal
[echo] Property: path/to/dir/
What happened to ${prop} when foo is called? How do I get the value to persist when foo is invoked?
Thanks in advance!
I can't reproduce your issue. What version of ANT are you using?
build.xml
<project name="demo" default="foo">
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
</project>
Run as follows:
$ ant -Dprop=hello
Buildfile: /home/me/tmp/build.xml
[echo] hello
foo:
[echo] Property: path/to/dir/hello
ANT version:
$ ant -version
Apache Ant(TM) version 1.9.0 compiled on March 5 2013
I'm using Ant version 1.8.4
I have this as my build.xml
<project>
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
</project>
I get this:
$ ant -Dprop=foo foo
Buildfile: /Users/david/build.xml
[echo] foo
foo:
[echo] Property: path/to/dir/foo
BUILD SUCCESSFUL
Total time: 0 seconds
I had to put <project> and </project> in the build.xml or else it wouldn't execute.
Is there something I'm missing? It seems to work fine.
I was trying to overwrite a pre-defined property that is immutable from the build.xml ...this is more along the lines of what I'm trying to do:
<project>
<property name="basedir" value="/usr/me/${prop}"/>
<echo message="${basedir}"/>
</project>
echos:
Buildfile: build.xml
[echo] /usr/me
BUILD SUCCESSFUL
Total time: 0 seconds
facepalm
I am using
<resourceexists>
<file file="${file}"/>
</resourceexists>
but getting an error in ant 1.8.2 as follows :
upgrade.xml:44: Problem: failed to create task or type resourceexists
Cause: The name is undefined. Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any / declarations have taken place.
What may be the reason?
Because <resourceexists/> is a <condition/> nested task. You should use is in this way:
<project name="resourcetest" default="test">
<target name="test">
<condition property="is.resource.exists" value="true" else="false">
<resourceexists>
<file file="C:\ac.txt"/>
</resourceexists>
</condition>
<echo>Does file C:\ac.txt exists? ${is.resource.exists}</echo>
</target>
</project>
I am sending a file path as a parameter to ant at command line. I want the build to fail if parameter doesnot exist. What is the way to do that?
Thanks!
Use the if attribute on a target e.g. :
<project name="test" default="init">
<target name="init" if="${path}">
<!--This will only execute if ${path} is defined from the command line-->
</target>
</project>
Second option : more verbose
<project name="test" default="init">
<target name="init">
<fail message="Path is not set! Exiting ant script!">
<condition>
<not>
<isset property="${path}"/>
</not>
</condition>
</fail>
</target>
</project>