In ant given a true or false property how can I conditionally define a macrodef - ant

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 />

Related

ant: condition command does not find pattern when pattern is a file path

I am using the following code with the idea of finding a file in a directory that is also part of a list in a file:
<loadfile property="ReportFileContent" srcFile="${ReportFile}"/>
<for param="file">
<path>
<fileset dir="${MainDir}" includes="**/**"/>
</path>
<sequential>
<basename file="#{file}" property="#{file}" />
<condition property="found-file${index2}">
<matches pattern="#{file}" string="${ReportFileContent}"/>
</condition>
<if>
<isset property="found-file${index2}"/>
<then>
<echo message=" Found file #{file}" level="warning" />
</then>
<else>
<echo message="Not Found file #{file}" level="warning" />
</else>
</if>
<math result="index2" operand1="${index2}" operation="+" operand2="1" datatype="int" />
</sequential>
</for>
The command is not working though as it is not finding the file that is available in ${ReportFileContent}.
The content of the ReportFileContent property is the following:
c:\___tools\test\file1.txt;2
c:\___tools\test\file2.txt;2
c:\___tools\test\file3.txt;2
Any idea why the condition is not working correctly?
Thanks
Tony

how to change variable depending on OS in ant

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>

Ant- How can i compare the list of strings?

<target name="build">
<for list="${platform}" param="platform" trim="true">
<sequential>
<if>
<equals arg1="${platform}" arg2="${project.SuppoortedPlatforms}" />
<then>
<antcall target="package.${platform}" />
</then>
</if>
</sequential>
</for>
</target>
where i'm getting platfrom values at runtime (eg:windows,ios) and project.SuppoortedPlatforms is declared under build.properties (eg:android,ios). how can i compare the list of strings?
could anyone help me to solve this problem?
Thanks,
sandhiya
You are looping over a comma-separated list of platforms, and for each one you're checking if it is contained in the list of supported platforms in project.SuppoortedPlatforms. This should go like this:
<for list="${platform}" param="platformParam" trim="true">
<sequential>
<if>
<contains string="${project.SuppoortedPlatforms}" substring="#{platformParam}" />
<then>
<antcall target="package.#{platformParam}" />
</then>
</if>
</sequential>
</for>
The parameter in the loop should be accessed with # instead of $. Also it would be better to rename the parameter for readability (platformParam instead of platform).
Instead of using contains task, i myself tried with the nested for loop, its cool working fine.
<for list="${platforms}" param="platformparam" trim="true">
<sequential>
<for list="${project.SupportedPlatforms}" param="supplatformparam" trim="true">
<sequential>
<if>
<equals arg1="#{platformparam}" arg2="#{supplatformparam}" />
<then>
<antcall target="package.#{platformParam}" />
</then>
</if>
</sequential>
</for>
</sequential>
</for>

Structure ant projects

I am currently writing an ant project xml file and I am looking for some hints and tips to improve the structure and readability of the project.
<target name="eatnutsOnClient" >
<monkey.eatnuts clientName="${clientName}" label="${nutLabel}" />
<if><not> <equals arg1="${returnCode}" arg2="0"/> </not><then>
<echo message="eatnuts-[${nutlabel}]_[${returnCode}]${line.separator}" file="${reachedFile}" append="true" />
</then></if>
</target>
<target name="eatnuts" depends="createClient,eatnutsOnClient,destroyClient"/>
In order to manage the return codes I would like to have the possibility to replace the full if section that I need to replicate over quite some targets by a sort of function which I can call to handle the returncode logic. I guess one option would be to create a target which only contains the if section and add it to the depend list of each task? Are there better ways?
An Ant <macrodef> provides a function-like way to share code:
<project name="ant-macrodef-echo" default="run">
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<macrodef name="echo-macrodef">
<attribute name="returnCode"/>
<sequential>
<if>
<not>
<equals arg1="#{returnCode}" arg2="0"/>
</not>
<then>
<echo message="#{returnCode}" />
</then>
</if>
</sequential>
</macrodef>
<target name="run">
<echo-macrodef returnCode="42"/>
<echo-macrodef returnCode="0"/>
<echo-macrodef returnCode="-9"/>
</target>
</project>
Results:
run:
[echo] 42
[echo] -9

How to read properties file in ant

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

Resources