48

Is there an if/else condition that I can use for an Ant task?

This is what i have written so far:

<target name="prepare-copy" description="copy file based on condition">
        <echo>Get file based on condition</echo>
    <copy file="${some.dir}/true" todir="."  if="true"/>
</target>

The script above will copy the file if a condition is true. What if the condition is false and I wish to copy another file? Is that possible in Ant?

I could pass a param to the above task and make sure the param that's passed is

rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
Jono
  • 17,341
  • 48
  • 135
  • 217

5 Answers5

47

The if attribute does not exist for <copy>. It should be applied to the <target>.

Below is an example of how you can use the depends attribute of a target and the if and unless attributes to control execution of dependent targets. Only one of the two should execute.

<target name="prepare-copy" description="copy file based on condition"
    depends="prepare-copy-true, prepare-copy-false">
</target>

<target name="prepare-copy-true" description="copy file based on condition"
    if="copy-condition">
    <echo>Get file based on condition being true</echo>
    <copy file="${some.dir}/true" todir="." />
</target>

<target name="prepare-copy-false" description="copy file based on false condition" 
    unless="copy-condition">
    <echo>Get file based on condition being false</echo>
    <copy file="${some.dir}/false" todir="." />
</target>

If you are using ANT 1.8+, then you can use property expansion and it will evaluate the value of the property to determine the boolean value. So, you could use if="${copy-condition}" instead of if="copy-condition".

In ANT 1.7.1 and earlier, you specify the name of the property. If the property is defined and has any value (even an empty string), then it will evaluate to true.

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • In this example, would it be possible to include some elements under "prepare-copy" that would be used regardless of whether "prepare-copy-true" or "prepare-copy-false" was used? – called2voyage Jan 25 '16 at 18:15
  • Of course. The target can have content, and the tasks would be executed after the depends targets. – Mads Hansen Jan 25 '16 at 18:22
26

You can also do this with ant contrib's if task.

<if>
    <equals arg1="${condition}" arg2="true"/>
    <then>
        <copy file="${some.dir}/file" todir="${another.dir}"/>
    </then>
    <elseif>
        <equals arg1="${condition}" arg2="false"/>
        <then>
            <copy file="${some.dir}/differentFile" todir="${another.dir}"/>
        </then>
    </elseif>
    <else>
        <echo message="Condition was neither true nor false"/>
    </else>
</if>
David
  • 2,602
  • 1
  • 18
  • 32
  • 8
    It should also be noted that _ant contrib_ is no longer maintained. The last version is from 2008! – Strinder Jun 14 '13 at 11:33
  • 1
    The last version 1.0b3 of ant-contrib which provides if/else, for, switch .. etc. is dated 2006-11-02 ! The cpptasks-1.0-beta5 is dated 2008-04-03. See http://sourceforge.net/projects/ant-contrib/files/ant-contrib/ – Rebse Jul 23 '14 at 07:52
  • 21
    Just because it's old doesn't mean it isn't any good or doesn't still work :) – David Jul 23 '14 at 18:48
16

The quirky syntax using conditions on the target (described by Mads) is the only supported way to perform conditional execution in core ANT.

ANT is not a programming language and when things get complicated I choose to embed a script within my build as follows:

<target name="prepare-copy" description="copy file based on condition">
    <groovy>
        if (properties["some.condition"] == "true") {
            ant.copy(file:"${properties["some.dir"]}/true", todir:".")
        }
    </groovy>
</target>

ANT supports several languages (See script task), my preference is Groovy because of its terse syntax and because it plays so well with the build.

Apologies, David I am not a fan of ant-contrib.

Arialdo Martini
  • 4,427
  • 3
  • 31
  • 42
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • 3
    Not sure how to get this to work - no groovy tag seems to be present. `failed to create task or type groovy`. – Joakim Tall Dec 05 '18 at 08:30
12

Since ant 1.9.1 you can use a if:set condition : https://ant.apache.org/manual/ifunless.html

Vincent Ricosti
  • 499
  • 5
  • 8
0
<project name="Build" basedir="." default="clean">
    <property name="default.build.type" value ="Release"/>

    <target name="clean">
    <echo>Value Buld is now  ${PARAM_BUILD_TYPE} is set</echo>
        <condition property="build.type" value="${PARAM_BUILD_TYPE}" else="${default.build.type}">
            <isset property="PARAM_BUILD_TYPE"/>
        </condition>

       <echo>Value Buld is now  ${PARAM_BUILD_TYPE} is set</echo>
       <echo>Value Buld is now  ${build.type} is set</echo>
    </target>
</project>

In my Case DPARAM_BUILD_TYPE=Debug if it is supplied than, I need to build for for Debug otherwise i need to go for building Release build. I write like above condition it worked and i have tested as below it is working fine for me.

And property ${build.type} we can pass this to other target or macrodef for processing which i am doing in my other ant macrodef.

D:\>ant -DPARAM_BUILD_TYPE=Debug
Buildfile: D:\build.xml
clean:
     [echo] Value Buld is now  Debug is set
     [echo] Value Buld is now  Debug is set
     [echo] Value Buld is now  Debug is set
main:
BUILD SUCCESSFUL
Total time: 0 seconds
D:\>ant
Buildfile: D:\build.xml
clean:
     [echo] Value Buld is now  ${PARAM_BUILD_TYPE} is set
     [echo] Value Buld is now  ${PARAM_BUILD_TYPE} is set
     [echo] Value Buld is now  Release is set
main:
BUILD SUCCESSFUL
Total time: 0 seconds

It work for me to implement condition so posted hope it will helpful.

Gautam
  • 3,707
  • 5
  • 36
  • 57