2

Gradle文档告诉我们:

请注意,如果任务指定了输出目录,则自上次执行以来添加到该目录的任何文件都将被忽略,并且不会导致任务过期。这是因为不相关的任务可以共享一个输出目录而不会相互干扰。如果由于某种原因这不是您想要的行为,请考虑使用 TaskOutputs.upToDateWhen(groovy.lang.Closure)

问题:使用 upToDateWhen 的解决方案如何(以便考虑添加的文件)。主要问题是必须访问构建缓存以检索上次任务运行时的输出目录内容哈希。

4

1 回答 1

2

不确定我是否正确理解了这个问题,或者您为什么提到构建缓存。我假设您不知道除了任何其他最新检查(例如添加upToDateWhen()的谓词?TaskOutputs.dir()

采取以下示例任务:

task foo {
    def outDir = file('out')
    outputs.dir(outDir)
    outputs.upToDateWhen { outDir.listFiles().length == 1 }
    doLast {
       new File(outDir, 'foo.txt') << 'whatever'
    }
}

只要输出目录中只有一个文件(通过 配置upToDateWhen并且任务(out/foo.txt)生成的文件在任务运行后没有更改,任务将是最新的。如果您更改/删除任务在输出目录中创建的文件,或者如果您将更多文件添加到输出目录,则任务将再次运行。


根据评论中的更新问题更新答案:

task foo {
    def outDir = file('out')

    /* sample task action: */
    doFirst {
        def numOutFiles = new Random().nextInt(5)
        for (int i = 1; i <= numOutFiles; i++) {
            new File(outDir, "foo${i}.txt") << 'whatever'
        }
    }

    /* up-to-date checking configuration: */
    def counterFile = new File(buildDir, 'counterFile.txt')
    outputs.dir(outDir)
    outputs.upToDateWhen {
        counterFile.isFile() \
          && counterFile.text as Integer == countFiles(outDir)
    }
    doLast {
        counterFile.text = countFiles(outDir)
    }
}

def countFiles(def dir) {
    def result = 0
    def files = dir.listFiles()
    if (files != null) {
        files.each {
            result++
            if (it.isDirectory()) {
                result += countFiles(it)
            }
        }
    }
    result
}
于 2019-01-08T11:51:30.387 回答