13
votes

I am using ant, and I have a problem with if/then/else task, (ant-contrib-1.0b3.jar). I am running something that can be simplified with build.xml below.

I am expecting to obtain from 'ant -Dgiv=Luke' the message

input name: Luke
should be overwritten with John except for Mark: John

but it seems property "giv" is not overwritten inside if/then/else..

input name: Luke
should be overwritten with John except for Mark: Luke

Is it depending from the fact I am using equals task with ${giv} ? Otherwise what is wrong in my code?

build.xml CODE:

<project name="Friend" default="ifthen" basedir=".">

<property name="runningLocation" location="" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
    <classpath>
        <pathelement location="${runningLocation}/antlib/ant-contrib-1.0b3.jar" />
    </classpath>
</taskdef>

<target name="ifthen">
<echo message="input name: ${giv}" />
<if>
    <equals arg1="${giv}" arg2="Mark" />
    <then>
    </then>
    <else>
        <property name="giv" value="John" />
    </else>
</if>
<echo message="should be overwritten with John except for Mark: ${giv}" />
</target>
</project>
5

5 Answers

16
votes

Ant Properties are very hard to overwrite (if not impossible). What you need is a Variable. These are also defined in the Ant Contrib JAR.

Editing your example:

  <target name="ifthen"> 
    <var name="Evangelist" value="${giv}" />
    <echo message="input name: ${Evangelist}" />
    <if>
      <equals arg1="${Evangelist}" arg2="Mark" />
      <then>
      </then>
      <else>
        <var name="Evangelist" value="John" />
      </else>
    </if>   
    <echo message="should be overwritten with John except for Mark: ${Evangelist}" />
 </target>
34
votes

In Ant a property is always set once, after that variable is not alterable anymore.

Here follows a solution using standard Ant (without ant-contrib) which could be useful for the people who does not want an extra dependency.

<target name="test"  >
    <echo message="input name: ${param}" />

    <condition property="cond" >
        <equals arg1="${param}" arg2="Mark" />
    </condition>
</target>

<target name="init" depends="test" if="cond"> 
    <property name="param2" value="Mark" />
</target>

<target name="finalize" depends="init"> 
    <property name="param2" value="John" />
    <echo message="should be overwritten with John except for Mark: ${param2}" />
</target>
2
votes
<project name="Friend" default="ifthen" basedir=".">

<property name="runningLocation" location="" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
    <classpath>
        <pathelement location="${runningLocation}/antlib/ant-contrib-1.0b3.jar" />
    </classpath>
</taskdef>

<target name="ifthen">
<echo message="input name: ${giv}" />
<if>
    <equals arg1="${giv}" arg2="Mark" />
    <then>
    </then>
    <else>
        <var name="giv" unset="true"/>
        <property name="giv" value="John" />
    </else>
</if>
<echo message="should be overwritten with John except for Mark: ${giv}" />
</target>
</project>

We can use var task to unset the property also.

2
votes

I know this is old, but should prove handy to others searching for a solution.

to re-assign a property without using ant-contrib, use macrodef with a script.

<macrodef name="property-change"> 
    <attribute name="name"/>
    <attribute name="value"/>
    <sequential> 
        <script language="javascript"><![CDATA[
            project.setProperty("@{name}", "@{value}");
        ]]></script>
    </sequential> 
</macrodef>  

then in anywhere in ant, just call this like the property tag

<property-change name="giv" value="John"/>

to Implement this in your original version of xml, it would look like this:

<project name="Friend" default="ifthen" basedir=".">

<property name="runningLocation" location="" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
    <classpath>
        <pathelement location="${runningLocation}/antlib/ant-contrib-1.0b3.jar" />
    </classpath>
</taskdef>

<target name="ifthen">
<echo message="input name: ${giv}" />
<if>
    <equals arg1="${giv}" arg2="Mark" />
    <then>
    </then>
    <else>
        <property-change name="giv" value="John" />
    </else>
</if>
<echo message="should be overwritten with John except for Mark: ${giv}" />
</target>
</project>

This sample is given purely as an example on writing a macro to replace the <var> command in ant-contrib. In a situation like this one, where the <if> command is being used, it makes more sense to use <var> sinnce ant-contrib is already loaded, and <var> might be faster in processing.

Hope this helps.

-1
votes

It is possible to re-assign the value of a property using the ant-contrib 'propertycopy'. This is an alternative to using ant-contrib Variables. This way the property "giv" can be overwritten.

<target name="ifthen">
  <echo message="input name: ${giv}" />
  <if>
    <equals arg1="${giv}" arg2="Mark" />
    <then>
    </then>
    <else>
      <property name="tempName" value="John" />
      <propertycopy name="giv" from="tempName" override="true" />
    </else>
  </if>
  <echo message="should be overwritten with John except for Mark: ${giv}" />
</target>

Be aware this assumes the property tempName is not already set to a value other than 'John'.