Engineering Full Stack Apps with Java and JavaScript
Gradle lifecycle consist of three phases: initialization, configuration, and execution:
During Initialization, Gradle decides which projects are to participate in the build.
During Configuration, task objects are assembled into an internal object model, usually called the DAG (for directed acyclic graph).
During Execution, build tasks are executed in the order required by their dependency relationships.
Closure in Gradle
A block of code between two curly braces is referred to as closure, and a closure is like an object that can be passed as a parameter to a method or assigned to a variable to execute later.
task helloWorld << {
println 'Hello World'
}
Tasks in Gradle
Though gradle tasks may look like tasks in other languages, gradle tasks are actually objects and you can even program using them if you want. A gradle task consists of a name, and optionally action and configuration block.
We will see actions and configuration blocks next.
Action is a closure appended to a task using << operator.
We need to declare a task and append an action.
We can declare a task as:
task helloWorld
and then assign the action later as:
helloWorld << {
println 'Hello World'
}
We can also declare name and append action together as:
task helloWorld << {
println 'Hello World'
}
Gradle action closures append to the list of actions. Here << is an append operator, not a replacement operator. So above task and definition can be decomposed as:
task helloWorld
helloWorld << {
print 'Hello'
}
helloWorld << {
println ' World!'
}
When you execute ‘gradle –q helloWorld’, all the above build files will print:
Hello World
This is possible because tasks in gradle are programmable objects.
Task actions are executed during the execution phase of Gradle lifecycle.
A configuration block is executed in the configuration phase, which is before the execution phase. It can be used to setup variables or data structures needed by a task action.
A configuration block is defined by a closure without the << operator.
Configuration blocks are also appended to other configuration blocks, similar to actions.
Example:
task helloWorld
helloWorld << {
println 'Hello World'
}
helloWorld {
println 'Config block 1'
}
helloWorld {
println 'Config block 2'
}
When you execute ‘gradle –q helloWorld’, this will print:
Config block 1
Config block 2
Hello World
Note that config blocks are appended and executed before the actions.
All build configuration code will run every time you run a Gradle build file, regardless of task that is executed.
Example:
task helloWorld
task anotherTask
helloWorld << {
println 'Hello World'
}
helloWorld {
println 'Config block 1'
}
anotherTask {
println 'Config block 2'
}
If you execute this as ‘gradle –q anotherTask’ you will get the output as:
Config block 1
Config block 2
If you execute this as ‘gradle –q helloWorld’ you will get the output as:
Config block 1
Config block 2
Hello World
http://www.gradle.org/docs/current/userguide/writing_build_scripts.html
Book: Building and Testing with Gradle by Tim Berglund and Matthew McCullough.
Examples in this note has been tested against Gradle versions 1.11 and 2.1.