How to put two conditions in ANT Target? - ant

My need is to check two conditions in my ANT Target. If either of them is true the ant target must execute.
<target name="generateArtifacts" if="${generateABC}" or if="${generatePQR}">
...
/>
The above syntax in WRONG. How to make it correct?

Maybe there's something simpler, but the following would do, I think:
<condition property="artifactsMustBeGenerated">
<or>
<isTrue value="${generateABC}"/>
<isTrue value="${generatePQR}"/>
</or>
</condition>
<target name="generateArtifacts" if="${artifactsMustBeGenerated}">
...
/>

Related

Getting condition doesn't support the nested "then" element in <condition>

I'm new to Ant/Apache. When I tried to use <condition> tag in XML it's throwing an error. condition doesn't support the nested "then" element. Here is my code
<target name="determine-ae-build">
<condition property="ApplicationName">
<equals arg1="${ApplicationName}" arg2="new"/>
<then>
<echo>3.9 Robots Config Copied</echo>
</then>
<else>
<condition property="ApplicationName">
<equals arg1="${ApplicationName}" arg2="old"/>
<then>
<echo>3.8 Robots Config Copied</echo>
</then>
<else>
<echo>3.9 Robots Config Copied</echo>
</else>
</condition>
</else>
</condition>
</target>
I've tried with IF also but since my Ant version is not supporting to do this. Can someone help to resolve this issue. Thanks! in advance
The condition task simply sets a property; it doesn't contain nested build logic. The property that it sets can later be used to control which targets are executed.
While you can use antcontrib's extra if, then, and else tasks to accomplish something like what you showed in your example, I'd recommend sticking to the native Ant approach, which relies on target dependencies and uses separate targets to control build logic:
<project name="build" basedir="." default="build">
<target name="build" depends="copy-3.8,copy-3.9" />
<target name="copy-3.8" depends="determine-ae-build" if="copy.old">
<echo>3.8 Robots Config Copied</echo>
</target>
<target name="copy-3.9" depends="determine-ae-build" unless="copy.old">
<echo>3.9 Robots Config Copied</echo>
</target>
<target name="determine-ae-build">
<condition property="copy.old">
<equals arg1="${ApplicationName}" arg2="old"/>
</condition>
</target>
</project>
With the above script, you would run ant build (possibly with -DApplicationName=old). The build target depends on both copy targets, both of which depend on determine-ae-build. The determine-ae-build target will therefore run first. If ApplicationName is set to "old" (either from a properties file that has been loaded, or from being provided in command line with -DApplicationName=old) then the property copy.old will be set to true. Otherwise it will remain unset.
Then copy-3.8 and copy-3.9 will be called. If copy.old is is true, copy-3.8 will run. Otherwise, it will be skipped. copy-3.9 has no condition so it will run no matter what.
Lastly, the build target will execute because it was the original target called from the command line, but it contains no actual steps so the build will finish.
<target name="prepare-copy" description="copy file based on condition" depends="determine-ae-build, prepare-copy-old, prepare-copy-new, prepare-copy-default">
<sleep seconds="10"/> --To read the results
</target>
<target name="prepare-copy-old" description="copy file based on condition" if="copy.old">
<echo>Old File Copied </echo>
</target>
<target name="prepare-copy-new" description="copy file based on condition" if="copy.new">
<echo>New File Copied</echo>
</target>
<target name="prepare-copy-default" description="copy file based on false condition" if="copy.default">
<echo>Default File Coping</echo>
</target>
<target name="determine-ae-build">
<condition property="copy.old">
<equals arg1="${ApplicationName}" arg2="old"/>
</condition>
<condition property="copy.new">
<equals arg1="${ApplicationName}" arg2="new"/>
</condition>
<condition property="copy.default">
<not>
<or>
<equals arg1="${ApplicationName}" arg2="new"/>
<equals arg1="${ApplicationName}" arg2="old"/>
</or>
</not>
</condition>
</target>
Explanation: Calling way "ant -Dcopy.old = true prepare-copy". Here we are passing to copy old file hence, "Old File Copied" will copied. If you call it like "ant prepare-copy" it'll call "Default File Coping".
Kindly Accept my answer if it is answered your question.Thankyou!

How to check if Ant is executed under certain path?

