创建一个在 gradle 中的所有其他任务之前运行的任务

Creating a task that runs before all other tasks in gradle

我需要创建一个初始化任务,当我执行它时,它将 运行 先于所有其他任务。

task A {
    println "Task A"
}

task initializer {
   println "initialized"
}

如果我执行gradle -q A,输出将是:

>initialized

>Task A

现在如果我要添加:

task B {
    println "Task B"
}

执行gradle -q B,我得到:

>initialized

>Task B

所以不管我执行哪个任务,它总是先得到"initialized"。

您可以让名称不是 'initializer' 的每个任务都依赖于 'initializer' 任务。例如:

task initializer {
   doLast { println "initializer" }
}

task task1() {
   doLast { println "task1" }
}

// make every other task depend on 'initializer'
// matching() and all() are "live" so any tasks declared after this line will also depend on 'initializer'
tasks.matching { it.name != 'initializer' }.all { Task task ->
    task.dependsOn initializer
}

task task2() {
   doLast { println "task2" }
}

或者您可以添加 BuildListener (or use one of the convenience methods eg: Gradle.buildStarted(...))

似乎您的目标是执行阶段,并且您希望每个任务都预先执行一个任务,或者只是 运行 作为执行阶段的第一个任务?

如果你想让一个任务在每个项目中总是在其他任务之前执行在它被评估之后你可以添加一个闭包到他的主要build.gradle:

allprojects {
  afterEvaluate {
    for(def task in it.tasks)
      if(task != rootProject.tasks.YourTask)
      task.dependsOn rootProject.tasks.YourTask
  }
}

tasks.matching {it != YourTask}.all {it.dependsOn YourTask}

您也可以使用Task Execution Graph来定义生命周期。根据您的需求和项目结构,实现目标的方法很少。

之前建议的 dependsOn 解决方案工作正常,但我不喜欢它,因为它改变了任务依赖性并使任务依赖性变得混乱。我想到的第一个解决方案是使用 Gradle Initialization Scripts。他们真的很酷。但是,用法有点乏味:目前没有办法有一个 default project-local Gradle init script。您必须在命令行上明确指定脚本,或将它们放在 USER_HOME/GRADLE_HOME.

所以另一个解决方案(@lance-java 已经简要提到)可以用于 运行 一些初始化,比如 init task/script,是 "build listeners" .根据 early/late 初始化代码应该如何 运行,我使用以下两个之一:

gradle.afterProject {
    println '=== initialized in afterProject'
}

gradle.taskGraph.whenReady {
    println '=== initialized in taskGraph.whenReady'
}

这里是 Gradle interface and of BuildListener.

的文档

请注意,有些事件发生得非常早,因此您可能无法使用它们,例如beforeProjectbuildStarted(解释 here and there)。