I am using more then one target for setting the variable name depending on OS.
<target name="checkos">
<condition property="isWindows">
<os family="windows" />
</condition>
<condition property="isUnix">
<os family="unix" />
</condition>
</target>
<target name="if_windows" depends="checkos" if="isWindows">
<property name="path" location="deploy.exe"/>
</target>
<target name="if_unix" depends="checkos" if="isUnix">
<property name="path" location="deploy.sh"/>
</target>
How can i set it in the single target.
I used if and condition but it doesn't allow it to do so.
With ant >= 1.9.1 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"
>
<target name="setos">
<condition property="isWindows">
<os family="windows" />
</condition>
<property name="path" location="deploy.exe" if:true="${isWindows}"/>
<property name="path" location="deploy.sh" unless:true="${isWindows}"/>
</target>
</project>
otherwise with ant < 1.9.1 use something like :
<target name="checkos">
<condition property="isWindows">
<os family="windows" />
</condition>
</target>
<target name="if_windows" depends="checkos" if="isWindows">
<property name="path" location="deploy.exe"/>
</target>
<target name="if_unix" depends="checkos" unless="isWindows">
<property name="path" location="deploy.sh"/>
</target>
Related
I have a situation in a build file where I want two OS dependent versions of a macrodef and want to select which one gets "compiled" based on a flag that is true or false.
<condition property="use.windows.macros" value=true else=false
<os family="windows" />
</condition>
Pseudocode
if(use.windows.macrodef)
<macrodef aMacro
... windows version
</macrodef>
else
<macrodef aMacro
... non windows version
</macrodef>
endif
how does one do this sort of thing with the basic out of the box ant xml nodes?
Why do you want two versions of macro? You can use only one (assuming you have ant version >= 1.9.3)
<project xmlns:if="ant:if" xmlns:unless="ant:unless">
<condition property="os.windows">
<os family="windows"/>
</condition>
<condition property="os.linux">
<os family="unix" name="linux" />
</condition>
<macrodef name="sayHello">
<sequential>
<sequential if:set="os.windows">
<echo message="hello from windows" />
</sequential>
<sequential if:set="os.linux">
<echo message="hello from linux" />
</sequential>
</sequential>
</macrodef>
<sayHello />
</project>
Ok - yes a synthesis of the prior partial answer and my work on it but this is what I ended up with as a structure.
I have to create two macros - the first creates the others based on the flags.
I'm not sure how this jibes with canonical ant but it does the job I need done and is easy for someone to see what is meant.
<condition property="os.windows">
<os family="windows"/>
</condition>
<condition property="os.linux">
<os family="unix" name="linux" />
</condition>
<macrodef name="createOsMacros">
<sequential if:set="os.windows">
<macrodef name="doOsMacro">
<attribute name="printstring" default="windows string"/>
<sequential>
<echo message="#{printstring}" />
</sequential>
</macrodef>
</sequential>
<sequential if:set="os.linux">
<macrodef name="doOsMacro">
<attribute name="printstring" default="unix string"/>
<sequential>
<echo message="#{printstring}" />
</sequential>
</macrodef>
</sequential>
</macrodef>
<createOsMacros />
<doOsMacro />
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>
The above ant script implements if dir_is_empty then git-clone else git-fetch using Ant-1.7.1 core statements:
<target name="update" depends="git.clone, git.fetch" />
<target name="check.dir">
<fileset dir="${dir}" id="fileset"/>
<pathconvert refid="fileset" property="dir.contains-files" setonempty="false"/>
</target>
<target name="git.clone" depends="check.dir" unless="dir.contains-files">
<exec executable="git">
<arg value="clone"/>
<arg value="${repo}"/>
<arg value="${dir}"/>
</exec>
</target>
<target name="git.fetch" depends="check.dir" if="dir.contains-files" >
<exec executable="git" dir="${dir}">
<arg value="fetch"/>
</exec>
</target>
(see my other post)
But how to implement a target enabled by two conditions?
if dir_does_not_exist or dir_is_empty then git-clone else git-fetch
my current attempt:
<target name="git.clone"
depends="chk.exist, chk.empty"
unless="!dir.exist || dir.noempty" >
[...]
</target>
<target name="chk.exist">
<condition property="dir.exist">
<available file="${dir}/.git" type="dir"/>
</condition>
</target>
[...]
I would prefer Ant-1.7.1 core statements. But I am open about other possibilities as Ant contrib, or embedded script... Feel free to post your ideas...
(See also question Execute ANT task just if a condition is met)
Even when bound to Ant 1.7.1 you may combine your 3 chk targets into one, see the condition part in the snippet.
Since Ant 1.9.1 (better use Ant 1.9.3 because of bugs in Ant 1.9.1 see this answer for details) it is possible to add if and unless attributes on all tasks and nested elements, so no extra target needed, f.e. :
<project xmlns:if="ant:if" xmlns:unless="ant:unless">
<condition property="cloned" else="false">
<and>
<available file="${dir}/.git" type="dir" />
<resourcecount when="gt" count="0">
<fileset dir="${dir}/.git" />
</resourcecount>
</and>
</condition>
<exec executable="git" unless:true="${cloned}">
<arg value="clone" />
<arg value="${repo}" />
<arg value="${dir}" />
</exec>
<exec executable="git" dir="${dir}" if:true="${cloned}">
<arg value="fetch" />
</exec>
</project>
From the ant documentation on targets:
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>
Moreover, there were some discussions on dev#ant.apache.org and user#ant.apache.org mailing-lists:
Using multiple properties in the 'if' and 'unless' conditions (June 2006)
Support mutliple if and unless (August 2008)
Multiple conditions satisfying in an ant target (October 2008)
For example, the following target combines two properties (dir.exist and dir.noempty) to create another one (cloned) using operators <and> and <istrue> (many other operators are documented as <or>, <xor>, <not>, <isfalse>, <equals>, <length>).
<target name="chk" depends="chk.exist, chk.empty" >
<condition property="cloned">
<and>
<istrue value="dir.exist" />
<istrue value="dir.noempty" />
</and>
</condition>
</target>
The above property "cloned" is used by targets git.clone and git.fetch as follows:
<target name="update" depends="git.clone, git.fetch" />
<target name="git.clone" depends="chk" unless="cloned" >
<exec executable="git" >
<arg value="clone" />
<arg value="${repo}" />
<arg value="${dir}" />
</exec>
</target>
<target name="git.fetch" depends="chk" if="cloned" >
<exec executable="git" dir="${dir}">
<arg value="fetch"/>
</exec>
</target>
<target name="chk.exist" >
<condition property="dir.exist" >
<available file="${dir}" type="dir" />
</condition>
</target>
<target name="chk.empty" >
<fileset dir="${dir}" id="fileset" />
<pathconvert refid="fileset" property="dir.noempty" setonempty="false" />
</target>
This is a small piece of code please give a look at it then follow the description....
<condition property="${param1}">
<or>
<istrue value="win-x86"/>
<istrue value= "win-x86-client"/>
<istrue value= "win-x64"/>
</or>
</condition>
<target name="Mytarget" if="${param1}">
<echo message="executing windows family build:::${param1}"/>
</target>
<target name="print.name" >
<antcall target="win-x86-build">
<param name="param1" value="${platform.id}"/>
</antcall>
</target>
I want that when ever platform.id contains any of the windows family name it should print the message EXECUTING WINDOWS FAMILY BUILD but the problem is that it is printing this message even when the family is unix.
I think either I am not checking the condition properly or else i am doing some other mistake.
Can someone help me out with this please?
Since ant 1.9.1 you can do this:
<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>
Looks like you misunderstood the Condition Task:
property: The name of the property to set.
Try using the Conditionos:
Test whether the current operating system is of a given type.
Peter is trying to explain that you must explicitly specify the property name. Try the following to make your code work:
<project name="demo" default="Mytarget">
<condition property="windoze">
<or>
<equals arg1="${param1}" arg2="win-x86"/>
<equals arg1="${param1}" arg2="win-x86-client"/>
<equals arg1="${param1}" arg2="win-x64"/>
</or>
</condition>
<target name="Mytarget" if="windoze">
<echo message="executing windows family build:::${param1}"/>
</target>
</project>
A better solution would be to make use of operating system tests built into ANT's condition task.
<project name="demo" default="Mytarget">
<condition property="windoze">
<os family="windows"/>
</condition>
<target name="Mytarget" if="windoze">
<echo message="executing windows family build:::${os.name}-${os.arch}-${os.version}"/>
</target>
</project>
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