gradle-plugins-howto
gradle-plugins-howto copied to clipboard
When to use another composite build or another project?
Thanks a lot for the fantastic Gradle resources!
I'm moving from a single build.gradle.kts file to a proper setup, primarily to ensure a growing team has a better time building plugins and that everyone can quickly add a new subproject to the repository without a lot of duplication.
One question that comes up is where to put the plugin implementation. Let's assume we're writing our plugins as Kotlin classes, e.g., MyPlugin.kt. Let's also assume our goal right now is to have at least the following plugins:
- Kotlin base plugin
- Java base plugin
- Android library plugin
- Android app plugin
- Miscellaneous "meta" plugins to analyze a project, its dependencies and the likes
I'm following what you outline in gradle-project-setup-howto, but I'm starting to wonder if I need to have multiple composite builds and multiple projects inside of each one. We won't have multiple Android app plugins as seen in your how-to repo, for example. At least for the near future.
Let's take the Android library and Android app plugins as an example. What pros and cons drive the decision on whether we should go with any of these setups (or another one I didn't come up with)?
- Two composite builds. Each build consists of a single project. Each project contains only a single plugin.
- One composite build that contains two projects. Each project contains a single plugin.
- One composite build that contains one project. The project contains both plugins.
The obvious (to me) question to drive a decision on how to structure things is whether the plugin is owned by another team or generally worked on independently. In that case, a composite build can be beneficial. However, I'm sure there is more to it. For example, perhaps my Android app project builds faster if it applies my Android app plugin that is isolated even from my Android library plugin? Do the same concerns apply to a team that uses a mono-repo and owns their plugins (no other team involved) and won't publish them either?
tl;dr: Why should or shouldn't I put all my plugins in a single composite build that only has one project inside? This is what Now In Android seems to use.
That's a good question @bddckr.
There are two concerns I would say:
- Sometimes it is technically necessary to have multiple separate builds. This is the case, when you further want to "stack" things. For example, when you want to reuse the same settings plugin for your main build and your gradle plugins build - e.g. to share repositories (like here).Or when you want to write tasks that do something with the gradle plugins themselves (like this PluginApplicationOrderAnalysis task).
- Everything else is conceptually - how do you want to structure your software? Where in this case the "software" is your build system/setup. (The structuring may have some performance impact on the compilation time of the plugins while you work on them, but in most cases this can be neglected; and for the users (who don't change plugin code) it does not matter.)
So regarding 2, I think it depends on how large your project grows and also personal/team preference. In general, it's good to put single concerns into single plugins (i.e. separate files). This can be files in just one project like nowinandroid is doing it. If you split it up into multiple projects, you have the same advantages/disadvantages you get when you split up your Java/Kotlin/Android project:
- Bit more boilerplate
- More isolated components: At compile time, you can hide dependencies to some of your plugins which makes it easier to enforce a certain structure
- Any other advantages that isolated components can bring (better overview, easier to get into for new folks, etc...)
In gradle-project-setup-howto I chose to split it up along the different aspects I think a JVM build has to cover most of the time. These are what is described in the Readme (and which I summarized here). There, for example, only my dependency rules plugins can see the external rules plugins – see build.gradle.kts - while these external plugins (implementation details) are hidden to other plugins.
I think it's valuable to do this split up if you anticipate that the configuration might grow larger. But if not, a concise list of plugins in one project also has advantages for the overview. I did/do both in different projects I help in depending on the size of the project and the customization demands they have for the build system.
Thanks a lot for this detailed response!
As I started implementing my plugins, I noticed the need for (1) simply because you want one of your plugins to use another. So that matches what you just said.
The fact that the build system itself is just another standalone software project made (2) click for me. It's all about the same pros and cons we usually encounter in the "actual" software project. 👍
Again, thanks a lot for the various repositories and your YouTube channel. 👏
Feel free to close this "issue" if that works best for this repo - my questions are answered now.