Executing tasks by name on multi-project and dependency

As per documentation describing the task execution matching in Multi-Project Build Basics :

The command gradle test will execute the test task in any subprojects relative to the current working directory that has that task.
If you run the command from the root project directory, you will run test in api, shared, services:shared and services:webservice.
If you run the command from the services project directory, you will only execute the task in services:shared and services:webservice.
The basic rule behind Gradle’s behavior is to execute all tasks down the hierarchy with this name. And complain if there is no such task found in any of the subprojects traversed.

I get the expected behaviour if I execute directly the targeted task that share the task name accross projects/subprojects.
What I also expected was that a dependent task that is being executed through dependency would also execute the said task in subprojects, but it does not to seem to be the case.
Dummy example in root project build gradle:

tasks.sonar.configure {
    dependsOn(tasks.test)
}

Executing sonar on root project will not trigger the test tasks in subprojects.
Is it the expected behaviour? And what is the correct way to handle this if I want to trigger all test tasks in subprojects?

Yes, that’s exactly the expected behavior.
Referring to tasks.test is like calling :test or :shared:test from the commandline, referring only to that exact task.
Only from commandline when you have a task without path the magic matching logic kicks in.

To achieve what you want, you could for example do

tasks.sonar {
    allprojects.forEach {
        dependsOn("${it.path}:test")
    }
}

but only if you are sure that all projects have a task with name test.

1 Like