Gradle uses up-to-date checks as a mechanism to avoid re-executing tasks unnecessarily, optimizing the build process and reducing execution time. Before executing a task, Gradle checks whether the task is up-to-date by comparing the task’s inputs and outputs. If none of the inputs or outputs have changed, the task is considered up-to-date, and Gradle skips its execution.
graph LR
A[Task Execution Requested] --> B{Are Inputs/Outputs Tracked?}
B -- No --> C[Task Executed]
B -- Yes --> D{Have Inputs Changed?}
D -- Yes --> C[Task Executed]
D -- No --> E{Have Outputs Changed??}
E -- Yes --> F[Task Skipped: Up-to-date]
E -- No --> C[Execute Task]
C --> G[Outputs Updated]
F --> G[Task Completed]
Example output
Example how gradle shows that a task was skipped because it was up-to-date (refer to to-add-print-more-output to see such output):
Task :lib:processData UP-TO-DATE
How Up-to-date Checks Work:
Gradle tracks the inputs (files, property, etc.) and outputs (generated files, artifacts) of each task.
If the inputs haven’t changed and the outputs haven’t changed, Gradle considers the task up-to-date and does not execute it. Gradle uses the hashes of the inputs and outputs to determine if they have changed. (hashes-data-of-input-and-output)
This feature improves build times by preventing tasks from running unnecessarily.
Gotcha:
environment-variables and system are not tracked by Gradle and can cause tasks to be skipped unintentionally.
Example of Up-to-date Checks:
tasks.register("processData") { // Declare input and output for the task inputs.file("src/data/input.txt") // Input file outputs.file("build/output.txt") // Output file doLast { println("doLast Task executing, Processing input...") val inputFile = file("src/data/input.txt") val outputFile = file("build/output.txt") outputFile.writeText("""${Instant.now()} ${inputFile.readText().toUpperCase()}""") println("Task executed: Input processed.") }}
Input: The file src/data/input.txt is declared as the input.
Output: The file build/output.txt is declared as the output.
When Gradle runs the task, it checks whether the input or output has changed. If the input file is unchanged and the output file already exists with the correct content, Gradle will skip re-executing the task and consider it up-to-date.
Additional Information:
Force Task Execution
Force Task Execution
Forcing Task Execution:
You can force Gradle to execute a task even if it is up-to-date by using the --rerun-tasks flag (such as test execution):