Gradle 插件:任务 C 应该 运行 如果任务 A 或任务 B:

Gradle Plugin: Task C should run if Task A or Task B:

我正在创建自定义插件任务,遇到需要帮助的情况。 我创建了 3 个任务。 gradle 中的任务 A、B、C。 仅当 A 或 B 成功时,才应执行任务 C。 请注意,A 和 B 是 2 个独立的任务,并不相关。

class A extends DefaultTask { }

class B extends DefaultTask { }

class C extends DefaultTask { }

如果我尝试 C.dependsOn(A); C.dependsOn(B);,那么我认为 C 依赖于 A B(不是 A B ).有没有办法在这里指定A B条件

您可以添加多个依赖项。

task B << {
    println 'Hello from B'
}

task C << {
    println 'Hello from C'
}

task D(dependsOn: ['B', 'C'] << {
    println 'Hello from D'
}

输出为:

> gradle -q D
Hello from B
Hello from C
Hello from D

Gradle 为任务依赖性和排序提供了四种方法(和相关容器):

风格:t1.<method>(t2)

  1. dependsOn - 确保 t2 被执行 ifbefore t1被执行。

  2. finalizedBy - 确保 t2 被执行 ifafter t2被执行。

  3. mustRunAfter - 确保 if t2t1 都被执行(由其他触发器引起) , t1 执行 after t2.

  4. shouldRunAfter - 与 mustRunAfter 基本相同,但对于特殊情况可以忽略(检查 the docs)。

你的要求比较特殊,用上面这种简单的方法是解决不了的。如果我理解你的问题是正确的,你想确保任务 C 在任务 A 和 B 之后执行,但前提是它无论如何都会执行(而不是自动触发它)。对于要求的第一部分,您可以使用 mustRunAfter。但是,您还希望确保之前执行过任务 A 任务 B。我建议使用 onlyIf 方法跳过任务 C 的任务执行,如果之前没有执行过 A 或 B。示例:

task A { }
task B { }

task C {
    mustRunAfter A, B
    onlyIf { A.state.executed || B.state.executed }
}

我认为 gradle 7.x+ 中 PM 问题的答案应该是这样的:

A.finalizedBy('C')
B.finalizedBy('C')

tasks.register('C'){
  onlyIf{
    (gradle.taskGraph.hasTask('A') &&
            tasks.A.getState().getExecuted() &&
            tasks.A.getState().getFailure() == null) 
     ||
    (gradle.taskGraph.hasTask('B') &&
                    tasks.B.getState().getExecuted() &&
                    tasks.B.getState().getFailure() == null)
        
  }
}

在这种情况下,您不能像 'gradle C' 那样单独执行 C。

另一个选项可以是任务侦听器:

A.finalizedBy('C')
B.finalizedBy('C')

gradle.taskGraph.afterTask { Task task, TaskState taskState ->
    if (['A','B'].contains(task.getName())){
        if(taskState.getFailure() == null){
            project.tasks.getByName('C').setEnabled(true)
        }else{
            project.tasks.getByName('C').setEnabled(false)
        }
    }
}

使用此选项可以仅使用 'gradle C'.

执行 C

是的,另一种选择是声明 C 的输入,然后在任务侦听器中根据需要更改 C 的输入以影响其 upToDate 检查。

然后A和B直接执行或由其他触发器执行。如果 A 和 B 都在任务图中,那么 C 可能会被执行两次。如果 A 和 B 并行执行,IMO 的结果是不可预测的。