【问题标题】:How to check if a property has value in Ant如何检查属性在 Ant 中是否有价值
【发布时间】:2012-03-01 17:39:36
【问题描述】:

我有一个用于构建的 Ant XML 文件。

我有 3 个属性。如果这些属性不包含任何值,我想中断构建。如果值为空,我也想中断构建。

如何在 Ant 中做到这一点?

我使用 Ant 而不是 Ant-contrib。

【问题讨论】:

标签: ant


【解决方案1】:

从 Ant 1.9.1 开始,可以在所有的对象上添加 ifunless 属性 使用特殊命名空间的任务和嵌套元素。

要使用此功能,您需要添加以下命名空间声明

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

ifunless 命名空间支持以下条件:

  • true - 如果属性的值为真,则为真
  • blank - 如果属性的值为 null 或为空,则为 true
  • set - 如果设置了指定的属性,则为 true

示例:

<project name="tryit"
 xmlns:if="ant:if"
 xmlns:unless="ant:unless">
 <exec executable="java">
   <arg line="-X" if:true="${showextendedparams}"/>
   <arg line="-version" unless:true="${showextendedparams}"/>
 </exec>
 <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>

From Ant manual "If And Unless"

【讨论】:

    【解决方案2】:

    试试这个。

    <condition property="isPropertySet" value="true" else="false">
        <and>
            <isset property="my_property"/>
            <length string="${my_property}" trim="true" when="greater" length="0"/>
        </and>
    </condition>
    <fail unless="isPropertySet" message="The property my_property is not set."/>
    

    【讨论】:

      【解决方案3】:

      我使用的是旧版本的 Ant,因此无法使用 isset。相反,我在等号中使用了带有双 $ 的以下符号。

        <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】:

        您可以使用&lt;fail&gt; 任务来使用条件:

        <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>
        

        这相当于说 if (not set ${foo} or ${foo} = "") 是伪代码。您必须从内到外阅读 XML 条件。

        如果您只关心变量是否已设置,而不关心它是否具有实际值,则可以在 &lt;fail&gt; 任务中使用 &lt;unless&gt; 子句。

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

        但是,如果设置了属性但没有值,这不会失败。


        有一个技巧可以让这更简单

         <!-- 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>
        

        请记住,我无法重置属性!如果${foo} 已经有一个值,上面的&lt;property&gt; 任务不会做任何事情。这样,我可以消除&lt;isset&gt; 条件。这可能会很好,因为您有三个属性:

        <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>
        

        【讨论】:

        • 避免嵌套ifs很好。还可以设置条件属性和值。
        • 很好的答案!我注意到最后一个失败语句缺少正确的结束标记 --> 斜杠丢失了,我无法更正它,因为编辑需要更改至少 6 个字符:
        • @Zainodis 感谢您的关注。固定。
        【解决方案5】:

        在其他答案的基础上,这是我的首选形式,作为宏:

        <!-- 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>
        

        用作:

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

        为简洁起见,您可以使用 &lt;or&gt; 将两个失败元素合并为一个,但我更喜欢我的错误消息来对待我,就像我无法独立思考一样;)

        【讨论】:

          【解决方案6】:

          使用Ant addon Flaka,您可以使用以下模式:

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

          具体检查是否为空:

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

          一个完整的例子,也使用了一些带有 'eq' 的等号检查(相反的是 '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>
          

          使用 ant -f build.xml -Dbuildtype=prod

          输出 ant -f build.xml -Dbuildtype=prod -Ddummybuild=whatever

          [echo] ..starting ProductionBuild
          

          输出有错字 => ant - build.xml -Dbuildtype=testt

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

          使用 ant -f build.xml -Ddummybuild=whatever 输出

          [echo] .. is DummyBuild
          

          【讨论】:

            【解决方案7】:

            您可以尝试使用conditions... 或使用unless 创建目标

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-04-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多