假设我有一个依赖于另一个任务“依赖”的任务“主”。我希望在重建任何依赖项(或其依赖项的依赖项)时重新运行“main”,因为“main”依赖于“依赖项”(或“依赖项”的依赖项)产生的工件。
包含我正在处理的内容示例的build.gradle
文件如下:
defaultTasks 'main'
task baseDependency {
outputs.file 'deps.out'
outputs.upToDateWhen { false }
doLast {
exec {
commandLine 'bash', '-c', 'echo hello world > deps.out'
}
}
}
task dependency(dependsOn: baseDependency)
task main(dependsOn: dependency) {
outputs.file 'main.out'
doLast {
exec {
commandLine 'bash', '-c', 'echo hello world > main.out'
}
}
}
第一次执行gradle
:
:baseDependency
:dependency
:main
BUILD SUCCESSFUL
Total time: 0.623 secs
第二次执行:
:baseDependency
:dependency
:main UP-TO-DATE
BUILD SUCCESSFUL
Total time: 0.709 secs
如果“main” 标记为“UP-TO-DATE”,如果必须重建其依赖项,那么 非常喜欢。这似乎很重要。你怎么确定是这样的?
答案 0 :(得分:3)
任务之间specify dependency的标准方式是通过任务的输入和输出。这可以是任何文件,文件集或目录。
在您的情况下,您应修改main
任务并将inputs.file 'deps.out'
添加到其定义中。
请注意,gradle有一个优化,可能会在您提供的简单示例中导致意外行为。
在第一次执行任务之前,Gradle会拍摄快照 的输入。此快照包含一组输入文件和一个 每个文件内容的哈希值。 Gradle然后执行任务。如果 任务成功完成,Gradle拍摄了快照 输出。此快照包含一组输出文件和一个散列 每个文件的内容。 Gradle会为下一个快照保留两个快照 任务执行的时间。
每次之后,在执行任务之前,Gradle会采用新的 输入和输出的快照。如果新快照是相同的 与之前的快照一样,Gradle假定输出最多 日期并跳过任务。如果它们不相同,Gradle会执行 任务。 Gradle会在下次任务时保留两个快照 执行。
因此,即使您在生成相同文件的简单示例中指定了正确的输入,依赖任务也将在第二次和后续运行时标记为最新。
如果您不想或不能对文件进行硬编码,则可以为依赖任务覆盖upToDateWhen
,并根据此任务的dependencies及其{state计算任务的最新条件。 {3}}像这样:
outputs.upToDateWhen { task ->
task.taskDependencies.inject(true) { r, dep ->
r && dep.values.inject(true) { res, v ->
res && (!(v instanceof Task) || v?.state.getSkipped())
}
}
}
如果不应该运行此任务(因为其输出已经是最新的), upToDateWhen
应该返回true
。当没有执行任何依赖任务时就是这种情况(gradle文档对此我有点模糊,我必须承认,但getSkipped
似乎按预期工作)。