如何在Ant中检查属性是否有值

37

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

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

如何在Ant中实现这一点?

我使用的是Ant而不是Ant-contrib。


可能是[ant过滤器-如果未设置属性则失败]的重复问题。(https://dev59.com/XXVC5IYBdhLWcg3wpS3f) - oers
7个回答

65
您可以使用<fail>任务来设置条件:
<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>

这相当于说如果 ${foo}未设置或等于"" 是伪代码。你必须从内向外阅读XML条件。

如果你只关心变量是否设置,而不是它是否有实际值,你可以在<fail>任务上使用<unless>子句。

<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}已经有一个值,上面的<property>任务将不会执行任何操作。这样,我可以消除<isset>条件。这可能很好,因为您有三个属性:
<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>

避免嵌套的if语句是很好的。此外,可以使用条件属性和值进行设置。 - user1587504
很棒的回答!我注意到最后一个失败语句缺少适当的闭合标签-->斜杠丢失了,而且我无法更正它,因为编辑需要至少更改6个字符 :< - AgentKnopf
1
@Zainodis 谢谢您的注意。已修复。 - David W.

13

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

<!-- 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" />
    <!-- ... -->

为了简洁起见,您可以使用<or>将两个失败元素合并为一个,但我更喜欢我的错误信息像对待我不会思考一样 ;)


0
使用Ant插件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

0
你可以尝试使用条件...或者创建一个带有除非的目标。

0

试试这个。

<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."/>

0

我使用的是较旧版本的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>

0

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

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

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

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

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

示例:

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

从Ant手册“如果和除非”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接