Gradle executes tasks that is not called

Hello,

I have two tasks (1.cucumber 2. hello)in build script as -

task cucumber{
println “Executing the gradle cucumber task”
}

task( hello, dependsOn: jar, type: JavaExec ) {
main = 'CukeRunner.MainTest’
classpath = sourceSets.test.runtimeClasspath
}

The task cucumber is just any other simple task to print in console,and task hello is calling the main method of the project.

Now the doubt I have is:-

When I do ‘gradle -q cucumber’ - it simply prints the line - Executing the gradle cucumber task BUT when I do ‘gradle -q hello’ it prints two lines i.e.,

Executing the gradle cucumber task
I am in main method

So here I can see the that the cucumber task is also getting called when I call the hello task.Could some one please explain the reason?

This is not what happens.
Gradle correctly executes the hello task when you do ‘gradle -q hello’.
The cucumber task is not executed when you do ‘gradle -q hello’.
It is configured though, like any stuffs from your build script.

When you create a task using the shortcut way

task taskName {
...
}

You actually call this method on the project linked to your build.gradle file
The closure that you can define is used to configure your task. It is therefore applied during the configuration phase.

During the configuration of your cucumber task, you print “Executing the gradle cucumber task”.
This will always be done, as long as your task is configured.

In the meantime, when you write

task( hello, dependsOn: jar, type: JavaExec ) {
main = ‘CukeRunner.MainTest’
classpath = sourceSets.test.runtimeClasspath
}

you also configure your task ‘hello’. You store custom values on two attributes of this class (main and classpath). This is also done during the configuration phase.

After the configuration phase, comes the execution phase (if the task is scheduled to be executed on the task graph, i.e. you explicitly called it, or you called a task that depends on it, …)

During the ‘hello’ task execution, the list of actions registered on the tasks are called. Since this task is a JavaExec subtask, the Java Exec action is called, which is ‘launching the main stuff as a java process, using the provided classpath, etc’

You custom task does not declare any action (more on this below), so it actually does nothing during the execution phase.
When declaring a custom task, you have to think about this configuration/execution notion.

To sum up

  • Currently Gradle has configuration and execution phases
  • Configuration is done by parsing your build phase and creating stuffs you declare on it
  • Execution phase is only a matter of executing the Actions registered on the tasks scheduled to be run

To add stuffs to a task’s execution phase, you can use doFirst() and doLast() methods on the task.
i.e.

task myTask {
println ‘this is called during configuration phase’
doFirst {
println ‘this is called first when executed’
}
doLast{
println ‘this is called last when executed’
}
}

Note : the doLast action can be replaced by a shortcut notation

tash myTask << {
println ‘execution time !’
}

Final Note:
One of the goal of the rule based model that is currently taking over in Gradle is to remove the concept of configuration and execution phases. When it is finished, everything will be ‘execution’

3 Likes

Is there a simply way to avoid the execution of a task script during the configuration phase? Give a example of how to skip the execution of the println in the “task cucumber” during the configuration phase.