Return value from Ant - ant

I am in the process of setting up hudson with already existing Ant scripts so I would be using a custom workspace. However, I would like to have a python script set some environment variables, call Ant with the top level build file and perform some other actions if the build was successful. Is there a way I can have ant return a true/false value based on the build status so that I can make appropriate decisions and perform related actions.

Ant will return a non-zero exit value if you use the <fail> task. The <fail> task can be combined with the <condition> task too:
<fail message="Missing file "${foo}&quot">
<condition>
<not>
<available file="${foo}" type="file"/>
</not>
</condition>
</fail>
You can use this to verify that what you were attempting to build was actually built, and if not, exit the build with an error.
If you don't want to fail immediately, you can use the <condition> task to set a property, and then fail if that property is set:
<fail message="Property foo.failed was set">
<condition>
<isset property="foo.failed"/>
<condition>
</fail>
Or simply:
If Python isn't picking up the fail status, you can set an exit value on failure too:
Ant will return a non-zero exit status too f a build halts because a task fails. Many Ant tasks have a haltonfailure or failonerror, and the default is not to halt or fail on an error.

Related

Failing task if variable undefined

I would like my Ant task to fail if a variable it uses is not defined. E.g. currently
<mkdir dir="${some.dir}"/>
always succeeds, if some.dir is defined, it creates a directory under the variable's value, if not it creates a directory named literally ${some.dir}.
Is there a way and how to switch between the currently lenient and a more strict mode of resolving variables in Ant? I am running this in Eclipse.
<fail unless="some.dir"/>
<mkdir dir="${some.dir}"/>
or
<fail>
<condition>
<not>
<isset property="some.dir"/>
</not>
</condition>
</fail>
<mkdir dir="${some.dir}"/>

How to correctly setup a conditional task with Maven-Ant?

New Ant user here. I've created a conditional task, which is run inside as a Maven Ant plugin. The issue I'm facing is the condition target: "ui-test-condition" is not being found during a build.
The error returned is:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.6:run (uitests) on project myProject: An Ant BuildException has occured: Target "ui-test-condition" does not exist in the project "maven-antrun-". It is used from target "ui-test-run". -> [Help 1]
This would suggest a syntax error in the code below, however I'm unable to identify the issue. Any assistance is greatly appreciated.
<target name="ui-test" depends="ui-test-run,ui-test-skip"/>
<target name="ui-test-condition">
<condition property="ui-test-condition-run">
<and>
<istrue value="${ui.test}"/>
</and>
</condition>
</target>
<target name="ui-test-run" depends="ui-test-condition" if="ui-test-condition-run">
<echo>Running tests</echo>
<exec dir="src/main/webapp/ui" executable="src/main/webapp/ui/${some.executable}"
resolveexecutable="true" failonerror="true">
<arg value="-e" />
<arg value="foo/run" />
</exec>
</target>
<target name="ui-test-skip" depends="ui-test-condition" unless="ui-test-condition-run">
<echo>Tests are skipped</echo>
</target>
I had the exact same problem and I found the answer is that the depends property of a target is not supported by maven-antrun-plugin.
Excerpt of http://maven.apache.org/plugins/maven-antrun-plugin/usage.html
Ultimately, you could specify some Ant <target/> attributes in the <target/> tag. Only depends attribute in Ant <target/> is not wrapped.
That does not prevent the feature from working, at least not from experience; by just removing the depends property and ordering the targets properly, it works.
Moreover, only the last target is considered by maven-antrun-plugin. You therefore need to find a way to evaluate your condition directly in that target.

Ant exec resultproperty is not working

I am calling a batch file using an Ant exec task and setting the result in resultpropery. But the return value never comes to Ant. Below is my code
<property name="BuildErrorCode" value="abc"/>
<exec executable="cmd" resultproperty="BuildErrorCode" failonerror="false"
dir="C:\workspace\build\">
<arg value="/c"/>
<arg value="cmake_cross_compile.bat"/>
</exec>
<echo message="Error Code:=${BuildErrorCode}" />
I exit my batch script by:
if %errorlevel% neq 0 exit /b %errorlevel%
When the script runs, i always get abc as value instead of return value from batch file. My batch file returns 2 for now and I have to stop the build
I want to do the following:
If the return value is <> 0 then i have to make the build fail which is not happening now.
Any idea how I can get he return value and make the ant build fail?
If you run the build script in verbose mode (ant -v), you will notice the line
Override ignored for property "BuildErrorCode"
Essentially once an ant property has been set its value cannot be changed. This SO question has details.
A possible workaround is to not declare the property.
...
<!--property name="BuildErrorCode" value="abc"/-->
<exec executable = "cmd" resultproperty="BuildErrorCode" failonerror="false" dir="D:\work">
<arg value="/c"/>
<arg value="cmake_cross_compile.bat"/>
</exec>
...
The exec task resultproperty will capture the exit code of the cmd interpreter. The way you are calling exit in the batch file though is not terminating cmd, it is only exiting the script. The exit code from cmd will be unaffected, and stay zero. If you simply remove the \b option of the exit command you will terminate the interpreter as well and see the exit code you supply propagated.
if %errorlevel% neq 0 exit %errorlevel%
To fail, you could use a fail task, perhaps something like this:
<fail message="cmake_cross_compile.bat exited non-zero">
<condition>
<not>
<equals arg1="${BuildErrorCode}" arg2="0"/>
</not>
</condition>
</fail>
Or you could set failonerror="true" in the exec task to fail immediately.

