如果在ant任务中的条件产生错误

时间:2013-08-21 09:55:04

标签: ant build.xml ant-contrib

我有一个场景,我需要将目录从一个位置移动到另一个位置。如果目标文件夹中存在相同的目录,则需要将目录名重命名为oldname_1。 所以我写了一个片段如下:

<target name="Move">
    <IF>
        <available file="${output.dir}" type="dir" />
        <then>
            <echo message="Directory exists" />
            <rename src="${output.dir}" dest="${output.dir}_1"/>
            <property name="newdirectory" value="${dest}"/>
        </then>
    <ELSE>
        <echo message="Directory does not exist" />
    </ELSE>
    </IF>
        <move file="${newdirectory}" todir="C:\reports" />
    </target>

我得到的错误是:

Problem: failed to create task
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any / declarations have taken place.

2 个答案:

答案 0 :(得分:2)

正如Ian Roberts已经提到过,你需要Ant-Contrib jar,然后设置<taskdef/>指向这个jar。我强烈建议将其放入项目中并将其检入您的版本控制系统。这样,当有人签出您的项目时,他们已经安装了Ant-Contib.jar

我的标准是将构建所需的所有可选jar(不是编译所需的jar)放在目录${basedir}/antlib中,然后将每个可选jar放在它自己的目录中,所以我会放ant-contrib-1.0b3.jar进入${basedir}/antlib/antcontrib

然后我用这种方式定义任务:

<property name="antlib.dir"      value="${basedir}/antlib"/>

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

这样,如果您将jar文件更新为新版本的Ant-Contrib jar,只需将其插入目录即可。您无需更新build.xml

另请注意,我使用net/sf/antcontrib/antlib.xml而非net/sf/antcontrib/antcontrib.properties XML 文件是您使用的文件。这方面的说明在tasks page上,与安装说明下main page上的说明不同。原因是XML文件具有<for>任务的正确定义,属性文件没有。


但是,还有另一种方法可以在Ant 1.9.1中执行ifunless,而无需可选的jar文件。这些是新的If and Unless entity attributes

这些可以放在所有任务或子实体中,通常可以替换Ant-Contrib if/else内容:

<target name="move">
    <available file="${output.dir}" type="dir"
        property="output.dir.exists"/>
    <echo message"Directory exists"
        if:true="output.dir.exists"/>
    <move file="${output.dir}" tofile="${output.dir}_1"
        if:true="output.dir.exists"/>
    <property name="newdirectory" value="${dest}"
        if:true="output.dir.exists"/>
    <echo message="Directory does not exists"
        unless:true="output.dir.exists"/>
    <move file="${newdirectory}" todir="C:\reports" />
</target>

不如你的例子那么干净。但是,我会在目标名称上使用if=unless=参数:

<target name="move.test">
    <available file="${output.dir}" type="dir"
        property="output.dir.exists"/>
</target>

<target name="move"
    depends="move.test, move.exists, move.does.not exists">
    <move file="${newdirectory}" todir="C:\reports" />
</target>

<target name="move.exists"
    if="output.dir.exists">
    <echo message="Directory exists" />
    <move file="${output.dir}" tofile="${output.dir}_1"/>
    <property name="newdirectory" value="${dest}"/>
</move.exists/>

<target name="move.does.not.exists"
    unless="output.dir.exists"/>
    <echo message="Directory does not exist" />
</target>

如果你没有回应所有东西,那么结构会更清晰:

<target name="move.test">
    <available file="${output.dir}" type="dir"
        property="output.dir.exists"/>
</target>

<target name="move"
    depends="move.test, backup">
    <move file="${newdirectory}" todir="C:\reports" />
</target>

<target name="backup"
    if="output.dir.exists">
    <move file="${output.dir}" tofile="${output.dir}_1"/>
    <property name="newdirectory" value="${dest}"/>
</move.exists/>

答案 1 :(得分:0)

if / else构造不是开箱即用的Ant的本机部分,它由ant-contrib项目提供,您需要下载JAR并将相关的<taskdef>添加到您的构建文件。例如,如果您下载ant-contrib-1.0b3.jar并将其放在与build.xml相同的目录中名为build的目录中,那么您可以说

<taskdef resource="net/sf/antcontrib/antcontrib.properties">
  <classpath>
    <pathelement location="build/ant-contrib-1.0b3.jar"/>
  </classpath>
</taskdef>