How can I use Ant to verify that the current working directory is located (arbitrarily deeply nested) under a certain path? For example, I want to execute a target only if the current directory is part of /some/dir/, for example if Ant is executed in directory /some/dir/to/my/project/.
The best I could come up with is a String contains condition:
<if>
<contains string="${basedir}" substring="/some/dir/"/>
<then>
<echo>Execute!</echo>
</then>
<else>
<echo>Skip.</echo>
</else>
</if>
This works for my current purpose but I'm afraid it might break some time in the future... for example when a build is executed in path /not/some/dir/ which is also contains the specified directory string.
Are there any more robust solutions like a startsWith comparison or even better a file system based check...?
There is no specific startswith condition in native Ant, but there is a matches condition that takes regular expressions.
As a side note, ant-contrib is rarely necessary for most build scripts, and will often lead to unreliable code. I would strongly recommend avoiding it.
Here's a sample script to illustrate how you can use the matches condition with native Ant. The test target is, of course, just for demonstration.
<property name="pattern" value="^/some/dir" />
<target name="init">
<condition property="basedir.starts.with">
<matches pattern="${pattern}" string="${basedir}" />
</condition>
</target>
<target name="execute" depends="init" if="basedir.starts.with">
<echo message="Executing" />
</target>
<target name="test">
<condition property="dir1.starts.with">
<matches pattern="${pattern}" string="/some/dir/" />
</condition>
<condition property="dir2.starts.with">
<matches pattern="${pattern}" string="/some/dir/to/my/project/" />
</condition>
<condition property="dir3.starts.with">
<matches pattern="${pattern}" string="/not/some/dir/" />
</condition>
<echo message="${dir1.starts.with}" />
<echo message="${dir2.starts.with}" />
<echo message="${dir3.starts.with}" />
</target>

How to stop ant script execution or skip targets without fail?

I want to terminate an ant script, or skip some targets, but without the fail task. I wanted to do it like this:
`
<target name="init">
<condition property="canContinue">
<not>
<equals arg1="${isOffline}" arg2="1" />
</not>
</condition>
</target>
<target name="init-setup" depends="init" if="canContinue">
<echo message="CanContinue: ${canContinue}"/>
</target>
<target name="doIt" depends="init-setup">
</target>
`
I would like to skip all the targets which depend on init-setup, not just init-setup.
How can I do this?
Thank you!
If you're not using explicit fail tasks, you'll need to add your boolean flag to each target you want to skip.
Using your example:
<target name="doIt" depends="init-setup" if="canContinue">
</target>

How to use logical operators in ant?

i have a small peice of code which prints if platform is unix or windowsas
<if>
<equals=${arg1} value="linux-86"/>
<then>
<echo message="linux"
<then>
<elseif>
<equals=${arg1} value="linux-64"/>
<then>
<echo message="linux"/>
</then>
</elseif>
<else>
<echo message="Windows">
</else>
</if>
Here we can see we are unnecessarily checking first two conditions for same message,is there any OR operator in ant like we have in c ||,so that we can write arg1=linux-64||linux-86....if there is please tell me how should i use this will save up lot of time here
<condition property="WinPlatform.Check">
<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="WinPlatform.Check">
<echo message="executing windows family build:::${param1}"/>
</target>
now call Mytarget with your parameter,it will work
The if task is part of ant-contrib. It is not available in core Ant.
Various conditions are available in core Ant and can be used, for example, to make target execution conditional.
Before 1.8, if/unless conditions evaluate "is the property set?"
<target name="test" if="foo" unless="bar"/>
From 1.8, if/unless conditions can evaluate "is the property true/false":
<target name="test" if="${foo}" unless="${bar}"/>
Why don't you have a look in the ant manual? http://ant.apache.org/manual/Tasks/conditions.html
Or google for "ant if task".

Different targets on Different OS with Ant

I have an ant target I don't want called unless I am running ant on Linux (Not called on Windows)
<target name="jar.all" depends="clean,compile.nic,jar,jar.resources"/>
The target that I don't want called on Windows is: compile.nic
How can I do this?
Insert an if property to your compile.nic target.
<target name="compile.nic" if="windowsos">
And use this conditions before running your target
<condition property="windowsos">
<os family="windows" />
</condition>
<condition property="linuxos">
<os family="unix" />
</condition>
Here is a real-world example for Windows vs. UNIX commands. The ELSE improves on previous answers.
<condition property="maven.executable" value="mvn.bat" else="mvn">
<os family="windows" />
</condition>
<target name="clean">
<exec executable="${maven.executable}">
<arg value="clean" />
</exec>
</target>
Can I make the Ant copy task OS-specific?
Additionally some tasks support os attribute. for example exec:
<exec executable="cmd" os="windows"/>
You can use the os condition to set a property, and then skip your target by adding either the if or unless attributes (depending on how you define your property)

Resources