我有一个ant
任务,它对文件列表执行一些命令。在连续的构建中,我希望避免在成功传递命令且没有更改的文件上重新运行命令。
例如:(此处的命令为xmllint
)
<target name="xmllint-files">
<apply executable="xmllint">
<srcfile/>
<fileset dir="." includes="*.xml">
<modified/>
</fileset>
</apply>
</target>
问题是,即使xmlint
失败的文件也被视为已修改,因此xmllint
将不会在连续的构建中重新运行。显然,这不是所期望的行为。
两点:
- 我正在寻找一个通用的解决方案,而不仅仅是
xmllint
的解决方案 - 我想完全在
ant
内部解决问题,而不创建外部脚本
此代码使用GroovyANT任务执行以下操作:
- 实现一个自定义groovy选择器,根据MD5校验和检查来选择要处理的XML文件
- 在每个文件上调用xmllint,并在成功完成时存储其校验和(除非文件的内容发生更改,否则这将防止重新执行xmllint
示例:
<project name="demo" default="xmllint">
<!--
======================
Groovy task dependency
======================
-->
<path id="build.path">
<pathelement location="jars/groovy-all-1.8.6.jar"/>
</path>
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
<!--
==============================================
Select files to be processed
MD5 checksums located in "checksums" directory
==============================================
-->
<target name="select-files">
<fileset id="unprocessedfiles" dir=".">
<include name="*.xml"/>
<exclude name="build.xml"/>
<scriptselector language="groovy" classpathref="build.path">
def ant = new AntBuilder()
ant.checksum(file:filename, toDir:"checksums", verifyProperty:"isMD5ok")
self.selected = (ant.project.properties.isMD5ok == "false") ? true : false
</scriptselector>
</fileset>
</target>
<!--
=============================================================
Process each file
Checksum is saved upon command success, prevents reprocessing
=============================================================
-->
<target name="xmllint" depends="select-files">
<groovy>
project.references.unprocessedfiles.each { file ->
ant.exec(executable:"xmllint", resultproperty:"cmdExit") {
arg(value:file)
}
if (properties.cmdExit == "0") {
ant.checksum(file:file.toString(), toDir:"checksums")
}
}
</groovy>
</target>
</project>
注意:
- 这个复杂的需求不能使用原来的applyANT任务来实现。对xmllint命令的一次调用可能成功,而另一次调用则可能失败
- 创建了一个名为"checksums"的子目录来存储MD5校验和文件
- groovy jar可以从Maven Central下载
原始答案
使用ANT修改的选择器
<project name="demo" default="xmllint">
<target name="xmllint">
<apply executable="xmllint">
<srcfile/>
<fileset dir="." includes="*.xml">
<modified/>
</fileset>
</apply>
</target>
</project>
将在生成目录中创建一个名为"cache.properties"的属性文件。它记录文件摘要,用于确定自上次构建运行以来文件是否已更改。