to check if the file is available or not in ant - ant

Requirement : to check if the file is available or not and then based on true or false value perform some task.
I am using task:
<varNested name="path" value="/user1/abc.jar"/>
<available file="${path}" property="file.available"/>
Problem 1:
Now when I am trying to print this property:
<echo message="value of file is available is : ${file.available}"/>
rather than printing the value true it prints ${file.available}
Problem 2:
Will this code snippet work? if not, what shall be used instead of equalsNested?
...
</then>
<else>
...
</else>
</if>

Try this:
<property name="abc" value="false" />
<available file="somefile" property="abc" value="true"/>
<echo message="value of file is available is : ${abc}"/>

Related

how to ignore a failure ant task?

I have this ant script that is reading from a parameter a list of components and running other ant tasks (build.xml's):
<for list="${components.locations}" param="component" failonany="false">
<sequential>
<property name="#{component}" value="true"/>
<if>
<and>
<available file="${repository.location}/#{component}"/>
<available file="${repository.location}/${jars.location}"/>
</and>
<then>
<ant inheritAll="false" antfile="${repository.location}/#{component}/build.xml">
<!-- failonerror="false" -->
<property name="copy.libs" value="${copy.libs}"/>
<property name="repository.location" value="${repository.location}"/>
<property name="jars.location" value="${repository.location}/${jars.location}"/>
</ant>
</then>
</if>
</sequential>
</for>
The problem is if one component is failing, the script doesn't continue to next one.
I tried running with -k (-keep-going) argument but it doesn't help.
I found this property failonerror="false" but it's valid for "exec" tasks and couldn't integrate it with "ant" tasks or inside a "target".
Other direction was "failonany" property of the "for" but I didn't manage setting it up explicitly.
Can you please advice...
Thanks.
First of all, I would suggest deleting ant-contrib.jar and never looking back. Believe me, you will be doing yourself a favor.
You can use the subant task to iterate Ant builds on a set of directories or files. Simply define a dirset and pass any extra properties you need.
Instead of using ant-contrib's <if> block, use the standard target's if attribute to switch the entire target on or off. This is much safer and better practice.
<property name="repository.location" location="repository_location" />
<property name="jars.location" location="${repository.location}/jars" />
<property name="components" value="dir1,dir2,dir3" />
<target name="init">
<condition property="jars.available">
<available file="${jars.location}" />
</condition>
</target>
<target name="default" depends="init" if="jars.available">
<subant inheritall="false" failonerror="false">
<dirset id="components.dirs" dir="${repository.location}" includes="${components}" />
<property name="copy.libs" value="${copy.libs}" />
<property name="repository.location" value="${repository.location}" />
<property name="jars.location" value="${jars.location}" />
</subant>
</target>

Available tag in ant is always true if a file is unavailable also

This code is always returning a true value even if file at given path does not exists
<available file="${x}/schema/#{componentname}-schema.sql" type="file" property="schema.file" />
<if>
<equals arg1="true" arg2="${schema.file}" />
<then>
<debug message="****schemafile is ${schema.file} ******" />
</then>
</if>
Output is always :-
*schemafile is true***
even if file is not available at that path.
Please help me to find the error.
I've refactored your example, in order to use standard ANT tasks:
<project name="demo" default="run" xmlns:if="ant:if">
<property name="src.dir" location="src"/>
<target name="run">
<available file="${src.dir}/schema/schema.sql" type="file" property="schema.file" />
<echo message="****schemafile is ${schema.file} ******" if:set="schema.file"/>
</target>
</project>
Notes:
I don't recognise the "debug" task so use the standard "echo" task instead
I recommend not using the ant-contrib "if" task. ANT 1.9.1 introduced an if attribute which can be used instead.
The following alternative variant will work with older versions of ANT. It uses an "if" target attribute to perform conditional execution:
<project name="demo" default="run">
<property name="src.dir" location="src"/>
<available file="${src.dir}/schema/schema.sql" type="file" property="schema.file" />
<target name="run" if="schema.file">
<echo message="****schemafile is ${schema.file} ******"/>
</target>
</project>
problem was i was iterating above code in for loop, and since property is immutable, it is always set to true if set at-least once. Thats why after 1 iteration even if the file was not found, it echoes schemafile is true** .
i have added below code to set property to false after that code
<var name="schema.file" unset="true"/>
<property name="schema.file" value="false"/>

Check multiple properties are set and not blank (ant)

I'm in a situation that involves running an ant build with optional parameters that are always specified but but not always defined, like so
ant -DBUILD_ENVIRONMENT=test -Dusername_ext= -Dconf.dir_ext= -Dcgi-dir_ext=
If the parameters are not given values on the command line they will be by loading a .properties file. I have the following code that will check if the property isset and is not blank.
<if>
<bool>
<and>
<isset property="username_ext"/>
<not>
<equals arg1="${username_ext}" arg2="" />
</not>
</and>
</bool>
<then>
<property name="username" value="${username_ext}" />
</then>
</if>
<property file="${BUILD_ENVIRONMENT}.properties" />
Since there are multiple properties it seems like I should write a target that will do the same actions for each property rather than repeat that code every time.
<antcall target="checkexists">
<property name="propname" value="username"/>
<property name="paramname" value="username_ext"/>
</antcall>
<antcall target="checkexists">
<property name="propname" value="conf.dir"/>
<property name="paramname" value="conf.dir_ext"/>
</antcall>
But AFAIK an antcall will not set a global property. How then can I write a target that will accept the name of a parameter it needs to check is set and is not blank, and then copy that in to a parameter that other targets can use?
Rather than using a target you could use a macro to conditionally set properties based on whether or not another property is set to a non-empty value.
<macrodef name="set-property">
<attribute name="name" />
<attribute name="if-property-isset" />
<attribute name="value" default="${#{if-property-isset}}" />
<sequential>
<condition property="#{name}" value="#{value}">
<and>
<isset property="#{if-property-isset}" />
<not>
<equals arg1="${#{if-property-isset}}" arg2="" />
</not>
</and>
</condition>
</sequential>
</macrodef>
<target name="test-macro">
<set-property name="username" if-property-isset="username_ext" />
<set-property name="conf.dir" if-property-isset="conf.dir_ext" />
<property name="conf.dir" value="default conf directory" />
<echo message="username = ${username}" />
<echo message="conf.dir = ${conf.dir}" />
</target>
Output
$ ant test-macro -Dusername_ext=jsmith -Dconf.dir_ext=
Buildfile: /your/project/build.xml
test-macro:
[echo] username = jsmith
[echo] conf.dir = default conf directory
BUILD SUCCESSFUL
Total time: 1 second
Alternate Property Value
This macro also allows you set the property to a different value than the one provided on the command line.
<target name="test-macro">
<set-property name="username" if-property-isset="username_ext"
value="It worked!" />
<set-property name="conf.dir" if-property-isset="conf.dir_ext" />
<property name="conf.dir" value="default conf directory" />
<echo message="username = ${username}" />
<echo message="conf.dir = ${conf.dir}" />
</target>
Output
$ ant test-macro -Dusername_ext=jsmith -Dconf.dir_ext=
Buildfile: /your/project/build.xml
test-macro:
[echo] username = It worked!
[echo] conf.dir = default conf directory
BUILD SUCCESSFUL
Total time: 1 second

How to check if a property exists?

How do I check the existence of a property using Ant?
I am open to the use of ant-contrib, if Ant doesn't provide a similar thing.
Also, ant-contrib has an assert task, which provides exists, but the assertion is not what I need here since I would prefer a boolean return value.
You can use the Condition task with an isset condition.
<project default="test">
<property name="a" value="a"/>
<target name="test">
<condition property="a.set" else="false">
<isset property="a"/>
</condition>
<condition property="b.set" else="false">
<isset property="b"/>
</condition>
<echo message="a set ? ${a.set}"/>
<echo message="b set ? ${b.set}"/>
</target>
</project>
Output:
test:
[echo] a set ? true
[echo] b set ? false
Since Ant 1.9.1 it is possible to use "if" and "unless" attributes. You can use these new attributes if you add the 2 namespaces xmlns:if="ant:if" and xmlns:unless="ant:unless" to the project.
<!DOCTYPE project>
<project xmlns:if="ant:if" xmlns:unless="ant:unless">
<property unless:set="property" name="property.is.set" value="false"/>
<property if:set="property" name="property.is.set" value="true"/>
<echo>${property.is.set}</echo>
</project>
see also https://ant.apache.org/manual/ifunless.html

How to set an Ant property only if it is unset

I can't figure out how to set an Ant property on the condition that it has not been set (i.e it is not defined in the properties file and should automatically default).
So far, I only have the following code:
<condition property="core.bin" value="../bin">
<isset property="core.bin"/>
</condition>
But this only seems to work if the value is defined in a <property> tag.
Does anyone know how to conditionally set a property for the first time if it currently unset?
You simply can set the property with the property-task. If the property is already set, the value is unchanged, because properties are immutable.
But you can also include 'not' in your condition:
<condition property="core.bin" value="../bin">
<not>
<isset property="core.bin"/>
</not>
</condition>
Ant does this by default; if the property is already set; setting it again has no effect:
<project name="demo" default="demo">
<target name="demo" >
<property name="aProperty" value="foo" />
<property name="aProperty" value="bar" /> <!-- already defined; no effect -->
<echo message="Property value is '${aProperty}'" /> <!-- Displays 'foo' -->
</target>
</project>
Gives
/c/scratch> ant -f build.xml
Buildfile: build.xml
demo:
[echo] Property value is '${aProperty}'
BUILD SUCCESSFUL
Total time: 0 seconds
/c/scratch> ant -f build.xml
Buildfile: build.xml
demo:
[echo] Property value is 'foo'
BUILD SUCCESSFUL
Properties cannot be redefined; to do this you need to use something like the variable task from ant-contrib.
The easiest way to do what you want:
<if>
<not>
<isset property="your.property"/>
</not>
<then>
<property name="your.property" value="your.value"/>
</then>
</if>
There is support of using 'else' within : https://ant.apache.org/manual/Tasks/condition.html to serve your exact purpose.
else
The value to set the property to if the condition evaluates to false. By default the property will remain unset. Since Apache Ant 1.6.3
So change to :
<condition property="core.bin" else="../bin">
<isset property="core.bin"/>
</condition>
Properties in Ant are immutable. After defined they cannot be changed.
But the Ant Contrib package offers the variable task. It works like a property but the values can be modified and unset.
Exmaple from the variable task documentation:
<var name="x" value="6"/>
<if>
<equals arg1="${x}" arg2="6" />
<then>
<var name="x" value="12"/>
</then>
</if>
<echo>${x}</echo> <!-- will print 12 -->

Resources