在某些情况下,控制两个任务的执行顺序很有用,而无需在这些任务之间引入显式依赖关系。
任务排序和任务依赖的主要区别在于,排序规则不影响哪些任务将被执行,只影响它们将以何种顺序执行。
任务排序在许多场景中都很有用
强制任务的顺序执行(例如,build 绝不能在 clean 之前运行)。
在构建早期运行构建验证(例如,在开始发布构建工作之前验证我拥有正确的凭据)。
通过在长时间验证任务之前运行快速验证任务来更快地获得反馈(例如,单元测试应在集成测试之前运行)。
一个聚合所有特定类型任务结果的任务(例如,测试报告任务结合所有已执行测试任务的输出)。
有两种排序规则可用:“必须在之后运行”和“应该在之后运行”。
要指定两个任务之间的“必须在之后运行”或“应该在之后运行”的顺序,您可以使用 Task.mustRunAfter(java.lang.Object...) 和 Task.shouldRunAfter(java.lang.Object...) 方法。这些方法接受一个任务实例、一个任务名称或 Task.dependsOn(java.lang.Object...) 接受的任何其他输入。
当您使用“必须在之后运行”时,您指定当构建需要执行 taskX 和 taskY 时,taskY 必须始终在 taskX 之后运行。因此,如果您只使用 mustRunAfter 运行 taskY,您不会导致 taskX 运行。这表示为 taskY.mustRunAfter(taskX)。
build.gradle.kts
val taskX by tasks.registering {
doLast {
println("taskX")
}
}
val taskY by tasks.registering {
doLast {
println("taskY")
}
}
taskY {
mustRunAfter(taskX)
}
build.gradle
def taskX = tasks.register('taskX') {
doLast {
println 'taskX'
}
}
def taskY = tasks.register('taskY') {
doLast {
println 'taskY'
}
}
taskY.configure {
mustRunAfter taskX
}
$ gradle -q taskY taskX
taskX
taskY
“应该在之后运行”排序规则类似但限制较少,因为它在两种情况下会被忽略:
如果使用该规则会引入排序循环。
当使用并行执行且所有任务依赖项都已满足,除了“应该在之后运行”的任务,那么此任务无论其“应该在之后运行”的依赖项是否已运行都将运行。
您应该在排序有用但不严格要求的情况下使用“应该在之后运行”。
build.gradle.kts
val taskX by tasks.registering {
doLast {
println("taskX")
}
}
val taskY by tasks.registering {
doLast {
println("taskY")
}
}
taskY {
shouldRunAfter(taskX)
}
build.gradle
def taskX = tasks.register('taskX') {
doLast {
println 'taskX'
}
}
def taskY = tasks.register('taskY') {
doLast {
println 'taskY'
}
}
taskY.configure {
shouldRunAfter taskX
}
$ gradle -q taskY taskX
taskX
taskY
在上面的示例中,仍然可以在不导致 taskX 运行的情况下执行 taskY。
$ gradle -q taskY
taskY
如果“应该在之后运行”排序规则引入排序循环,它将被忽略。
build.gradle.kts
val taskX by tasks.registering {
doLast {
println("taskX")
}
}
val taskY by tasks.registering {
doLast {
println("taskY")
}
}
val taskZ by tasks.registering {
doLast {
println("taskZ")
}
}
taskX { dependsOn(taskY) }
taskY { dependsOn(taskZ) }
taskZ { shouldRunAfter(taskX) }
build.gradle
def taskX = tasks.register('taskX') {
doLast {
println 'taskX'
}
}
def taskY = tasks.register('taskY') {
doLast {
println 'taskY'
}
}
def taskZ = tasks.register('taskZ') {
doLast {
println 'taskZ'
}
}
taskX.configure { dependsOn(taskY) }
taskY.configure { dependsOn(taskZ) }
taskZ.configure { shouldRunAfter(taskX) }
$ gradle -q taskX
taskZ
taskY
taskX
请注意,taskY.mustRunAfter(taskX) 或 taskY.shouldRunAfter(taskX) 并不意味着任务之间存在任何执行依赖关系。
可以独立执行 taskX 和 taskY。排序规则仅在两个任务都计划执行时才有效。
当使用 --continue 运行时,如果 taskX 失败,taskY 仍然有可能执行。