In this chapter, we will discuss the basic unit of Gradle build script, that is, Task. We will have a detailed look into the Task framework, how to create your own tasks, overwrite tasks provided by Gradle, tasks configurations, and creating custom tasks using different approaches provided by Gradle. We will also discuss the task dependencies. This chapter will also give insight view of controlling the execution of tasks, how to enable or disable task execution, and skip task execution based on some conditions. Gradle provides one additional feature known as incremental build support, which skips the execution of tasks if it is up to date, that is, if there are no changes in the input and output of the tasks. It helps in reducing the build time of the scripts if you are running the build repeatedly. We will try to understand this feature with some examples. Gradle supports this functionality by default. We will see how to extend this feature to user-defined tasks. Additionally, we will also explore the Project
object provided by Gradle to control the build scripts.
A build script is nothing but a set of actions that execute in some predefined order and perform certain operations. In Gradle, we call these actions or group of actions a Task, which is part of the parent entity called Project. The atomic unit of execution in the Gradle build file is called a Task. The outcome of the build file might be some assets such as JAR, WAR, and so on, or it might perform certain operations such as deployment of assets and configuration of assets. Each build file that is build.gradle
represents at least one project. It might contain more than one project also in case of multiproject or multimodule build. We will discuss multiproject build in Chapter 6, Working with Gradle. The execution of the build represents the execution of the Project
object, which internally calls different tasks to perform the operations.
When you execute any build script, Gradle instantiates the org.gradle.api.Project
object for the build file and gives an implicit project object. You can use this object to access the Project API in the build file either through project.<methodname | property>
or simply <methodname | property>
. For example; to print the name of the project in your build file, you can use the following code:
println "Project name is "+project.name println "Project name is "+name // here project object is implicit println "Project name is $project.name" println "Project name is $name"
All the preceding statements will return the same output, that is, the project name. The project name is the name of the parent directory of the build.gradle
file. Consider that build.gradle
is under the Chapter3
directory; thus, the output of the preceding statements would be Project name is Chapter3
. You can change the name of the project by providing rootProject.name=<New Project Name>
in the settings.gradle
file. We will discuss further usage of the settings.gradle
file in Chapter 6, Working with Gradle.
The following are some of the properties of the project object, which can be used to configure the build file using the getter and setter methods:
name // readonly
, you can only change using settings.gradle
parent // readonly
version
description
Some of the properties are read-only, which are directly set by Gradle runtime.
Gradle also provides some default tasks, which can be used without applying any plugin such as copy task and zip task. It is also possible to define your own custom properties and custom tasks for the project object.
For each task in the build file, Gradle instantiates one of the implementations of Task object. There are different implementations of the Task interface; you can find further details of it at https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html. Similar to the Project
object, you can also control tasks programmatically using the Task API. You will see more details on this when we will create custom tasks using Groovy in a later section. In summary:
We will start with a simple build file example to explain the existing project properties, provide custom properties, create tasks, and so on.
Consider the file location /Chapter3/build.gradle
:
// Section 1: Project object existing properties version = '1.0' description = 'Sample Java Project' // Section 2: Project level custom properties ext { startDate="Jan 2015" } ext.endDate = "Dec 2015" println "This is project configuration part, description is $description" // Section 3: Task task sampleTask1 { // Section 3.1: Task existing properties description = "This is task level description" // Section 3.2: Task level custom properties ext { taskDetail=" This is custom property of task1" } println "This is sampleTask1 configuration statements, taskDetail is $taskDetail" // Section 3.3: Task actions doFirst { println "Project name is $project.name, description is $project.description" println "Task name is $name, description is $description" println "Project start date is $startDate" } doLast { println "Project endDate is $endDate" } } // Section 4: Task task sampleTask2 { println "This is sampleTask2 configuration statements" doFirst { println "Task getProjectDetailsTask properties are: "+sampleTask1.taskDetail } }
To execute the preceding build.gradle
file:
$ gradle sampleTask1 sampleTask2 This is project configuration part, description is Sample Java Project This is sampleTask1 configuration statements, taskDetail is This is custom property of task1 This is sampleTask2 configuration statements :sampleTask1 Project name is chapter3, description is Sample Java Project Task name is sampleTask1, description is This is task level description Project start date is Jan 2015 Project endDate is Dec 2015 :sampleTask2 Task getProjectDetailsTask properties are: This is custom property of task1 BUILD SUCCESSFUL Total time: 6.892 secs
In the preceding example, in Section 1, we have overwritten some of the existing properties of the project object. In Section 2, we have added custom properties to the project object. Note that the syntax of adding custom properties is to add the <name=value>
pair inside the ext
closure, or we can define it as ext.<propertyname> = value
. Then, we have added two tasks to this build script in Section 3 and 4 and added custom properties to the sampleTask1
task. To add/update properties of the project, you do not need to add the def
keyword. def
is used to define the user-defined variables. However, here we are defining project properties. If you use def startDate=<Value>
, it would be treated as a variable not a project property.
We are able to print the startDate
and endDate
in sampleTask1
as we added these two as project properties, which can be directly accessed throughout the build file. To call task methods or to use task properties outside the task, we can use task.<property name>
or task.<method name>
. As in the preceding example, inside the sampleTask2
task, we are printing sampleTask1.taskDetail
.
There are multiple ways to specify the properties of any project. We will see this in detail when we discuss properties in Chapter 6, Working with Gradle.
3.147.59.198