11

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.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Ori Wiesel
  • 488
  • 2
  • 8
  • 26

3 Answers3

18

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(...))

lance-java
  • 25,497
  • 4
  • 59
  • 101
4

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.

LazerBanana
  • 6,865
  • 3
  • 28
  • 47
  • answer to you question, i want it to be always the first task in the execution phase. – Ori Wiesel Jul 19 '17 at 14:32
  • @OriWiesel then why you have accepted an answer that precurse each task with a initialize task ? – LazerBanana Jul 19 '17 at 15:08
  • maybe i'm missing something. because, that's exactly what i was needed.. a task that run before all the other tasks.. – Ori Wiesel Jul 24 '17 at 08:37
  • @OriWiesel nvm, I was asking if you need a task that runs as a first task ONCE per build or a task that pre curse EACH task in the build. – LazerBanana Jul 24 '17 at 09:50
  • ohh... sorry, so the answer is Once per build and before all the other tasks. – Ori Wiesel Jul 24 '17 at 10:20
  • @OriWiesel and the answer you have accepted is running a task once per build before all other tasks? I thought it precedes each task with it, from looking at the code. – LazerBanana Jul 24 '17 at 10:22
  • yes it is.. because if a and b depends on c and you try to run a and b, then c will run, and after that a and b. it'll run only once (as for my knowledge) – Ori Wiesel Jul 24 '17 at 11:17
  • @OriWiesel hmm, feels weird as it attaches a dependency of a task on each task in the project, then looks like it would be invoked before each task, and if you ask me it's not really ideal, but well it works right ;) – LazerBanana Jul 24 '17 at 12:38
1

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).

t0r0X
  • 4,212
  • 1
  • 38
  • 34