How to check if a property has value in Ant

2020-02-26 14:07发布

I have an Ant XML file which I use for build.

I have 3 properties. I want to break the build if these properties does not contain any value. Also I want to break the build if the value is empty.

How can I do this in Ant?

I a using Ant and not Ant-contrib.

标签: ant
5条回答
Lonely孤独者°
2楼-- · 2020-02-26 14:37

You can use conditions using the <fail> task:

<fail message="Property &quot;foo&quot; needs to be set to a value">
    <condition>
        <or>
            <equals arg1="${foo}" arg2=""/>
            <not>
                <isset property="foo"/>
            </not>
       </or>
   </condition>

This is equivalent to saying if (not set ${foo} or ${foo} = "") is pseudocode. You have to read the XML conditions from the inside out.

You could have used the <unless> clause on the <fail> task if you only cared whether or not the variable was set, and not whether it has an actual value.

<fail message="Property &quot;foo&quot; needs to be set"
    unless="foo"/>

However, this won't fail if the property is set, but has no value.


There's a trick that can make this simpler

 <!-- Won't change the value of `${foo}` if it's already defined -->
 <property name="foo" value=""/>
 <fail message="Property &quot;foo&quot; has no value">
     <condition>
             <equals arg1="${foo}" arg2=""/>
     </condition>
</fail>

Remember that I can't reset a property! If ${foo} already has a value, the <property> task above won't do anything. This way, I can eliminate the <isset> condition. It might be nice since you have three properties:

<property name="foo" value=""/>
<property name="bar" value=""/>
<property name="fubar" value=""/>
<fail message="You broke the build, you dufus">
    <condition>
        <or>
            <equals arg1="${foo}" arg2=""/>
            <equals arg1="${bar}" arg2=""/>
            <equals arg1="${fubar}" arg2=""/>
       </or>
    </condition>
</fail>
查看更多
放我归山
3楼-- · 2020-02-26 14:43

I'm on an older version of Ant, so isset wasn't available. Instead I used the following notation with the double $ in the equals.

  <target name="xxx">
        <echo message="${contextRoot}" />
        <if>
            <!-- check if the contextRoot property is defined. -->
            <equals arg1="${contextRoot}" arg2="$${contextRoot}" />
            <then>
                <!-- it isn't set, set a default -->
                <property name="contextRoot" value="/WebAppCtx" />
            </then>
        </if>
        <echo message="${contextRoot}" />
    </target>
查看更多
混吃等死
4楼-- · 2020-02-26 14:45

With Ant addon Flaka you may use patterns like :

 <property name="foo" value="bar"/>
...
   <fl:unless test="has.property.foo">
    ...
   </fl:unless>
...
   <fl:when test="has.property.foo">
    ...
   </fl:when>

Concrete check for emptyness :

 <fl:when test=" empty '${foo}' ">
  <fail message="Houston we have a problem!!"/>
 </fl:when>

A complete example, also using some equals check with 'eq' (opposite would be 'neq'):

<project xmlns:fl="antlib:it.haefelinger.flaka">
  <!-- some if/then/else construct -->
  <fl:choose>
    <!-- if -->
    <when test=" '${buildtype}' eq 'prod' ">
      <!-- then -->
      <echo>..starting ProductionBuild</echo>
    </when>
    <when test=" '${buildtype}' eq 'test' ">
      <!-- then -->
      <echo>..starting TestBuild</echo>
    </when>
    <!-- else -->
    <otherwise>
      <fl:unless test="has.property.dummybuild">
        <fail message="No valid buildtype !, found => '${buildtype}'"/>
      </fl:unless>
      <echo>.. is DummyBuild</echo>
    </otherwise>
  </fl:choose>
</project>

output with ant -f build.xml -Dbuildtype=prod
or
ant -f build.xml -Dbuildtype=prod -Ddummybuild=whatever

[echo] ..starting ProductionBuild

output with typo => ant - build.xml -Dbuildtype=testt

BUILD FAILED
/home/rosebud/workspace/AntTest/build.xml:21: No valid buildtype !, found => 'testt'

output with ant -f build.xml -Ddummybuild=whatever

[echo] .. is DummyBuild
查看更多
Melony?
5楼-- · 2020-02-26 14:50

You could try using conditions... or creating a target with unless

查看更多
一夜七次
6楼-- · 2020-02-26 14:56

Building on the other answers, this is my preferred form, as a Macro:

<!-- Macro to require a property is not blank -->
<macrodef name="prop-require">
    <attribute name="prop"/>
    <sequential>
        <fail message="Property &quot;@{prop}&quot; must be set">
            <condition>
                <not>
                    <isset property="@{prop}"/>
                </not>
           </condition>
        </fail>

        <fail message="Property &quot;@{prop}&quot; must not be empty">
            <condition>
                <equals arg1="${@{prop}}" arg2=""/>
           </condition>
        </fail>
    </sequential>
</macrodef>

To Be used as:

<target name="deploy.war" description="Do the war deployment ;)">
    <prop-require prop="target.vm" />
    <prop-require prop="target.vip" />
    <!-- ... -->

For brevity you can collapse the two fail elements into one by using an <or>, but I prefer my error messages to treat me like I cannot think for myself ;)

查看更多
登录 后发表回答