I always thought that the input snapshot (the one that’s persisted between gradle invocations) is taken before task execution and the output snapshot is taken after task execution. However, I have an example that seems to contradict this assumption.
class FooTask extends DefaultTask {
@Input
def props = [:]
@TaskAction
def run() {
println "Executing FooTask"
}
}
task foo(type: FooTask) {
outputs.upToDateWhen { true }
doFirst {
props['fruit'] = 'cherry'
}
}
$ ./gradlew :it:foo :it:foo Executing FooTask BUILD SUCCESSFUL Total time: 3.613 secs"foo" will never be considered UP-TO-DATE. However, if I get rid of doFirst or clear the property in doLast, "foo" can be UP-TO-DATE.
If input snapshots are persisted BEFORE task execution, I don’t understand why that’s happening. However, if input snapshots are persisted AFTER, then it makes sense:
- First run. There’s no history. Input and output snapshots are taken and persisted after task execution. Input snapshot contains the “fruit” property. 2. Second run. Before task execution, a snapshot of the inputs is taken. It does not contain the “fruit” property, and as a result, gives a different hash than the snapshot taken at the end of the last run. So, task is not UP-TO-DATE. 3. Repeat step 2 ad infinitum. Task is never considered UP-TO-DATE.
Is my reasoning correct? If not, what is causing this behavior?