Settings.gradle: conditional inclusion of subprojects

Hi
I am runing a native gradle build that contains some application modules, each module having additional subproject like testunit and sample. The overall build is taking 30mn and I would like to reduce on demand this build time with a command line parameter by excluding for example the unittest and the samples. Is there a way to exclude subprojects from the settings.gradle like the one proposed below?

BUILD SUCCESSFUL in 29m 59s
556 actionable tasks: 544 executed, 12 up-to-date

settings.gradle:

println 'This is executed during the initialization phase.'
rootProject.name = 'Poco'

include ':CppUnit'
include ':Foundation'
include ':XML'
include ':JSON'
include ':Util'
include ':Net'
include ':Crypto'
include ':NetSSL_OpenSSL'
include ':NetSSL_Win'
include ':Data'
include ':Data:ODBC'
include ':Data:SQLite'
include ':Data:MySQL'
include ':Data/PostgreSQL'
include ':Zip'
include ':PageCompiler'
include ':PageCompiler:File2Page'
include ':PDF'
include ':CppParser'
include ':MongoDB'
include ':Redis'
include ':PocoDoc'
include ':ProGen'

if (doTestSuite) {
include ':Foundation:testsuite'
include ':XML:testsuite'
include ':JSON:testsuite'
include ':Util:testsuite'
include ':Net:testsuite'
include ':Crypto:testsuite'
include ':NetSSL_OpenSSL:testsuite'
include ':Data:testsuite'
include ':Data:ODBC:testsuite'
include ':Data:SQLite:testsuite'
include ':Data:MySQL:testsuite'
include ':Data:PostgreSQL:testsuite'
include ':MongoDB:testsuite'
include ':Redis:testsuite'
include ':CppParser:testsuite'
include ':Zip:testsuite'
}
if (doSample) {
include ':Foundation:samples'
include ':Data:samples'
include ':JSON:samples'
include ':MongoDB:samples'
include ':Net:samples'
include ':PageCompiler:samples'
include ':PDF:samples'
include ':Util:samples'
include ':XML:samples'
include ':Zip:samples'
}

IIRC, the params specified by -P on the command line can be accessed via the map startParameter.projectProperties.

https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html#org.gradle.api.initialization.Settings:startParameter

I wouldn’t conditionally include subprojects like this because it makes it harder to tell which parts of the build are active at any given time (e.g., you can’t just run gradle projects or gradle components or gradle tasks and have a definitive list).

If you’re running gradle assemble and it takes a long time because it builds extra projects like testunit and sample, you may just want to have a gradle assembleProduction that only builds “production” sources (not any of the tests or samples).

2 Likes

I have some trouble to choice the best way to implement this assembleProduction task. Would you mind to give me sample or a template I could follow?. TIA

The idea would be to have something like this in your root project:

task assembleProduction {
   dependsOn subprojects.filter { isProduction(it) }.collect { it.path + ":" + assemble }
}

Where isProduction is a method that can decide if a subproject is production or not. This is OK if there isn’t any hierarchy to the project, IOW, you don’t expect to cd to a subproject and run assembleProduction and only build production projects from that subproject and below.

The other way would be to have a plugin that adds a assembleProduction task (which could be as simple as task assembleProduction { dependsOn "assemble" }), but only adds the task if it’s applied to a “production” project.

In that case, you could run assembleProduction from anywhere and it would find any tasks matching that.

1 Like

Thanks for your detailled solution and explanation. I like it.

I have been using the following and it seems easier to me.

Whatever you have in gradle.properties file is available as a String property in settings.gradle

So let’s say you have the following line in gradle.properties

enableAdditionalModules=true

Then in settings.gradle, you can have

if (enableAdditionalModules.toBoolean()) {
   include 'additionalModule1', 'additionalModule2'
}