Update task finalizedBy after task graph ready?

(Mark E. Scott, Jr.) #1

I have three tasks:

  • DoSomeStuff
  • PublishResults
  • Cleanup

The DoSomeStuff has a finalizeBy ‘Cleanup’ command. This works fine.

I also want the same thing for “PublishResults”, but I only want to do this if PublishResults was set to execute already. I.E. if the developer has decided he wants to publish results, it will do it even if DoSomeStuff ends up failing.

I tried adding a block of code that executed when the task graph was ready, and used graph.hasTask(‘PublishResults’) and if that returned true, executing finalizedBy(‘PublishResults’).

In this case, it is obvious that once the task graph is ready, it has no effect. Is there another way to accomplish this?

I really want to avoid running PublishResults, because it is not used often by developers, but by a build agent. Today, I have to add the finalizedBy statement statically, which means I have to have the developers tell Gradle to skip that PublishResults task (-x PublishResults).

The only other option I have come up with is to use an onlyIf block, and do this based on a property, that is false by default, and the user can override when necessary.

(Daniel Lacasse) #2

Hi Mark,

I’m not sure if I understand correctly. Could you simply have

DoSomeStuff.finalizedBy "PublishResults", "Cleanup"
Cleanup.mustRunAfter "PublishResults"

It should ensure that both tasks - PublishResult and Cleanup - runs after DoSomeSuff, and Cleanup runs after PublishResults.

I hope this answer your questions,


(Mark E. Scott, Jr.) #3

Apologies for the confusion.

What you suggest certainly works, and ensures that cleanup runs after PublishResults. However, this will force PublishResults to be added to the task graph to run, even if the developer isn’t publishing.

I wanted the PublishResults task to only be added as a finalizer if it was explicitly asked for by the developer/build agent. The goal is that if they wanted to publish results, I wanted that to happen regardless if some other task later failed.

(James Justinic) #4

I’m not entirely clear on what you’re saying a developer would ideally have done to indicate that he decided to publish results. However, if it is good enough to say that a developer wants to publish results only if he explicitly lists the “PublishResults” task (and not a dependency of it, if there is one), you can programmatically use or manipulate the StartParameter configuration, in addition to the suggestion by @Daniel_L .

The “PublishResults” task will be added to the task graph regardless, but you can still use the enabled property to control whether or not the task executes or is SKIPPED:

task PublishResults {
    enabled = project.gradle.startParameter.taskNames.contains(it.name)
    doLast {
        println "publishing results..."

Alternatively, you can set the same effective value as when you manually have developers skip the task with the “-x PublishResults” argument. In this case, you will not see the task show up as SKIPPED in the lifecycle logging:

if (!project.gradle.startParameter.taskNames.contains("PublishResults")) {
    project.gradle.startParameter.excludedTaskNames += "PublishResults"

(Daniel Lacasse) #5

I would have suggested something similar to @jjustinic. The information in startParameter contains the task name as entered on the command line. This means if you enter PubRes or any variant, the task will be executed but you won’t detect it with startParameter.taskNames.contains(it.name). You can work around this with some code without problems.