Root project's 'clean' task does not clean subprojects?


(lu.shunshun) #1

I’ve got a multiproject build and one of the task (say ‘si’) in root project which needs to clear everything first. So I added a dependency on the ‘clean’ task to ‘si’ task and I thought it will clean everything including subprojects. The task declaration looks something like below:

task('si', dependsOn: clean)

This is defined in the root build script. I’m expecting it does the same thing as executing gradle clean on the command line but it turns out it’s not. It actually only cleans the ‘build’ folder of the root project leaving all the subproject untouched.

I had to reconfigure the ‘clean’ task of the root project to depends on the ‘clean’ tasks of all the subproject.

clean {
    subprojects.each {
        it.afterEvaluate {
            def cleanTask = it.tasks.findByName('clean')
            if (cleanTask) {
                dependsOn(cleanTask)
            }
        }
    }
}

Even though this solution works, I still want to understand why dependsOn: clean does not work the same way as gradle clean on the command line? Are they really two different things which just happen to have the same name (which is really confusing and counter intuitive)? Or am I missing something here?


(Mark Vieira) #2

Running the task ‘clean’ from the command line does behave a bit differently. Essentially the CLI will attempt to run that task for any and all projects in your multi-project build. When you depend on clean you are depending on the task from that project. You will have to indeed depend on the task from all subprojects. You can make this a bit cleaner though, I wouldn’t change the behavior of the root ‘clean’ task. Rather make the ‘si’ task depend on the ‘clean’ task from every subproject.

task si {
    dependsOn subprojects.collect { it.tasks.matching { it.name == 'clean' } }
}

(lu.shunshun) #3

Thanks for the clarification Mark! I’ll watch out for this in the future.

I’ve tried out your suggestion by changing subprojects to allprojects (because I want it to clean everything just like running gradle clean) but it doesn’t seem to do anything. I’ve reverted the clean task of the root project so it doesn’t depends on all subprojects and the build becomes something like below:

//clean {
//    subprojects.each {
//        it.afterEvaluate {
//            def cleanTask = it.tasks.findByName('clean')
//            if (cleanTask) {
//                dependsOn(cleanTask)
//            }
//        }
//    }
//}

task si {
    dependsOn allprojects.collect { it.tasks.matching { it.name == 'clean' } }
}

When I run the si task, it just says:

Incremental java compilation is an incubating feature.
:si UP-TO-DATE

BUILD SUCCESSFUL

Nothing has been cleaned really (neither the root project nor any of the subprojects). It works for dependsOn subprojects.collection { ...} but this doesn’t clean the root project. So am I missing something here?

I’m using Gradle 2.8 btw


(Janek) #4

Sorry for reviving an old thread, but I have the same issue and tried your fixes. But for me, it doesn’t even find a clean task for the subprojects, which is really weird, since there certainly is one…


(lu.shunshun) #5

WOW… this is old.

Does it work if you just run “clean” task on the subproject?