Reputation: 2947
Consider the following Gradle project structure:
- root
|- build.gradle
|- barProject
|- build.gradle
|- fooProject
|- build.gradle
where the root build.gradle configures its subprojects like so:
subprojects {
apply plugin: 'java'
//bunch of other stuff
}
Now when I call gradlew build
on the root project it automatically configures both subprojects and then builds them - all well and good.
I also know that I can skip a specific task with various means (onlyIf()
, [taskName].enabled = false
, etc.) but when I utilize any of those on build
Gradle still runs all the dependent tasks (compileJava
, processResources
, classes
, etc.) until finally hitting build
which it then skips.
My question is, is there any way to have Gradle stop and go to the next subproject right after the configuration phase?
EDIT:
To clarify; each subproject has a property called skip
that is evaluated in the configuration phase.
Now when I call gradlew build
on the root project I want Gradle to, ideally, check that property and if it's true then to completely skip the corresponding project.
Executing external task 'build'...
//check project.skip -> IF true -> skip project, go to :foo ELSE continue
:bar:compileJava
:bar:processResources UP-TO-DATE
:bar:classes
:bar:jar
:bar:startScripts
:bar:distTar
:bar:distZip
:bar:assemble
:bar:compileTestJava UP-TO-DATE
:bar:processTestResources UP-TO-DATE
:bar:testClasses UP-TO-DATE
:bar:test UP-TO-DATE
:bar:check UP-TO-DATE
:bar:build
//check project.skip -> IF true -> skip project, go to end ELSE continue
:foo:compileJava
:foo:processResources UP-TO-DATE
:foo:classes
:foo:jar
:foo:startScripts
:foo:distTar
:foo:distZip
:foo:assemble
:foo:compileTestJava UP-TO-DATE
:foo:processTestResources UP-TO-DATE
:foo:testClasses UP-TO-DATE
:foo:test UP-TO-DATE
:foo:check UP-TO-DATE
:foo:build
BUILD SUCCESSFUL
I hope this makes more sense
Upvotes: 2
Views: 8558
Reputation: 14493
Well, first of all: An easy solution would be calling exactly the task(s) you need. In simple Gradle builds, task names are unique. However, in multi-project builds, each project can have a task with a specific name. This is the reason why Gradle introduced task paths. Task paths combine the unique project paths with the intra-project unique task names: :projectX:taskY
.
Using project paths, you can easily specify the project-specific task you want to execute: :build
for the build
task in the root project and :<subproject>:build
for the build
task in a subproject. If a task name, e.g. build
, is provided for a multi-project build, Gradle will search through any project (root and subs) for a task with the specified name and execute them all. This explains the current behaviour.
The task names for execution are managed by a StartParameter
object of the Gradle Settings
. These Settings
can be modified in your settings.gradle
file, where you also include subprojects:
include ':foo', ':bar'
startParameter.excludedTaskNames += ':foo:build'
This line excludes the build
task of the foo
subproject from the execution. You could add the subproject task path (even independent from the task name) to the excluded task names, if a specific condition is met. But, I did not find a way to access the Settings
in your build file, so this solution can not be used during configuration phase. However, if your condition is solely based on project / system properties, they can be accessed from settings.gradle
.
Another solution for the configuration phase came to my mind, but it's basically what you already mentioned, because it simply skips the tasks:
if (project.skip) {
project.tasks.all { task -> task.enabled = false }
}
This way, all tasks from the project (not only the build
task) will be skipped.
Please consider, that tasks can also be executed, because they create a dependency for another project. Even gradle :bar:build
will execute the task :foo:jar
and its task dependencies, if foo
is a project dependency of bar
. You can disable this behaviour with the Gradle command line options -a
or --no-rebuild
or the following entry in your settings.gradle
:
startParameter.buildProjectDependencies = false
Upvotes: 4