I have a gradle Copy task that copies assets from the project directory into the build directory:
tasks.register("copyAssets", Copy) {
def fromDir = "${project.projectDir.toString()}/../assets"
def toDir = "${project.buildDir.toString()}/assets"
println "Copying assets"
println " from $fromDir"
println " into $toDir"
from fromDir
into toDir
}
build.dependsOn copyAssets
run.dependsOn copyAssets
This works, but somehow it not only runs on build and run, but also on clean.
If I remove both lines with dependsOn, it doesn't run on build, run, or clean. But as soon as I put the line with build.dependsOn in, the task runs on build, run, and clean. If, on the other hand, I remove build.dependsOn and put in run.dependsOn instead, the outcome is the same: The task runs on build, run, and clean.
How does dependsOn work? How can I make it to run on build and run, but not on clean?
I use gradle wrapper, and it's a multi-module project, i.e.
./gradlew main:clean
./gradlew main:build
./gradlew main:run
The task is in the main module only, not inside the top-level build.gradle.
Interesting question, as it mixes two of the most common mistakes or confusion made when using Gradle:
Task configuration vs execution phase
Lots of SO questions are dealing with this topic , just search "configuration vs execution phase" for answers explaining this in details. One example : Gradle always does println from any task
In your example: you say that
copyAssetstask is also executed when runningcleantask but in fact it's not executed, it's just configured.Executing
gradle build:Executing
gradle clean:You can check that when calling
clean, you assets will not be copied, you will just see the println in console. Note that you will also see these println when executing any other task ( e.g.gradle help,gradle tasks...)Task configuration avoidance issue
You are declaring your task using the
registerAPI, which enables Task configuraiton avoidance feature. So, in theory, thecopyAssetsshould be configured only if it must be executed (=> only when you invokebuildorruntasks in your example)So why is it configured (but not executed) when executing
cleanin your example ?This is due to the way you are declaring the tasks dependencies , as explained in the Task configuration avoidance pitfalls section/
=> this will eagerly create and configure the
buildtask, and in cascade will also create and configure the dependentcopyAssetstask.There are several ways to fix this, given in the link above. One example: