Task Configuration Avoidance example

Hello,

When reading the Task Configuration Avoidance page, I read bullet 2, which provides this example:

def check = tasks.register("check")
def verificationTask = tasks.register("verificationTask") {
    // Configure verificationTask
}
check.configure {
    dependsOn verificationTask
}

Since I have started to migrate to tasks.register, I ran into this issue when trying to depend on an existing task, which may or may not have been defined.

tasks.register throws an exception if the task is already registered, and tasks.named throws an exception if a task is missing.

There are methods to retrieve an optional Task by name (getByName), but not to retrieve an optional TaskProvider, which I must assume means that the task will be configured eagerly.

I have found a protected method in DefaultNamedDomainObject called findDomainObject, that does the trick, but in an unintended way.

Is there any known way to retrieve an optional TaskProvider instead of an optional Task?

An example to clarify from

def assembleTask = tasks.findDomainObject("assemble")
def helloTask = tasks.register("hello") {
    doLast {
        println "Hello world"
    }
}

assembleTask?.configure {
    dependsOn helloTask
}

If the assemble task may not exist in your case, then you could do something like:

def helloTask = ...
tasks.configureEach {
    if( it.name == "assemble" ) {
        it.dependsOn( helloTask )
    }
}

The closure passed to configureEach should only be called for tasks being realized.

Actually, you usually either apply the plugin that adds the task that you want to configure so you know it exists,
or you react to the plugin being applied.
In case of the assemble task, that would be the lifecycle-base plugin.
So you could apply the lifecycle-base plugin (or another plugin that applies it implicitly which should be basically all built-in plugins) and be sure the task exists.
Or you react to it being applied using pluginManager.withPlugin("lifecycle-base") { ... } and know the task is already registered when the closure is executed.

That makes sense, thanks. I tried both of the solutions out and they both worked like a charm,

I’ll stick with @Vampire 's advice whenever I can, since it seems to be decent in concept.

However, I would still add that having a

tasks.withName(‘assemble’)

That returned an optional provider and/or task seems most intuitive to me.

This is the issue you want to follow for that: Introduce `TaskContainer.maybeNamed` · Issue #8057 · gradle/gradle · GitHub