Nested multiproject setup with multiple settings.gradle files

Hi,

Greetings. I’m trying to setup a Multiproject in a nested way and would like to look for suggestions on this. Let’s say we have a large directory layout abstracted as following:

gandon@gandon-laptop:~/test-workspace/gradle$ tree rootDir
rootDir
|-- common
|-- teamA
|   |-- common
|   |-- component1
|   |   `-- subcomponent
|   `-- component2
`-- teamB
    `-- componentFoo

We want to be able to build at any level, and only build the things enclosed in this dir (possibly also other dependent subprojects like ‘common’). We initially made it as a standard gradle multiproject, where a single settings.gradle file is located under ‘rootDir’ declaring all the sub-projects. Under each sub-project dir, we have build.gradle file for it to build the sub-project, and so forth.
This works as expected - except that

  • All sub-project declarations are in a centralized settings.gradle file in the rootDir.
  • It has to go over all project configurations even if we are only building a tiny leaf node.

We want each team/comonent to own their part and be self-contained with all the build/config logic located in its own directory. So ideally we would like a single settings.gradle file in different team/components, so that when a component’s structure changes, it does not need to modify the root settings.gradle file. But Gradle does not support multiple settings.gradle files, at least for now. Also, when it scales it would be slow to go over all projects to build a just small part of it - even with config-on-demand feature enabled. So ideally we would prefer to have a nested, self-contained multi-project model instead of current flattened, centralized model. Is this even possible in Gradle? Or would a custom plugin be able to do this?

I did find a similar topic at Multiple settings.gradle files in a multi-project build, but I did not find any answer to it.

Any input from you will be appreciated.

Thanks,
Gan

If you list all projects in settings.gradle then the default behavior is that all projects would have to be configured. The time spent during the configuration phase will improve over time with the new configuration model.

Another option would be to make teamA and teamB separate multi-project builds with their own settings.gradle. The only shared module you’d need would be the common module. Depending on how frequent the code of common changes, you could publish its binary artifact and refer to it from teamA and teamB by declaring an external module dependency.

You might also want to think about breaking up the single source tree by team. As far as I understand your scenario, developers usually work on team A or B but most of the times not on both teams. Having the code in separate VCS repositories also helps clarify project boundaries. The common module would then live in its own VCS repository as well. The downside is that shared modules would have to be published. In the long run we want to provide a hybrid approach by substituting module dependencies by project dependencies and vice versa (even if the code lives in different VCS repositories). This work has been started with 2.5. Please refer to the release notes for more information.

Hi Benjamin,

Thanks for the reply.

Sorry, I have incorrectly described our scenario - currently we’ve already setup a multi-project per each team as you suggested. The structure should be better described as

teamA/
|-- common
|-- component1
|   `-- subcomponent
`-- component2

What I intended to ask is to have multiple settings.gradle files in component and subcomponent level, but still can build at teamA level as a whole project. Would custom plugins be able to do this?

Thanks,
Gan

Maybe I am misunderstanding your question but I don’t think you actually need multiple settings files to make this work for teamA. If component is part of the multi-project build simply say gradle :component:build. If you want to just build subcomponent, say gradle :component:subcomponent:build. You should also be able to build everything with gradle build.