Understanding the execution and configuration phases

I want to write a build.gradle that resembles the following DAG:

rebuild -> clean -> build -> jar

This is what I have in my build.gradle:

task build (dependsOn: ‘jar’) { }

task rebuild (dependsOn: ‘clean’) { }

task clean (type: Delete, dependsOn: ‘build’) {

delete ‘test.jar’ }

task jar (type: Jar) {

from ‘src’

archiveName = ‘test.jar’ }

When I run ‘build’, it behaves as expected. It will create the jar if it does not exist. Any subsequent calls to ‘build’ does not create a new jar since the jar has not been modified. However, if I run ‘rebuild’, I can see that the jar is deleted but it is never rebuilt. I feel like I am missing some information about the execution and configuration phases. From what I have read, the dependsOn relationship affects the execution phase. Is there any way to manipulate the configuration phase or a way to translate what I have so that I can control it in the execution phase? I’ve tried adding doLast and doFirst but it does not behave as I would want it to.

‘rebuild’ is more of a workflow, and workflows cannot be easily modelled with Gradle’s (non-conditional) task relationships alone. (It’s also a goal of Gradle to make ‘clean’ unnecessary.) To implement ‘rebuild’ for a single-project build, you could perhaps do:

rebuild.dependsOn(clean, build)
tasks.matching { it.name != "clean" }*.mustRunAfter(clean)

‘clean.dependsOn(build)’ seems wrong in any case. Why would you first build and then clean?

Thanks for the quick reply.

As for your question, you’re right. I would never want to do that. I am still trying to get an understanding about how to chain tasks together. Is there any other way to chain them aside from mustRunAfter or dependsOn? Is there a way to call a task the same way you call a function? On the same topic, what’s the best practice to pass arguments to different tasks?

There is ‘dependsOn’, ‘mustRunAfter’, ‘shouldRunAfter’, and ‘finalizedBy’. Tasks cannot be called like functions. Some built-in task types support task parameters. For all other task types, the build script configuring the task would typically query a system or project property, which can be passed with ‘-D’ or ‘-P’, respectively.

Ah I see. Thanks for your help!

I guess this is not something one should do often, but it is possible to call a task x with x.execute(). This will loose some of the functionality that the task have when run properly, though.

Note that ‘TaskInternal#execute’ is an internal method, and is not intended to be called from build scripts. The effects of doing so are unspecified.

That is good to know…thanks! Need to see what I can do with my usages of this in my build scripts, then.