In Ant, how do I suppress the exec error "CreateProcess error=2"?

I'm attempting to execute a program, and if that fails I have a fallback method to get the information required. Not everyone who uses this build script will have the program installed. My task has the following:
<exec executable="runMe"
failonerror="false"
failifexecutionfails="false"
outputproperty="my.answer"
errorproperty="my.error"
error="myerror.txt" />
Apparently I misunderstand the Ant manual because I thought by setting error or errorproperty the error would be redirected and not shown on the screen.
Is it possible to hide the message "Execute failed: java.io.IOException: Cannot run program "runMe"..."?
Alternately, is there a way to determine if that program can be run without checking for its existence? If the program is on the user's system it won't be in the same place from user to user.
Thank you,
Paul
Try ant-contrib's try/catch/finally commands.
http://ant-contrib.sourceforge.net/tasks/tasks/trycatch.html
The goal for doing this was to get the Subversion revision for my project in Ant. Some developers have command line Subversion installed and others don't so I needed a way to test for the presence of svnversion.
In the end I used a batch file to test the command:
REM File checkCommand.bat
#echo off
%1 >NUL 2 >NUL
if errorlevel 1 goto fail
REM command succeeded
exit 0
:fail
REM command failed
exit 1
In my Ant target I run this like so:
<target name="checkForSvnversion">
<local name="cmdresult" />
<exec dir="." executable="com"
resultproperty="cmdresult"
failonerror="false"
failifexecutionfails="false">
<arg line="/c checkCommand.bat svnversion" />
</exec>
<condition property="exec.failed">
<equals arg1="${cmdresult}" arg2="1" trim="true" />
</condition>
</target>
I have two targets that depend on this result:
<target name="getRevisionFromSvnversion" depends="checkForSvnversion"
unless="exec.failed">
etc etc
</target>
and
<target name="getRevisionFromEntries" depends="checkForSvnversion"
if="exec.failed">
etc etc
</target>
Finally, the task I call to get the revision is:
<target name="getRevision"
depends="getRevisionFromSvnversion,getRevisionFromEntries">
<echo>My rev is ${svn.revision}</echo>
</target>

In Ant, how do I get the return value from an exec?

<target name="CheckState">
<exec executable="${App.path}"/>
</target>
In this task, the executable will return a value which will indicate the state of my app. How could I get the value returned in the Ant build file. I will use this value to determine some behaviour.
Use the resultproperty and failonerror attributes of the exec task, e.g.:
<target name="CheckState">
<exec executable="${App.path}"
resultproperty="App.state"
failonerror="false"/>
<echo message="App state was: ${App.state}" />
</target>
Quoting from the exec task docs Errors and return codes:
By default the return code of an exec
is ignored; when you set
failonerror="true" then any return
code signaling failure (OS specific)
causes the build to fail.
Alternatively, you can set
resultproperty to the name of a
property and have it assigned to the
result code (barring immutability, of
course).
If the attempt to start the program
fails with an OS dependent error code,
then halts the build unless
failifexecutionfails is set to false.
You can use that to run a program if
it exists, but otherwise do nothing.
What do those error codes mean? Well,
they are OS dependent. On Windows
boxes you have to look at the
documentation; error code 2 means 'no
such program', which usually means it
is not on the path. Any time you see
such an error from any Ant task, it is
usually not an Ant bug, but some
configuration problem on your machine.
Here is a generic way to check the result and display the output of the execution only if the process returns a failure code.
<property
name="my.project.tmp.exec.output"
value="${tmp.dir}/exec-output.txt"/>
<target
name="my.project.my.task">
<exec
executable="${App.path}"
output="${my.project.tmp.exec.output}"
resultproperty="my.project.my.task.result"
failonerror="false"/>
<loadfile
srcfile="${my.project.tmp.exec.output}"
property="my.project.my.task.output"
/>
<fail message="ERROR: ${my.project.my.task.output}">
<condition>
<not>
<equals arg1="${my.project.my.task.result}" arg2="0"/>
</not>
</condition>
</fail>
<delete file="${my.project.tmp.exec.output}"/>
</target>

Resources