Gradle文档是这样说的:
请注意,如果任务指定了输出目录,则自上次执行以来添加到该目录的任何文件都将被忽略,并且不会导致任务过期。因此,不相关的任务可以共享输出目录而不会相互干扰。如果由于某种原因这不是您想要的行为,请考虑使用 TaskOutputs.upToDateWhen(groovy.lang.Closure)
问题:具有 upToDateWhen 的解决方案是什么样的(以便考虑添加的文件)。主要问题是必须访问构建缓存才能在上次运行任务时检索输出目录内容哈希。
不确定我是否正确理解了这个问题,或者为什么你提到构建缓存。我假设您不知道除了任何其他最新检查(例如与TaskOutputs.dir()
一起添加的检查)之外,还考虑了与upToDateWhen()
一起添加的谓词?
执行以下示例任务:
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
}