Chapter 5. If Task

Table of Contents

If
More Conditions

If

The If task provides a greatly improved "if" capability to Ant projects. This task works in a manner very similar to the Java if keyword. This is useful for performing certain tasks only if a property has a specific value or certain conditions are met.

This task can hold other tasks including the If task. In particular, it can also have a single "else", which gives Ant a Java-like if/else construct, and a single "bool", which can be used for the "if" boolean expression.

To use this task in your build files, include a task definition like this:


    <taskdef name="if" classname="ise.antelope.tasks.IfTask"/>
   

An If task may contain only one 'bool' and one 'else' and may contain a 'break'. The 'bool' element is identical to the ConditionTask, but unlike the ConditionTask, is actually a Task. The 'bool' element can contain all the conditions permitted by the ConditionTask, plus the IsPropertyTrue, IsPropertyFalse, StartsWith, EndsWith, IsGreaterThan, IsLessThan and conditions.

Here is a general outline of the If task:


<if>
    <bool>
        <some condition(s)/>
    </bool>

    some tasks...

    <!-- a break is allowed
    <break/>
    -->

    <else>
        some other tasks...

        <!-- a break is allowed
        <break/>
        -->
    </else>
</if>

Table 5.1. If Task Attributes

AttributeDescriptionDefaultRequired
nameThe name of the property to test for.noneYes, unless nested bool is used.
existsTest for existence or non-existence of the property.TrueNo
valueThe value to test for, implies 'exists=true'. If the value for the property in the project is the same as this value, embedded tasks will be executed.noneNo

The If task can hold any number of Ant tasks. If the property value is correct or the "bool" element evaluates to true, these tasks will be executed.

In addition, the If task supports three special nested elements:

  • bool This is very similar to the standard Ant Condition task. All conditions supported by the Condition task are supported by the bool element. This is an optional element and if used, is used to decide if the "if" tasks or the "else" tasks should be executed. If the bool element is not used, then the "name" attribute must be used.

  • else This is very similar to the standard Ant Sequential task. The "else" can hold any number of Ant tasks. These tasks are executed if the "bool" element evaluates to false.

  • break This is very similar to the Java "break" keyword. This is only useful if the If task is nested in another task that understands "break", such as the Switch task. Like the Java "break", when this element is encountered, no subsequent tasks will be executed and control passes outside the If.

In the following example, the antcall task will execute only if the project has a property named test with a value of true.

   
   <if name="test" value="true">
      <antcall target="doUnitTests"/>
   </if>
   

In the next example, the antcall task will execute only if the project has a property named test. In this example, it does not matter what value is assigned to the test property.

    
   <if name="test">
      <antcall target="doUnitTests"/>
   </if>
   

Of course, the same thing could have been done as follows, but the "if" is generally much cleaner.

   
   <antcall target="doUnitTests"/>
   <target name="doUnitTests" if="test">
      ...
   </target>
   

In the next example, the antcall task will execute only if the project does not have a property named test. This is the opposite situation of the previous example.

   
   <if name="test" exists="false">
      <antcall target="doUnitTests"/>
   </if>
   

The next example demonstrates nested 'if' tasks. This example will run the unit tests, and if it is Monday, will publish the accumulated test results.

    
   <tstamp>
      <format property="day" pattern="E" />
   </tstamp>
   <if name="test" value="true">
      <antcall target="doUnitTests"/>
      <if name="day" value="Mon">
         <antcall target="publishTestResults"/>
      </if>
   </if>
   

The next example shows how to use If with Else. Notice that it doesn't matter where the Else is placed inside the If. All tasks in the If that are not in the Else will execute if the property value is correct, otherwise, only those tasks inside the else will execute. The "var" task is discussed here.

    
    <var name="foo" value="bar"/>
    <if name="foo" value="bar">
        <echo>this will happen</echo>
        <else>
            <echo>this won't happen</echo>
        </else>
        <echo>this will happen also</echo>
    </if>

    <if name="foo" value="snarf">
        <echo>this won't happen</echo>
        <else>
            <echo>this 'else' will happen</echo>
            <echo>and so will this</echo>
        </else>
        <echo>this won't happen either</echo>
    </if>
    

The next example shows the "if" and "assert" tasks working together to validate a property before use, and also shows an example of where the "assert" 'failonerror' attribute might be useful. In this example, if the e-mail address is invalid, the e-mail won't be sent and the build won't fail. The "try" task is discussed here.

    
   <if name="email_from" value="buildteam@mycompany.com">
      <property name="valid_email" value="true"/>
   </if>
   <if name="email_from" value="buildsite@mycompany.com">
      <property name="valid_email" value="true"/>
   </if>
   <assert name="valid_email" value="true" failonerror="false">
      <try>
          <mail from="${email_from}" tolist="${email_to}"
              message="New release available"/>
      </try>
   </assert>
   

Here is the same thing, but using only If and Else:

    
   <try>
       <if name="email_from" value="buildteam@mycompany.com">
          <mail from="${email_from}" tolist="${email_to}"
              message="New release available"/>
          <else>
             <if name="email_from" value="buildsite@mycompany.com">
                 <mail from="${email_from}" tolist="${email_to}"
                      message="New release available"/>
             </if>
          </else>
       </if>
   </try>
   

The next example shows how to use the "bool" element:

    
    <if>
        <!-- "if" evaluates this element -->
        <bool>
            <and>
                <available file="build.xml"/>
                <available file="run.xml"/>
            </and>
        </bool>

        <!-- if true, then tasks listed here will execute -->
        <echo>build.xml and run.xml are available</echo>

        <!-- if false, then tasks inside the "else" will execute -->
        <else>
            <echo>didn't find one or both of build.xml and run.xml</echo>
        </else>
    </if>
    

The following example shows the "bool" element again:

    
    <if>
        <bool>
            <equals arg1="${download.dir}" arg2="test.dir"/>
        </bool>

        <fail message="Download and test directories cannot be
            the same! You need to reset to use the production
            property set."/>

        <else>
            <copy file="installer.zip" todir="${download.dir}"/>
        </else>
    </if>
    

The following example is from the unit test for the "Limit" task. It shows the Stopwatch task, the Limit task, and the If task with boolean conditions:

    
  <target name="test2">
    <!-- should not stop 'sleep' task, should print out '_passed_' -->
    <stopwatch name="timer"/>
    <limit maxwait="5">
        <sleep seconds="1"/>
        <echo>_passed_</echo>
    </limit>
    <stopwatch name="timer" action="total"/>
    <if>
        <bool>
            <isgreaterthan arg1="${timer}" arg2="2"/>
        </bool>
        <fail message="Too much time"/>
    </if>
  </target>