Creating a task that runs before all other tasks in gradle

前提是你 提交于 2019-12-04 19:29:43

问题


I need to create an initialize task that will run before all other task when I execute it.

task A {
    println "Task A"
}

task initializer {
   println "initialized"
}

If I execute gradle -q A, the output will be:

>initialized

>Task A

Now if i'll add:

task B {
    println "Task B"
}

Execute gradle -q B, and I get:

>initialized

>Task B

So it doesn't matter which task I execute, it always get "initialized" first.


回答1:


You can make every Task who's name is NOT 'initializer' depend on the 'initializer' task. Eg:

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" }
}

Or you could add a BuildListener (or use one of the convenience methods eg: Gradle.buildStarted(...))




回答2:


The previously suggested solution with dependsOn works fine, but I don't like about it that it changes and clutters the task dependencies. The first solution coming to my mind is using Gradle Initialization Scripts. They are really cool. But, the usage is a bit tedious: currently there is no way to have a default project-local Gradle init script. You have to either explicitly specify the script(s) on command line, or place them in USER_HOME/GRADLE_HOME.

So another solution (already briefliy mentioned by @lance-java) which can be used to run some initialization, like a init task/script, is "build listeners". Depending on how early/late the initialization code should run, I use one of these two:

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

or

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

Here the docs of the Gradle interface and of BuildListener.

Note that some of the events occur very early, and you probably can't use them because of that, like e.g. beforeProject and buildStarted (explanations here and there).




回答3:


Seems like you aim execution phase, and you want a task precursing each task or just run as a first task in the execution phase?

If you want a task to always execute in every project before each other task after its being evaluated you can add a closure to he main build.gradle:

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

or

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

You can also use the Task Execution Graph to define the lifecycle. There are few ways of achieving your goal, depending on your needs and a project structure.



来源:https://stackoverflow.com/questions/45183642/creating-a-task-that-runs-before-all-other-tasks-in-gradle

标签

工具导航Map