9

foreach我有以下 ant 脚本,当 antcontrib 的任务的并行设置为 true 时,我似乎找不到失败的方法。有任何想法吗?

<project name="asdf" >
    <taskdef resource="net/sf/antcontrib/antcontrib.properties">
        <classpath>
            <pathelement location="../lib/ant/ant-contrib-1.0b3.jar" />
        </classpath>
    </taskdef>
    <target name="build">
        <foreach target="exex-subant" param="foreach.dir" parallel="true" maxthreads="4" inheritall="true" list="1,2,3">
            <param name="target" value="build" />
        </foreach>
    </target>

    <target name="exex-subant">
        <fail>test</fail>
    </target>
</project>
4

1 回答 1

9

发生这种情况是因为当并行执行时,<foreach>使用<parallel>任务,但没有设置“failonany”属性,或者给出任何方式说如果任何迭代失败,任务应该失败。

幸运的是,有一个相对简单的解决方法,就是<for>使用<foreach>. 在您的示例中,它看起来像这样:

<target name="build">
    <for param="foreach.dir" parallel="true" list="1,2,3">
        <sequential>
            <antcall target="exex-subant" inheritall="true">
                <param name="target" value="build" />
                <param name="foreach.dir" value="@{foreach.dir}" />
            </antcall>
        </sequential>
    </for>
</target>

请注意,您必须显式传入 foreach.dir 属性,然后可以在 exex-subant 目标中以${foreach.dir}.

这将并行执行所有迭代,但如果其中任何一个失败,脚本将失败(它不会执行 for 任务之外的任何内容)。

请注意,为了使用该for任务,您需要 ant 1.6 或更高版本,并且需要将您的 taskdef 更改为:

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

如果出于某种原因您需要支持旧版本的 ant,那么您将不得不稍微更改 exex-subant 目标,以便在失败时更改某些内容。例如,您可以将 exex-subant 中的当前逻辑包装在 try/catch 中,并在 catch 块中创建一个文件。然后在 foreach 终止后,您可以检查该文件是否存在,如果存在则使构建失败。这样,如果 foreach 的任何执行失败,则 ant 脚本将在 foreach 完成后失败。

请注意,您不能只在失败时在 exex-subant 中设置属性,因为该属性不会传播回 foreach 循环(这就是我建议创建文件的原因)。但我强烈建议只使用该for任务并要求 ant 1.6 或更高版本。

于 2011-06-23T22:52:50.663 回答