假设我有一个任务“main”,它依赖于另一个任务“dependency”。我希望“main”在其依赖项(或其依赖项的依赖项)被重建的任何时候都可以重新运行,因为“main”依赖于“dependency”(或“dependency”的依赖项)产生的 Artifact 。
包含我正在处理的示例的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”,我真的很喜欢。这似乎很重要。您如何确定是这种情况?
最佳答案
在任务之间specify dependency的标准方法是通过任务的输入和输出。这可以是任何文件,文件集或目录。
在您的情况下,您应该修改main
任务,并将inputs.file 'deps.out'
添加到其定义中。
请注意,在您提供的简单示例中,gradle进行了优化,可能会导致意外行为。
Before a task is executed for the first time, Gradle takes a snapshot of the inputs. This snapshot contains the set of input files and a hash of the contents of each file. Gradle then executes the task. If the task completes successfully, Gradle takes a snapshot of the outputs. This snapshot contains the set of output files and a hash of the contents of each file. Gradle persists both snapshots for the next time the task is executed.
Each time after that, before the task is executed, Gradle takes a new snapshot of the inputs and outputs. If the new snapshots are the same as the previous snapshots, Gradle assumes that the outputs are up to date and skips the task. If they are not the same, Gradle executes the task. Gradle persists both snapshots for the next time the task is executed.
因此,即使您在生成相同文件的简单示例中指定了正确的输入,在第二次及以后的运行中,相关任务也会被标记为最新。
如果您不希望或无法对文件进行硬编码依赖性,则可以根据此任务的dependencies及其state覆盖相关任务的
upToDateWhen
并计算条件(如果该任务是最新的):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
似乎按预期工作了)。
关于gradle - 运行依赖项时如何使Gradle重新运行任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34277839/