if and unless in ant

19,851

Solution 1

You've got the logic right, but I'm not sure that the <exec> task accepts the if and unless attributes. See the docs for more info.

You will probably need to wrap the <exec> tasks in a target that checks the condition. For example:

<condition property="hasExtensions">
    <contains string="${Product_version}" substring="Extensions">
</condition>

<target name="ssremove" unless="hasExtensions">
    <exec executable="${TrueCM_App}\ssremove.exe">
        ...
    </exec>
</target>

Then if you run ant ssremove I think you will get what you want.

Solution 2

"exec" supports neither if, nor unless, so ChrisH's answer is correct. Typically you would also wrap the condition in a target and make that a dependency of the other target:

<target name="-should-ssremove">
  <condition ...
</target>

<target name="ssremove" depends="-should-ssremove" unless="hasExtensions">
  ...

Note the idiom of starting a target with a hyphen (-should-ssremove) to prohibit it's use from the command line. (You can't do 'ant -should-ssremove' because ant will treat it as an argument instead of a target - this is documented in the ant manual)

Another clever idiom to use in this case, also from the manual, is to take advantage of the old "is defined" meaning of if/unless and the new (since Ant 1.8) expansion and comparison with true/false.

This would give you:

<target name="-should-ssremove" unless="hasExtensions">
  <condition ...
</target>

<target name="ssremove" depends="-should-ssremove" unless="${hasExtensions}">
  ...

Note the distinction: the first target uses a plain old unless, the second target expands the variable hasExtensions (using the ${} which are not used in the first target) and only runs if it expands to true (which is the default value that 'available' will set on it, but you can set by adding a 'value' attribute to 'available')

The advantage of this idiom is that you can set the hasExtensions property externally, in a file that imports this one (say build.xml) or on the command line:

 ant -DhasExtensions=true ssremove

This works because the -should-ssremove target will not run if hasExtensions is already defined (which, pre-1.8 is the only logic supported by if/unless). Therefore your external definition trumps -should-ssremove. The ssremove target, on the other hand, will run only if the property hasExtensions evaluates to false. And it will always have been defined by the time it checks - thanks to the dependency on -should-ssremove.

Solution 3

Since Ant 1.9.1 it is possible to add if and unless attributes on all tasks and nested elements using special namespaces:

xmlns:if="ant:if"
xmlns:unless="ant:unless"

See If And Unless

<project name="tryit" xmlns:if="ant:if" xmlns:unless="ant:unless">
    <condition property="onmac">
        <os family="mac" />
     </condition>
     <echo if:set="onmac">running on MacOS</echo>
     <echo unless:set="onmac">not running on MacOS</echo>
</project>

It also supports if:true/unless:true and if:blank/unless:blank.

Solution 4

<condition property="myStatus" value="My test is OK" else="My test is KO">
    <available file="${filePath}/${fileName}.txt"/>
</condition>
<echo message="${myStatus}" />

Solution 5

There is also the if task in ant contrib. I personally think it is easier to read ant script that uses the the if task than those using conditional targets. The if task is frowned upon in the ant community though and you probably want to go with ChrisH´s solution if you don't plan on doing a lot of conditional stuff.

Share:
19,851

Related videos on Youtube

jeremychan
Author by

jeremychan

Updated on June 04, 2022

Comments

  • jeremychan
    jeremychan almost 2 years

    I would like to clarify the if and unless statements in ANT script

    I have the following code:

    <condition property="hasExtensions">
        <contains string="${Product_version}" substring="Extensions">
    </condition>
    
    <exec executable="${TrueCM_App}\ssremove.exe" unless="hasExtensions">
        ...
    </exec>
    

    Does that mean the above <exec> would execute ssremove.exe if Product_version does not contain the string "Extensions"?

    Then how about the opposite case: if it contains the string "Extensions"? Will my code look like this:

    <condition property="hasExtensions">
        <contains string="${Product_version}" substring="Extensions">
    </condition>
    <!-- here below it does not have the string "Extensions" -->
    <exec executable="${TrueCM_App}\ssremove.exe" unless="hasExtensions">
        ...
    </exec>
    
    <!-- below is for if it has the string "Extensions" -->
    <exec executable="${TrueCM_App}\ssremove.exe" if="hasExtensions">
        ...
    </exec>
    

Related