upToDateWhen will not prevent task from running the first time


(Justin Ryan) #1

Per the docs for TaskOutputs (http://www.gradle.org/docs/current/javadoc/org/gradle/api/tasks/TaskOutputs.html#upToDateWhen(groovy.lang.Closure)), it says “The task outputs are considered out-of-date when any predicate returns false.” Yet, it appears that the first time I run a task it ALWAYS out-of-date, irrelevant of what my upToDateWhen closure says. Here’s a sample project that creates tasks in two ways:

import org.gradle.api.Plugin
import org.gradle.api.Project
  class SomePlugin implements Plugin<Project> {
      @Override
    void apply(Project project) {
        def task = project.task("echo") {
            doLast {
                println "I ran!"
            }
        }
        task.outputs.upToDateWhen {
            return true
        }
      }
}
  apply plugin: SomePlugin
  task run << {
    println "I run!"
}
run.outputs.upToDateWhen { true }

I ran these commands for Gradle 1.9 and 1.11:

> rm -fr .gradle
> gradle echo run
  :echo
I ran!
:run
I run!
  BUILD SUCCESSFUL
  Total time: 0.684 secs

On the second run, the upToDateWhen check is respected and the tasks are considered UP-TO-DATE. Is this a bug? Does the documentation need to be changed? My concern is if my task is interacting with an external service (maybe in a destructive way) and I’m doing a complex up to date check, yet it’s being ignored forcing a expensive task to run for no need. It also makes it hard to test my own tasks.


(Peter Niederwieser) #2

You seem to be looking for a ‘task.upToDateWhen’ feature (which is different from ‘task.outputs.upToDateWhen’), and it seems that you don’t need to take inputs into account. How about using ‘task.onlyIf’ for this?


(Justin Ryan) #3

I don’t see any docs for a upToDateWhen function on DefaultTask, can you point me to the docs?

My simple example was to make it clear how to reproduce. I agree that onlyIf has applicability, but my point was that the docs don’t match the behavior.


(Peter Niederwieser) #4

What I was trying to say is that the docs are for ‘task.outputs.upToDateWhen’, which isn’t the same as the task itself being up-to-date. There isn’t currently a ‘task.upToDateWhen’ method. It’s a built-in algorithm that (at least) considers whether inputs have changed, whether outputs have changed, and whether the task has run before.