Condition in Ant not working properly - jenkins

I'm doing a task in Ant which tests whether a server is stopped or running, and in case the server is stoppped, the Ant task fail and sends an email. The problem is that my condition isn't working properly, and the tasks always goes good, regardless the server is stopped or running.
Here is the code of my condition:
<condition property="check" value="true" >
<or>
<equals arg1="${state}" arg2="STOPPED" />
<equals arg1="${state}" arg2="STOPPING" />
</or>
</condition>
<fail if="${check}" message="Server stopped"/>
The variable state can have the next values: STOPPED, STOPPING or STARTED (I checked before that the value is correct). As I said, even if state = STOPPED or state = STOPPING, the property check is never set, so my task is always successful.
I have tried using forcestring and casesensitive in equals, and I have tried:
<fail if="check" message="Server stopped"/>
but the condition is still not working.
Any advice or idea on how to solve this and make it work?
Thanks.

try this:
<fail message="Server stopped">
<condition>
<or>
<equals arg1="${state}" arg2="STOPPED" />
<equals arg1="${state}" arg2="STOPPING" />
</or>
</condition>
</fail>

Try :
<target name="server_stopped" if="check">
<fail message="Server stopped"/>
</target>

Related

Retry task on exec task in Ant gives incorrect resultproperty

I have a piece of code in my ant build.xml
<retry retrycount="10" retrydelay="30000">
<exec executable="${env.M2_HOME}/bin/mvn.cmd" output="#{log}" failonerror="true" resultproperty="res" timeout="#{timeoutmillis}" errorproperty="error">
...
</exec>
</retry>
<echo message="${res}"/>
I retry my cmd task if if fails once upto 10 times. But even if it were to succeed after retrying a few turns, the value returned in res is 1 even though it is a build success. I expect it to be 0 as if it was SUCCESS.
Properties in Ant are immutable (they're not variables), so even if your exec task eventually succeeds, the result property will have already been set to whatever it got from the first run.
You can get past this by creating a sequential block and using the local task inside it to control your property scope.
<retry retrycount="10">
<sequential>
<local name="do.fail" />
<input addproperty="do.fail" validargs="y,n" message="fail?" />
<fail>
<condition>
<equals arg1="${do.fail}" arg2="y" />
</condition>
</fail>
</sequential>
</retry>
Running the above example will prompt the user until "n" is provided as input (or 10 retries).
This is not a direct answer to the question I asked. But taking into consideration what CAustin and jdpjamesp said, I'm reading the content of my output log to see whether the command failed or not.
The cmd will return 1 even if it passed after some n number of failures. But the output log in case of mvn will have "BUILD SUCCESS" only if the command passes at the end. So searching for this string works for me. The log should not be appended after every time though.
So I implemented this-
<property name="pass.string" value="BUILD SUCCESS" />
<resourcecount property="pass.string.count">
<fileset id="matches" file="#{log}">
<contains text="${pass.string}" />
</fileset>
</resourcecount>
<if>
<equals arg1="${pass.string.count}" arg2="0" />
<then>
..
</then>
<else>
..
</else>
</if>

Number of parameters passed in a Ant command line

I would know if it's possible using an Ant task to know the number of parameters passed to an Ant target ? For example, with the following command :
ant myTarget -Darg1="arg1" -Darg2="arg2"
I would like to be able, inside the "myTarget" target, to get that the user passed exactly 2 arguments.
I have built this condition:
<condition property="params.set">
<and>
<isset property="arg1"/>
<isset property="arg2"/>
</and>
</condition>
but I would like to add in it a check on the number of passed parameters.
Or perhaps is it possible to get the same information using a groovy task in the "myTarget" target ? I think getting the whole command line would be enough (but how to do this ?) because I can then count the number of " -D" tokens.
Thanks in advance.
Personally, I would recommend checking for specific properties that the user should not be setting, as opposed to simply counting them and assuming any extras are unwanted. That could make the script rather annoying to deal with if someone is modifying or debugging it later on.
This would be my approach:
<fail>
<condition>
<or>
<not>
<or>
<isset property="arg1" />
<isset property="arg2" />
</or>
</not>
<isset property="doNotSet1" />
<isset property="doNotSet2" />
<isset property="doNotSet3" />
</or>
</condition>
</fail>
However, if you're dead-set on doing it the way you described, it should technically be possible. Ant stores any properties defined by the initial command in a propertyset named "commandline". However, this set includes more than just user properties defined with -D.... It will also contain generated properties such as ant.file that are set automatically. The number of these properties can vary depending on how your script is configured (for example specifying a default target in the root element), so those will need to be filtered out. Fortunately, these generated properties all begin with ant.file or ant.project, so they're relatively simple to identify.
<fail>
<condition>
<or>
<not>
<or>
<isset property="arg1" />
<isset property="arg2" />
</or>
</not>
<resourcecount when="ne" count="2">
<intersect>
<propertyset>
<propertyref builtin="commandline" />
</propertyset>
<propertyset>
<propertyref regex="^(?!ant\.(?:file|project))" />
</propertyset>
</intersect>
</resourcecount>
</or>
</condition>
</fail>
I finally used:
<resourcecount when="ne" count="2">
<difference>
<propertyset>
<propertyref builtin="commandline"/>
</propertyset>
<union>
<propertyset>
<propertyref prefix="ant.file"/>
</propertyset>
<propertyset>
<propertyref prefix="ant.project"/>
</propertyset>
</union>
</difference>
</resourcecount>
with also:
<condition>
<or>
<equals arg1="${library.name}" arg2=""/>
<equals arg1="${suffix}" arg2=""/>
</or>
</condition>
and it works well. Thanks again for your answers containing very interesting trails.

Ant property not setting correctly?

I'm reasonably new to ant and I'm not quite sure why
I am getting the following error when I run ant: Cannot locate target java: please set JAVA_HOME to its location. I've pasted the relevant source code below. From what I can see, the target -check-langtools.jdk.home is being executed. But because it depends on -def-check, that gets executed. Do the attributes (name, property, marker) get passed into -def-check when -check-langtools.jdk.home is being called? If so - the failure must be happening at the condition where is the property is not being set (i.e isset must be returning false). I don't understand how the property is not being set, if it is able to print out the value (i.e. JAVA_HOME).
Background: Trying to build langtools from OpenJDK
<target name="-def-check">
<macrodef name="check">
<attribute name="name"/>
<attribute name="property"/>
<attribute name="marker" default=""/>
<sequential>
<fail message="Cannot locate #{name}: please set #{property} to its location">
<condition>
<not>
<isset property="#{property}"/>
</not>
</condition>
</fail>
<fail message="#{name} is not installed in ${#{property}}">
<condition>
<and>
<not>
<equals arg1="#{marker}" arg2=""/>
</not>
<not>
<available file="${#{property}}/#{marker}"/>
</not>
</and>
</condition>
</fail>
</sequential>
</macrodef>
</target>
<target name="-check-langtools.jdk.home" depends="-def-check">
<!-- <check name="target java" property="langtools.jdk.home" marker="${java.marker}"/> -->
<check name="target java" property="JAVA_HOME" marker="${java.marker}"/>
</target>
<target name="-check-jtreg.home" depends="-def-check">
<check name="jtreg" property="jtreg.home" marker="lib/jtreg.jar"/>
</target>
This question was a bit of a blonde one but I ended up approaching this problem the wrong way, but I'll post up the answer here if anyone is new to Ant, and looking to do the same thing. To build the langtools portion of javac, what they need to do is set langtools.jdk.home=path_to_jdk_installation in a separate build.properties file that is included.
(eg. langtools.jdk.home=/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home)

How to fail an ant build if a property is not empty

I have an ANT build file which has the line-
<java classname="arq.sparql" fork="true" outputproperty="javaresult" errorproperty="javaerror">
Now I want add the condition to fail the build of the property 'javaerror' is not empty.
So I have the condition written like this :
<fail message="${javaerror}">
<condition>
<not>
<equals javaerror=""/>
</not>
</condition>
</fail>
But this did not work, can you please help.
Kind regards
Som
Your equals condition has the wrong syntax, it will work like that :
<fail message="${javaerror}">
<condition>
<not>
<equals arg1="${javaerror}" arg2=""/>
</not>
</condition>
</fail>
see Ant manual conditions for details
-- EDIT --
Alternatively you could use the new if/unless feature introduced with Ant 1.9.1 but you should use Ant 1.9.3 because of bugs in Ant 1.9.1 see this answer for details
<project xmlns:if="ant:if" xmlns:unless="ant:unless">
<property name="javaerror" value="whatever"/>
<fail message="${javaerror}" unless:blank="${javaerror}"/>
</project>
You're looking for
<fail message="failed" if="javaerror"/>
Fail ant task doc

How can I check if file exists, and if not kill the build?

How can I stop a build, and notify the user if a file does not exist? I know I can use the available task to set a property if a file exists, but I'm not sure how I would stop a build and echo something.
I would like to stick with core tasks if possible.
You can use the fail task for all your failing needs. The last example on that page is actually pretty much what you need
<fail message="Files are missing.">
<condition>
<not>
<resourcecount count="2">
<fileset id="fs" dir="." includes="one.txt,two.txt"/>
</resourcecount>
</not>
</condition>
</fail>
A little simpler (I wish it could be made simpler)
<fail message="file ${myfile} not set or missing">
<condition>
<not>
<available file="${myfile}" />
</not>
</condition>
</fail>
Set your property and use the Fail task with the if attribute.
This can be done more compactly (as indicated by Jason Punyon). Specifically, assuming the file you want is in the property file, do:
<available file="${file}" property="file.exists" />
<fail message="File missing: ${file}" unless="file.exists" />
These kind of checks are common, so it might pay off to use a macro.
Here is a macro based on the solution by leonbloy:
<macrodef name="require">
<attribute name="file"/>
<attribute name="message" default="file #{file} not set or missing"/>
<sequential>
<fail message="#{message}">
<condition>
<not>
<available file="#{file}" />
</not>
</condition>
</fail>
</sequential>
</macrodef>
Use like this:
<require file="${myfile}" />
or
<require file="${myfile}" message="my custom message" />

Resources