如果在两个文件中检测到错误,如何使Ant构建失败?

wei*_*iji 6 ant

我使用Ant基本上使用exec任务来运行一些SQL脚本来进行数据库构建.

但是,在脚本执行期间可能会出现错误(例如,无法正确删除已连接的用户等),因此我通过查看两个输出日志文件来检查这一点.

以下是相关目标的片段:

<target name="build">
    <echo message="Add foo bar baz"/>
    <exec executable="${db.sqlplus}">
    </exec>

    <echo message="Load x y z"/>
    <exec executable="${db.sqlplus}" dir="foobar">
    </exec>

    <!--Check the log files here-->
    <antcall target="check-log-file">
        <param name="file.to.check" value="${output.log.1}"/>
    </antcall>

    <antcall target="check-log-file">
        <param name="file.to.check" value="${output.log.2}"/>
    </antcall>

    <antcall target="fail-if-error"/>
</target>

<!--=============================================================================
    Check the file named in the property file.to.check to see if there are errors.

    The way this works is to find all lines containing the text "ERROR" and put
    them into a separate file.  Then it checks to see if this file has non-zero
    length. If so, then there are errors, and it sets the property errors.found.
    Then it calls the send-email target, which doesn't execute if the 
    errors.found property isn't set.
-->
<target name="check-log-file" 
        description="Checks the file (specified in ${file.to.check}) for errors">
    <property name="file.errorcount" value="${file.to.check}.errorcount" 
              description="The file to hold the error lines"/>
    <copy file="${file.to.check}" tofile="${file.errorcount}">
        <filterchain>
            <linecontains>
                <contains value="ERROR"/>
            </linecontains>
        </filterchain>
    </copy>

    <condition property="errors.found" value="true">
        <length file="${file.errorcount}" when="gt" length="0"/>
    </condition>

    <antcall target="check-log-file-send-email"/>
</target>

<!--=========================================================================
    If there are any errors, send an email to let someone know
-->
<target name="check-log-file-send-email" if="errors.found" 
        description="Sends an email out if error detected">
    <resourcecount property="error.count">
        <tokens><!-- default tokenizer is a line tokenizer -->
            <file file="${file.to.check}.errorcount"/>
        </tokens>
    </resourcecount>

    <echo
     message="Database build (${e1.codeline} - ${error.count} errors found..."/>

    <antcall target="mail">
      <param name="from-address" value="build"/>
      <param name="to-list" value="myemail"/>
      <param name="subject" 
            value="Automated database build error report for ${db.host}"/>
      <param name="message" 
            value="See attached log file, ${error.count} error(s)found..."/>
      <param name="attach"  value="${file.to.check}"/>
    </antcall>
</target>

<!--==========================================================================
    Fails the database build if errors were detected.
-->
<target name="fail-if-error" if="errors.found">
 <echo message="Errors found - setting database fail flag..."/>
 <fail message="Errors detected during ${codeline} database build.  Check logs."/>
</target>
Run Code Online (Sandbox Code Playgroud)

当出现错误时,构建不会失败.

我认为这是因为检查日志的antcall任务不会返回属性错误.

找回构建目标,因此当调用fail-if-error时,将取消该属性.

是对的吗?

有没有办法将其设置为正确失败?

wei*_*iji 3

感谢 Rich Seller,他提供了使用宏定义的想法。宏定义需要进行一些清理(宏定义内不允许使用属性,任务需要包装在顺序标记中),因此我在这里完整提供它:

<macrodef name="check-log-file">
    <attribute name="file.to.check"/>
    <attribute name="file.errorcount" default="@{file.to.check}.errorcount" description="The file to hold the error lines"/>

    <sequential>
        <copy file="@{file.to.check}" tofile="@{file.errorcount}">
            <filterchain>
                <linecontains>
                    <contains value="ERROR"/>
                </linecontains>
            </filterchain>
        </copy>

        <condition property="errors.found" value="true">
            <length file="@{file.errorcount}" when="gt" length="0"/>
        </condition>

        <antcall target="check-log-file-send-email">
            <param name="file.to.check"   value="@{file.to.check}"/>
        </antcall>
    </sequential>
</macrodef>
Run Code Online (Sandbox Code Playgroud)