1. Creating Simple Tasks
A task in Gradle is a single piece of work, such as compiling classes, running tests, or packaging applications.
Syntax
Tasks can be defined using the task
keyword followed by a task name and an optional configuration block.
Example
// Define a simple task
task hello {
doLast {
println 'Hello, World!'
}
}
In this example, the hello
task prints "Hello, World!" to the console.
2. Configuring Tasks
Tasks can have multiple actions using doFirst
and doLast
methods. Actions added with doFirst
will execute before the task's main action, and those added with doLast
will execute after.
Example
task greet {
doFirst {
println 'Starting task...'
}
doLast {
println 'Hello, World!'
}
doLast {
println 'Task completed.'
}
}
This task will print "Starting task...", "Hello, World!", and "Task completed." in sequence.
Task Properties
Tasks can have properties to configure their behavior. For example, a Copy
task has from
and into
properties.
Example
task copyFiles(type: Copy) {
from 'src/main/resources'
into 'build/resources'
}
This task copies files from src/main/resources
to build/resources
.
3. Task Dependencies
Tasks can depend on other tasks, ensuring that dependent tasks are executed before the task itself.
Example
task compile {
doLast {
println 'Compiling source code...'
}
}
task build {
dependsOn compile
doLast {
println 'Building project...'
}
}
In this example, the build
task depends on the compile
task, ensuring that compile
runs before build
.
4. Task Inputs and Outputs
Tasks can define inputs and outputs to determine if they are up-to-date and if they need to be executed again.
Example
task compile {
inputs.file 'src/main/java/MyClass.java'
outputs.file 'build/classes/MyClass.class'
doLast {
println 'Compiling MyClass.java...'
// Compilation logic here
}
}
This task specifies that MyClass.java
is the input and MyClass.class
is the output. If the input file changes, the task will be executed again.
5. Incremental Tasks
Incremental tasks only process inputs that have changed since the last execution.
Example
task compile(type: IncrementalTask) {
inputs.dir 'src/main/java'
outputs.dir 'build/classes'
doLast {
println 'Compiling changed files...'
// Incremental compilation logic here
}
}
This task will only compile files that have changed since the last execution.
6. Built-in Tasks
Common Built-in Tasks
Gradle provides several built-in tasks for common build activities.
- clean: Deletes the build directory.
- assemble: Assembles the outputs of the project.
- check: Runs all checks, including tests.
- build: Assembles and tests the project.
Example
./gradlew clean build
This command cleans the project and then builds it.
7. Custom Tasks
Custom tasks allow you to define specific actions that are not covered by the standard Gradle tasks.
Example
task customTask {
doLast {
println 'Executing custom task...'
}
}
This task prints "Executing custom task..." to the console.
8. Task Configuration Avoidance
Gradle provides a way to avoid configuring tasks until they are needed, improving build performance.
Example
tasks.register('lazyTask') {
doLast {
println 'Executing lazy task...'
}
}
The lazyTask
is not configured until it is executed.
9. Parallel Execution
Gradle can execute tasks in parallel to reduce build time. This requires specifying the --parallel
option when running tasks.
Example
./gradlew build --parallel
10. Finalized By
A task can specify another task to run after it, regardless of whether it succeeds or fails.
Example
task clean {
doLast {
println 'Cleaning project...'
}
}
task build {
doLast {
println 'Building project...'
}
finalizedBy clean
}
In this example, the clean
task will run after the build
task, regardless of the build's success.
Complete Example
Let's create a complete example to demonstrate various aspects of Gradle tasks.
Project Structure
gradle-tasks-example/
|-- build.gradle
|-- settings.gradle
|-- src/
|-- main/
|-- java/
|-- com/
|-- example/
|-- App.java
|-- resources/
|-- application.properties
|-- test/
|-- java/
|-- com/
|-- example/
|-- AppTest.java
build.gradle
plugins {
id 'java'
id 'application'
}
group 'com.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.0'
}
application {
mainClass = 'com.example.App'
}
tasks.register('hello') {
doLast {
println 'Hello, World!'
}
}
task copyFiles(type: Copy) {
from 'src/main/resources'
into 'build/resources'
}
task compileJava {
dependsOn 'copyFiles'
inputs.file 'src/main/java/com/example/App.java'
outputs.dir 'build/classes'
doLast {
println 'Compiling Java files...'
// Java compilation logic here
}
}
tasks.build {
dependsOn compileJava
doLast {
println 'Building the project...'
}
}
settings.gradle
rootProject.name = 'gradle-tasks-example'
src/main/java/com/example/App.java
package com.example;
public class App {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
src/test/java/com/example/AppTest.java
package com.example;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class AppTest {
@Test
public void testApp() {
assertTrue(true);
}
}
Conclusion
Understanding Gradle tasks is essential for effectively managing build processes. Tasks can be simple or complex, with dependencies, inputs, outputs, and incremental execution. Utilizing built-in tasks and creating custom tasks allows for flexible and efficient builds. For more detailed information, visit the official Gradle documentation.
Happy learning!
Comments
Post a Comment
Leave Comment