Gradle Task Dependencies and Ordering: Difference between revisions
Line 55: | Line 55: | ||
=Implicit Dependencies= | =Implicit Dependencies= | ||
==Task Inputs and Outputs== | ==Task Inputs and Outputs== | ||
Gradle determines whether a task is up to date if the task's inputs and outputs have not changed since the last execution, by comparing their values with those preserved in the [[Gradle_Build_Cache#Overview|build cache]]. If the input and output snapshots are identical to the previous ones, the task is not executed. An input can be a property, a directory or one or more files. An output is a directory or one or more files. Inputs and outputs are fields of the DefaultTask class. Task inputs and outputs are obtained with [https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html#getInputs-- Task.getInputs()] and [https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html#getOutputs-- Task.getOutputs()], which return [https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskInputs.html TaskInputs] and [https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskOutputs.html TaskOutputs] instances, respectively. | Gradle determines whether a task is up to date if the task's inputs and outputs have not changed since the last execution, by comparing their values with those preserved in the [[Gradle_Build_Cache#Overview|build cache]]. <font color=darkgray>Does the build cache need to be enabled for inputs and outputs to be relevant?</font> | ||
If the input and output snapshots are identical to the previous ones, the task is not executed. An input can be a property, a directory or one or more files. An output is a directory or one or more files. Inputs and outputs are fields of the DefaultTask class. Task inputs and outputs are obtained with [https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html#getInputs-- Task.getInputs()] and [https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html#getOutputs-- Task.getOutputs()], which return [https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskInputs.html TaskInputs] and [https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskOutputs.html TaskOutputs] instances, respectively. | |||
<font color=darkgray>Task inputs and outputs are evaluated during the configuration phase to wire up the task dependencies. That is why they need to be defined in a configuration block. To avoid unexpected behavior, make sure that the value you assign to inputs and outputs is accessible at configuration time. If you need to implement programmatic output evaluation, the method upToDateWhen(Closure) on TaskOutputs comes in handy. In contrast to regular inputs/outputs evaluation, this method is evaluated at execution time. If the closure returns true, the task is considered up to date.</font> | <font color=darkgray>Task inputs and outputs are evaluated during the configuration phase to wire up the task dependencies. That is why they need to be defined in a configuration block. To avoid unexpected behavior, make sure that the value you assign to inputs and outputs is accessible at configuration time. If you need to implement programmatic output evaluation, the method upToDateWhen(Closure) on TaskOutputs comes in handy. In contrast to regular inputs/outputs evaluation, this method is evaluated at execution time. If the closure returns true, the task is considered up to date.</font> |
Revision as of 00:09, 18 October 2020
External
- https://docs.gradle.org/current/dsl/org.gradle.api.Task.html#N18D13
- https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html#dependencies
Internal
Overview
May times, a task requires another task to run first, especially if the task depends on the produced output of its dependency task. A task may declared its dependencies explicitly. A task may depend on other tasks implicitly, as described in the Implicit Dependencies section.
In Gradle, task execution order is automatically determined taking into account explicit dependencies and implicit dependencies, and a specific execution order of all tasks involved is not guaranteed. The only thing that is guaranteed is that the dependencies will be honored. This architectural decision has several benefits: you don't need to know the whole chain of task dependencies to make a change, and because the tasks don't have to be executed strictly sequentially, they can be parallized.
Explicit Dependencies
The Task API used to declare explicit task dependencies is Task.dependsOn(Object... paths), which surfaces in the DSL as:
task red {
dependsOn 'blue', 'green' // comma is required
...
}
task red(dependsOn: [blue, green] {
...
}
task red {
...
}
red.dependsOn(blue, green)
Note that a task dependency may be another task name, the task instance itself or another objects.
If multiple tasks are provides as argument of dependsOn(...), the order in which they are declared does not influence the order in which they are executed. The only thing that is guaranteed is that all will be executed before the task that declares the dependency.
Other methods that can be used to set explicit dependencies are:
- Task.setDependsOn(Iterable)
- Task.mustRunAfter(Object...)
- Task.setMustRunAfter(Iterable)
- Task.shouldRunAfter(Object ...)
- Task.setShouldRunAfter(Iterable)
Finalizer Tasks
A finalizer task is a task that will be scheduled to run after the task that requires finalization, regardless of whether the task succeeds or fails.
task a { ... }
task b { ... }
a.finalizedBy b
Implicit Dependencies
Task Inputs and Outputs
Gradle determines whether a task is up to date if the task's inputs and outputs have not changed since the last execution, by comparing their values with those preserved in the build cache. Does the build cache need to be enabled for inputs and outputs to be relevant?
If the input and output snapshots are identical to the previous ones, the task is not executed. An input can be a property, a directory or one or more files. An output is a directory or one or more files. Inputs and outputs are fields of the DefaultTask class. Task inputs and outputs are obtained with Task.getInputs() and Task.getOutputs(), which return TaskInputs and TaskOutputs instances, respectively.
Task inputs and outputs are evaluated during the configuration phase to wire up the task dependencies. That is why they need to be defined in a configuration block. To avoid unexpected behavior, make sure that the value you assign to inputs and outputs is accessible at configuration time. If you need to implement programmatic output evaluation, the method upToDateWhen(Closure) on TaskOutputs comes in handy. In contrast to regular inputs/outputs evaluation, this method is evaluated at execution time. If the closure returns true, the task is considered up to date.
Debug a Java compilation task to see how input/output works.
Annotations
@Input
⚠️ Note that in Java, the annotation must be attached to the getter method. Annotations on setters or just the field in Java are ignored.