Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果在两个文件中检测到错误,如何使Ant构建失败?_Ant - Fatal编程技术网

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

如果在两个文件中检测到错误,如何使Ant构建失败?,ant,Ant,我使用Ant进行数据库构建,基本上是使用exec任务来运行一些SQL脚本 但是,在脚本执行过程中可能会产生错误(例如,无法正确删除已连接的用户等),因此我通过查看两个输出日志文件来检查这一点 以下是相关目标的一个片段: <target name="build"> <echo message="Add foo bar baz"/> <exec executable="${db.sqlplus}"> </exec> &

我使用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>

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

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

返回到构建目标,因此当调用fail if error时,该属性将被取消设置

是这样吗


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

antcall将在其执行范围内设置属性,因此当您进行检查时,它不会被设置。相反,请尝试使用,这将在当前作用域中运行,并在该作用域中设置errors found属性,以便稍后的检查可以读取它。您可以这样定义宏定义:

<macrodef name="check-log-file">
  <attribute name="fileToCheck"/>

  <!--note attributes are referenced with an "@" rather than a "$" -->
  <property name="file.errorcount" value="@{fileToCheck}.errorcount"/>
  <copy file="@{fileToCheck}" tofile="${file.errorcount}">

  ...

</macrodef>
<check-log-file fileToCheck="${output.log.1}"/>
<check-log-file fileToCheck="${output.log.1}"/>

...
这样称呼它:

<macrodef name="check-log-file">
  <attribute name="fileToCheck"/>

  <!--note attributes are referenced with an "@" rather than a "$" -->
  <property name="file.errorcount" value="@{fileToCheck}.errorcount"/>
  <copy file="@{fileToCheck}" tofile="${file.errorcount}">

  ...

</macrodef>
<check-log-file fileToCheck="${output.log.1}"/>
<check-log-file fileToCheck="${output.log.1}"/>

感谢富有的卖家,他们提供了使用macrodef的想法。macrodef需要一些清理(macrodef中不允许使用属性,任务需要包装在顺序标记中),因此我在这里提供了完整的内容:

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

使用错误和警告检查常规日志文件

这是一个通用的宏定义,可用于扫描文件以查找问题。只要您可以为问题编写regexp,它就可以检查它

  • 如果发现问题,它可以失败,也可以不失败
  • 它总结了发现的问题,并将其写入Ant输出
  • 要扫描的文件可以用通配符表示
以下是检查Oracle错误日志文件的调用示例:

  • “SP2-”错误时失败
  • 警告“ORA-”错误
  • 警告“错误:”文本

    
    
以下是执行前检查生成的sql文件中是否存在未替换令牌的调用示例:

    <check_for_errors file.to.check.dir="${distdir}" file.to.check.include="**/\*.sql" 
        error.name="Token" error.pattern="^(?!--).+@[^@ ]+@" error.display.find=".*(@[^@ ]+@).*" error.display.show="  Token = '\1'"/>
    <check_for_errors file.to.check.dir="${distdir}" file.to.check.include="**/*.sql" 
        error.name="Token" error.pattern="^(?!--).+@\$\{[^ }]+\}" error.display.find=".*(\$\{[^ }]+\}).*" error.display.show="  Token = '\1'"/>

以下是宏定义:

<macrodef name="check_for_errors">
    <attribute name="file.to.check.dir" default="." />
    <attribute name="file.to.check.include" default="*.log" />
    <attribute name="file.to.check.exclude" default="" />
    <attribute name="error.pattern" default="ERROR" />
    <attribute name="error.name" default="ERROR" />
    <attribute name="error.action" default="fail" />
    <attribute name="error.display.find" default="(.+)" />
    <attribute name="error.display.show" default="  \1" />
    <sequential>
        <echo message="Excluding file ${buildlogfile}" level="debug" />
        <for param="file.to.check.name">
            <fileset dir="@{file.to.check.dir}">
                <include name="@{file.to.check.include}"/>
                <exclude name="@{file.to.check.exclude}"/>
                <exclude name="${buildlogfile}"/>
                <containsregexp expression="@{error.pattern}"/>
            </fileset>
            <sequential>
                <echo message="ERROR: @{error.name} found in file '@{file.to.check.name}' :" level="warn" />
                <concat>
                    <fileset file="@{file.to.check.name}" />
                    <filterchain>
                        <linecontainsregexp>
                            <regexp pattern="@{error.pattern}" />
                        </linecontainsregexp>
                        <replaceregex pattern="@{error.display.find}" replace="@{error.display.show}" />
                    </filterchain>
                </concat>
                <property name="error.check.foundvalues" value="true" />
            </sequential>
        </for>
        <condition property="error.check.fail">
            <and>
                <matches string="@{error.action}" pattern="fail" />
                <isset property="error.check.foundvalues" />
            </and>
        </condition>
        <fail message="ERROR: Fix the above errors and try again. Exiting..." if="error.check.fail"/>       
    </sequential>
</macrodef>