How can I share code / properties / settings in settings.gradle.kts, gradle.properties, and possibly other gradle files between projects?
I know how to share code for build.gradle.kts between projects by creating a conventions plugin, then applying it then plugins block in each of my projects’ respective build.gradle.kts file, but I don’t know how best to share code, etc. amongst projects for other files.
e.g., I might want all of my projects to enable the same gradle feature previews (done in settings.gradle.kts), to fail on any warning (org.gradle.warning.mode=fail in gradle.properties), etc.
For code in settings scripts, the answer is the same as for build scripts, write a convention plugin.
If you write them as binary plugin, implement Plugin<Settings> instead of Plugin<Project> or if you need one that is applicable to both (actually all three as you can also write init script plugins), Plugin<PluginAware>.
If you write them as precompiled script plugins, name it foo.settings.gradle.kts to write one for settings scripts instead of foo.gradle.kts which is for build scripts.
The warning mode I don’t think you can centralize, except by using a custom Gradle distribution. Or if you just want this for yourself when running any build, put it to <GRADLE_USER_HOME>/gradle.properties.
The convention plugin docs don’t mention foo.settings.gradle.kts. It would probably be good to add this info there so people will get the answer straight from the docs.
This is something Kotlin DSL specific, as Groovy DSL script are duck-typed anyway.
Thus, it is documented on the Kotlin DSL documentation page: Gradle Kotlin DSL Primer
Also, it is not really about convention plugins, but about precompiled script plugins.
Convention plugins can be developed in any JVM language and as precompiled script plugins, binary plugins, or whatever.
But it is also not mentioned on the precompiled script plugins page.
As Kotlin DSL is now promoted as default DSL, I agree that at least the precompiled script plugins page should maybe mention it.
I’d recommend you open a feature request issue or PR to improve the docs.
It looks like the settings conventions (for settings.gradle.kts) must be in a separate plugin from the build conventions (for build.gradle.kts).
My conventions plugins are all in one project. Their users are in other projects. All of the projects (conventions plugin project & projects that use it) are included builds in an overarching composite build.
build.gradle.kts finds its conventions plugin just fine (only had to apply it in the plugins block).
settings.gradle.kts can’t find the settings conventions plugin that I applied in the plugins block.
The error message mentioned that the plugin wasn’t found in any included builds or plugin repositories.
I’ve verified that the built conventions project has class files for both plugins under build/classes/kotlin/main where:
Why does this work for build.gradle.kts but not for settings.gradle.kts?
I’m not sure how to fix this, either via pluginManagement or some other mechanism.
I tried directly including the conventions plugin project in the project trying to apply the settings conventions plugin (instead of only including builds in the overarching composite build), but that didn’t help (either building the whole composite, or just building one project (outside of the composite) that directly included the conventions plugin project).
I haven’t dealt with creating a local Maven repo, and I’d prefer to not have to learn about this / maintain it, if there’s a simpler methodology.
They don’t have to be separate, having them together is no problem. You should consider separate subprojects in the plugin build, but that’s not different from multiple build script plugins in the same build. Otherwise changing one changes the classpath for all while it could stay the same for the others if they are in different projects and thus different jars.
Make sure that you do the includeBuild within the pluginManagement { ... } block. You should even do that for build script plugins, it just works for them outside as that is the classical way. But for settings plugins only the new way works.
Thanks. Moving includeBuild into pluginManagement { … } worked.
I had to repeat that in each of my included builds. Doing it just in the composite build didn’t work. Do you know of any way to make it work only modifying the composite build instead of each included build?
As I didn’t fully get the setup I’m not sure.
You can try to make sure to include the build with the plugin first.
For some situations this worked in the past, though I’m not sure what it was.
I have always included the build with my conventions plugin before all the other builds in my composite. When I added pluginManagement in my composite’s settings.gradle.kts, I added that before I included any builds. I’m including the conventions plugin project/build in both pluginManagement & at the top level of the file, like:
Thanks for the suggestion, but, unless I misunderstood you, I already tried that arrangement.
Everything works when I include the above pluginManagement {…} in each of the included builds, so it’s working, just requiring slightly more verbose settings than I had expected.