只要满足条件,就执行Ant任务

时间:2013-01-28 13:17:32

标签: ant

只有在满足条件时才需要在特定目标内执行Ant任务。

我找到了一种在目标级别定义条件的方法,但不是在任务级别。我还找到了一个实现IF task的贡献。

我的问题是,您是否了解使用标准Ant任务实现此目标的任何方法?

更长的解释:我正在尝试启动Tomcat Server以防它停止。要检测它是否已停止,我使用以下代码:

<echo message="Checking whether Tomcat is running"/>
<condition property="tomcat.running">
  <socket server="${tomcat.host}" port="${tomcat.port}"/> 
</condition>

所以我在这个目标中的下一个任务是一个exec任务,只有当${tomcat.running}为false时才应执行该任务。正如我所说,我不想在目标中添加单个任务来使用除属性。

4 个答案:

答案 0 :(得分:44)

Ant目标可以有一个可选的ifunless子句。这意味着仅在设置属性时使用if子句执行任务,或者使用unless子句 1 取消设置。有趣的是,在 首次执行任何相关任务后,{strong> 检查ifunless子句。

这意味着,只有满足特定条件时,才能在标准Ant中执行此操作,作为执行Ant任务的方法:

 <target name="test.if.tomcat.is.running">
      <condition property="tomcat.running">
          <socket server="${tomcat.host}" port="${tomcat.port}"/> 
      </condition>
</target>

<target name="my.target"
    if="tomcat.running"
    depends="test.if.tomcat.is.running">
    <yaddah/>
    <yaddah/>
    <yaddah/>
</target>

您指定希望Ant执行目标my.target。 Ant注意my.target取决于test.if.tomcat.is.running目标,并将首先执行该目标。如果Tomcat实际运行,test.if.tomcat.is.running任务将设置tomcat.running属性。否则,未设置该属性。

最后,Ant将返回到my.target目标并查看属性tomcat.running是否已设置,并且只有在设置后才会执行目标my.target

或者,您可以使用Ant-contrib任务,这可以使您的整个构建过程更容易理解。

如果您想要使用Ant-Contrib路线,可以轻松设置Ant-Contrib,因此Ant-contrib jar实际上是您项目的一部分。如果有人从版本控制系统中检出你的项目,他们也会获得Ant-contrib jar,因此不必自己安装Ant-Contrib。

下载Ant-Contrib jar,并将其放入项目根目录中名为antlib/ac的目录中。 antlib可用于各种可选任务jar,例如Findbugs或PMD。只需将每个可选的Ant jar放在antlib下的自己的目录中(就像我将Ant-Contrib放在ac目录下)。

然后,在build.xml中,以这种方式指定Ant-Contrib任务:

<taskdef resource="net/sf/antcontrib/antlib.xml">
   <classpath>
       <fileset dir="${basedir}/antlib/ac"/>
   </classpath>
</taskdef>

现在,您可以使用Ant-Contrib任务,而无需担心它们是否安装在特定计算机上。您可以签出项目,并且可以自动访问这些任务。


1。这是正确的,if/unless子句检查是否设置了属性而不是true / false,这可能会导致很多混乱。我见过开发人员将属性设置为falseno,然后想知道为什么目标实际上正在执行,因为if子句设置为false。

答案 1 :(得分:10)

由于版本1.9.1 (*)ant支持在任何任务上以更细粒度的方式 if-和除非条件 ,如果在项目元素中声明必要的名称空间。

(*)请使用最新版本的ant(撰写本文时为1.9.6),因为版本1.9.1包含了WRT这个新功能的缺陷,正如用户@Rebse所指出的那样。

在下面的示例中,您可以播放评论/取消注释属性......

<project name="test"
         xmlns:if="ant:if"
         xmlns:unless="ant:unless">

  <property name="is.good" value="hohoho"/>
  <!--property name="hide.base" value="boo"/-->

  <target name="foo">
     <echo unless:set="hide.base">${basedir}</echo>
     <echo if:set="is.good">GOOD</echo>
  </target>
</project>

...并观察如下输出:

Buildfile: D:\test\ant\taskcondition\build.xml
foo:
     [echo] D:\test\ant\taskcondition
     [echo] GOOD
BUILD SUCCESSFUL
Total time: 191 milliseconds

答案 2 :(得分:5)

如果您想要“if else”类型的实现:

<target name="test.if.tomcat.is.running">
      <condition property="tomcat.running" value="true" else="false">
          <socket server="${tomcat.host}" port="${tomcat.port}"/> 
      </condition>
</target>

<target name="my.target.running"
    if="${tomcat.running}"
    depends="test.if.tomcat.is.running">
...
</target>

<target name="my.target.ifnotrunning"
    unless="${tomcat.running}"
    depends="test.if.tomcat.is.running">
   .....
</target>

答案 3 :(得分:1)

在某些情况下,您无法使Ant目标依赖于另一个Ant目标,因为 if 应根据exec之前初始化的值进行评估(我可以提供一个明确的示例但是为简单起见,我不会。)

在Unix系统上,替代方案(在某些情况下更可取)如下:

<!-- the property that contains the value to be checked agains IF -->
<property name="myprop" value="true"/>

<!-- the Ant's exec combined with OS-IF command -->
<exec executable="bash">
        <arg value="-c" />
        <arg value="if [ &quot;${myprop}&quot; != &quot;$${myprop}&quot;] || [&quot;${tag_exists}&quot; != &quot;true&quot; ]; then my-bash-command _arguments_; fi" />
</exec>

在上面, my-bash-command 说明了你想要执行的命令/程序, 参数 说明了该参数。命令。

请注意,当未设置 myprop 时,$ {myprop}将简单地计算为字符串“$”+“{”+“myprop”+“}”(即“。” $ {myprop}“),因此我们必须将 myprop 的值与该字符串进行比较。

另一方面,当设置 myprop 时,其值可能是字符串 true / false 所以为了检查 IF 我们的条件如果符合,我们应该将 myprop 与字符串 true (或者您可能拥有的任何值)进行比较。

结论:使用Ant的 exec 结合OS命令 IF ,我们可以执行任意OS命令/程序,而无需其他Ant目标。使用与上面相同的逻辑, IF -like语句可以调整为甚至在Windows上工作。