ant在文件被删除时重建



我正在使用Ant构建项目,并希望在源代码发生更改时进行重新编译。这主要与标准javac任务一起自动工作,除了一种情况:

当删除源文件但没有进行其他更改时,不会重新编译任何内容

即使这会使项目无法干净无错误地编译,但由于遗留的类文件,构建仍然会成功。

每次都进行干净的构建不是一种选择,因为我们有137个依赖模块需要很长时间才能构建。此外,我们不希望在完全清理后重试每一个失败的CI构建,看看它是否能正常工作。

这似乎是javac任务应该支持的一个非常基本的东西,但我没有看到任何看起来有用的属性。在尝试了我能想到的任何其他东西后,我都做不好:

找出是否有任何遗留类:

<difference id="targets.todelete">
  <union>
    <mappedresources>
      <fileset dir="${src.java.dir}" includes="**/*.java" />
      <globmapper from="*.java" to="*.class" />
    </mappedresources>
  </union>
  <union>
    <fileset dir="${build.java.dir}" includes="**/*.class" />
  </union>
</difference>

以上这些都不起作用,差异实际上似乎更像是一个联盟。如果一个java文件有一个相应的类文件,那么该类文件将有两个条目存在差异。

这是另一次尝试:

<fileset id="del" dir="${src.java.dir}" includes="**/*.java" casesensitive="false" defaultexcludes="false">
  <different targetdir="${build.java.dir}" ignoreFileTimes="true">
    <globmapper from="*.java" to="*.class" />
  </different>
</fileset>

我试图找到所有不同的文件,但结果或多或少与上面相同。

当我尝试在没有映射器的情况下,在和中使用部分重叠的源文件集时,它确实按预期工作。这让我怀疑,任何与资源差异有关的东西都不能很好地处理映射文件。

这里有人知道如何以其他方式实现我的目标吗?

更新:这是正确处理内部类的有效解决方案。我需要多个源目录,这会使事情更加复杂。

<!-- find class files with without corresponding source files -->
<fileset id="src1" dir="${src.java.dir}" includes="**/*.java" />
<fileset id="src2" dir="${build.generated.java.dir}" includes="**/*.java" erroronmissingdir="no" />
<fileset id="src3" dir="${generated.java.dir}" includes="**/*.java" erroronmissingdir="no" />
<fileset id="build" dir="${build.java.dir}" includes="**/*.class" erroronmissingdir="no" />
<difference id="targets.todelete">
  <resourcelist>
    <string>${toString:src1};${toString:src2};${toString:src3}</string>
    <filterchain>
      <tokenfilter>
        <replacestring from=";" to="${line.separator}" />
        <replacestring from=".java" to=".class" />
      </tokenfilter>
      <ignoreblank/>
      <prefixlines prefix="${build.java.dir}/" />
    </filterchain>
  </resourcelist>
  <resourcelist>
    <string>${toString:build}</string>
    <filterchain>
      <tokenfilter>
        <replacestring from=";" to="${line.separator}" />
        <!-- map inner classes back to their java files -->
        <replaceregex pattern="$.*(.class)" replace="1" flags="gi"/>
      </tokenfilter>
      <prefixlines prefix="${build.java.dir}/" />
    </filterchain>
  </resourcelist>
</difference>
<if>
  <not>
    <length string="${toString:targets.todelete}" trim="true" length="0" />
  </not>
  <then>
    <echo>Source files were deleted, cleaning output to force re-build!</echo>
    <delete dir="${build.java.dir}" />
    <delete dir="${build.test.java.dir}" />
    <delete dir="${cobertura_html_report.dir}" />
  </then>
</if>

问题是difference资源集合基于绝对路径而不是相对路径来执行差异。而且没有办法让Ant将映射器应用到一个完整的绝对路径。它只适用于资源名称。

解决方案是将文件集序列化为字符串列表,对该字符串列表进行适当的更改,并将它们解释回不同的文件。

以下是build.xml的建议片段,它应该计算正确的类文件列表:

<fileset id="src" dir="${src.java.dir}" includes="**/*.java"/>
<fileset id="build" dir="${build.java.dir}" includes="**/*.class"/>
<difference id="targets.todelete">
    <resourcelist>
        <string>${toString:src}</string>
        <filterchain>
            <tokenfilter>
                <replacestring from=";" to="${line.separator}" />
                <replacestring from=".java" to=".class" />
            </tokenfilter>
            <prefixlines prefix="${build.java.dir}" />
        </filterchain>
    </resourcelist>
    <resourcelist>
        <string>${toString:build}</string>
        <filterchain>
            <tokenfilter>
                <replacestring from=";" to="${line.separator}" />
            </tokenfilter>
            <prefixlines prefix="${build.java.dir}" />
        </filterchain>
    </resourcelist>
</difference>

相关内容

  • 没有找到相关文章

最新更新