Reputation: 13
I have the following project structure correctly found by gradle:
$ ./gradlew projects
Root project 'test-project'
\--- Project ':sub-1'
\--- Project ':sub-1:sub-2'
Which makes me believe that my setups is correct.
Now, I have found that the following gradle syntax:
$ ./gradlew clean :sub-1:build
is not equivalent to:
$ cd sub-1
$ ../gradlew clean build
$ cd ..
The above is equivalence is stated in many places on the gradle website. Like HERE
Running the former, the result is incorrect:
> Task :sub-1:test
test.project.LibrarySuite > someLibraryMethod is always true PASSED
Running the latter, the result is correct:
> Task :sub-1:test
test.project.LibrarySuite > someLibraryMethod is always true PASSED
> Task :sub-1:sub-2:test
test.project.LibrarySuite > someLibraryMethod is always true PASSED
Please help me understand if I might have assumed or done anything wrong, or if it's a bug that should be raised to the gradle team.
Upvotes: 1
Views: 1963
Reputation: 12096
You will find detailed description of how Gradle handles execution of tasks in a multiproject build setup here : https://docs.gradle.org/current/userguide/intro_multi_project_builds.html#sec:executing_a_multiproject_build , specially:
From a user’s perspective, multi-project builds are still collections of tasks you can run. The difference is that you may want to control which project’s tasks get executed. You have two options here:
Change to the directory corresponding to the subproject you’re interested in and just execute gradle as normal.
Use a qualified task name from any directory, although this is usually done from the root. For example: gradle :services:webservice:build will build the webservice subproject and any subprojects it depends on.
The first approach is similar to the single-project use case, but Gradle works slightly differently in the case of a multi-project build. The command gradle test will execute the test task in any subprojects, relative to the current working directory, that have that task. So if you run the command from the root project directory, you’ll run test in api, shared, services:shared and services:webservice. If you run the command from the services project directory, you’ll only execute the task in services:shared and services:webservice.
This explains how Gradle behaves in the two examples you gave in your question :
$ ./gradlew clean :sub-1:build
from the root project directory: you execute task clean
, which will be executed for current project and each subprojects below, then :sub-1:build
(with qualified task name) which executes build
tasks ONLY for subproject sub1
Gradle execution log:
> Task :clean UP-TO-DATE
> Task :sub-1:clean
> Task :sub-1:sub-2:clean UP-TO-DATE
> Task :sub-1:compileJava NO-SOURCE
> Task :sub-1:processResources NO-SOURCE
> Task :sub-1:classes UP-TO-DATE
> Task :sub-1:jar
> Task :sub-1:assemble
> Task :sub-1:compileTestJava NO-SOURCE
> Task :sub-1:processTestResources NO-SOURCE
> Task :sub-1:testClasses UP-TO-DATE
> Task :sub-1:test NO-SOURCE
> Task :sub-1:check UP-TO-DATE
> Task :sub-1:build
EDIT to answer @Guido's comment: this will also build any other projects sub-1
depends on, so ./gradlew clean :sub-1:build
will also trigger build of sub-2
if sub-1
project dependsOn sub-2
:
sub-1 build.gradle
dependencies {
implementation project(":sub-1:sub-2")
}
$ cd sub-1 && ../gradlew clean build
From sub-1
subproject directory , you trigger tasks clean
then build
, without using qualified names, so these two tasks will both be executed on current project and sub-projects` :
Gralde output:
$ ../gradlew clean build --console=plain
> Task :sub-1:clean
> Task :sub-1:sub-2:clean
> Task :sub-1:compileJava NO-SOURCE
> Task :sub-1:processResources NO-SOURCE
> Task :sub-1:classes UP-TO-DATE
> Task :sub-1:jar
> Task :sub-1:assemble
> Task :sub-1:compileTestJava NO-SOURCE
> Task :sub-1:processTestResources NO-SOURCE
> Task :sub-1:testClasses UP-TO-DATE
> Task :sub-1:test NO-SOURCE
> Task :sub-1:check UP-TO-DATE
> Task :sub-1:build
> Task :sub-1:sub-2:compileJava NO-SOURCE
> Task :sub-1:sub-2:processResources NO-SOURCE
> Task :sub-1:sub-2:classes UP-TO-DATE
> Task :sub-1:sub-2:jar
> Task :sub-1:sub-2:assemble
> Task :sub-1:sub-2:compileTestJava NO-SOURCE
> Task :sub-1:sub-2:processTestResources NO-SOURCE
> Task :sub-1:sub-2:testClasses UP-TO-DATE
> Task :sub-1:sub-2:test NO-SOURCE
> Task :sub-1:sub-2:check UP-TO-DATE
> Task :sub-1:sub-2:build
Upvotes: 1