Skip to content

Projects and Tasks

Estimated time to read: 4 minutes

Structure

What is in a project?

  • A 'build' file
  • build.gradle (Groovy DSL)
  • build.gradle.kts (Kotlin DSL)
  • Optional settings file

What is in a build file?

  • Build file defines tasks for the project
  • Either pre-defined
  • Directly in using DSL
  • Indirectly through plugins

Default Tasks

Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'test'.
dependencies - Displays all dependencies declared in root project 'test'.
dependencyInsight - Displays the insight into a specific dependency in root project 'test'.
help - Displays a help message.
javaToolchains - Displays the detected java toolchains.
outgoingVariants - Displays the outgoing variants of root project 'test'.
projects - Displays the sub-projects of root project 'test'.
properties - Displays the properties of root project 'test'.
resolvableConfigurations - Displays the configurations that can be resolved in root project 'test'.
tasks - Displays the tasks runnable from root project 'test'.

Writing Tasks

A project file consists of tasks. When a task is run, Gradle runs through several phases for that given task.

Build Phases

  • Initialisation
  • Gradle works out which parts of the project are going to be included in the current build.
  • If it is a multi-project build, then it determines which projects in the multi-project build become part of the execution.
  • Configuration
  • Configuration is done by executing the build scrips of all of the projects that are a part of the current build.
  • Execution
  • Gradle works out which tasks are to be executed, based upon the task name that has been passed as the argument for Gradle on the command line.

Task Execution

A given task has multiple phases of execution:

  • doFirst - Specifies the actions that execute at the start of the task execution
  • doLast - Specifics the actions that execute at the end of the task execution
  • Conditional Elements - Conditions can be included in task execution, so that actions only execute if a given condition is valid

Task Example

Groovy

task hello {
 doFirst {
  print 'Hello'
 }
 doLast {
  print 'World!'
 }
}

Kotlin

tasks.register("hello") {
 doFirst {
  print("Hello")
 }
 doLast {
  print("World!")
 }
}

Dependencies

Tasks may have dependencies, for example a jar task depends on the classes task. A task may have more than one dependency and a sub-task may have further dependencies.

Screenshot 2022-08-02 at 16.41.06.png In the example above:

  • Task A is dependant on Task B, C and D.
  • Task C and D and dependant on Task E.

When running Task A, all other dependant tasks, B, C, D and E must also be run. Task E must run before C and D. Task B, C and D must run before A.

Example build files

Groovy

task hello {
 doLast {
  println 'Hello, '
 }
}

task world {
 dependsOn hello

 doLast {
  println('world!')
 }
}

Kotlin

tasks.register("hello") {
 doLast {
  println("Hello, ")
 }
}

tasks.register("world") {

 dependsOn(hello) // Adding `dependsOn` runs the task that is being called within this task.

 doLast{
  println("world!")
 }
}

Output

gradle world

> Task :hello
Hello, 

> Task :world
world!

dependsOn

dependsOn can also be used in other ways, however, when it is called, the task the it depends on is always calculated in place within the execution sequence.

Groovy

task hello {
 doFirst {
  println ('He')
 }
 doLast {
  println ('llo, ')
 }
}

task world {
 dependsOn hello

 doFirst {
  println('Wo')
 }
 doLast {
  println('rld!')
 }
}

Kotlin

tasks.register("hello") {
 doFirst {
  println("He")
 }
 doLast {
  println("llo, ")
 }
}

tasks.register("world") {

 dependsOn(hello)
 doFirst {
  println("Wo")
 }
 doLast {
  println("rld!")
 }
}

Output

gradle world

> Task :hello
He
llo, 

> Task :world
Wo
rld!

Adding Plugins

Tasks can be added to the project either by adding tasks to the task collection explicitly within Kotlin or the task function within Groovy. Doing so enables us to build dependencies of tasks also.

Plugins allow tasks to be added to a project. A plugin extends the projects capabilities. For example, the Java plugin.

Java Plugin

plugins { java } //Kotlin / KTS
plugins { id 'java'} // Groovy (Preferred)
apply plugin: 'java' // Groovy

The Java plugin is part of Gradle's core library, so it can be added to a Gradle build using the examples above. This then provides a collection of tasks that are suitable for Java applications.

Community Plugins

In this example, we will be using Flyway as an external plugin.

Community plugins can not be defined in a Gradle build file by name. They must be defined by their reverse QDN and version. For example:

Groovy

plugins {
 id 'java'
 id 'org.flywaydb.flyway' version '9.0.4'
}

Kotlin

plugins {
 java
 id ('org.flywaydb.flyway') version '9.0.4'
}

Running gradle tasks after a community plugin has been added to a build file will tell Gradle to attempt to acquire the plugin via its repository, along with its dependencies. By default, this is done automatically.