Hello, not so sure about where to ask this questio...
# plugin-development
p
Hello, not so sure about where to ask this question. Because it's related to Gradle plugin conventions, I'm gonna ask here. I have several plugins in
buildSrc/src/main/kotlin/com/company/allprojects/*.gradle.kts
where I split the logic applied by
allprojects
or
subprojects
blocks across multiple files. They all need to be applied at the root build.gradle.kts but it happened a newly added plugin apply was forgotten. To solve this problem, I wrote this
buildSrc/src/main/kotlin/com/company/allprojects/apply-all.gradle.kts
logic:
Copy code
package com.company.allprojects

//
// Programmatically ensure all plugins located in this folder are applied.
//

val PLUGIN_SUFFIX = "gradle.kts"

rootDir.resolve("buildSrc/src/main/kotlin/com/company/allprojects")
    .listFiles()
    .asSequence()
    .filter { it.name != "apply-all.gradle.kts" }
    .filter { it.name.endsWith(".gradle.kts") }
    .sorted()
    .forEach { apply(plugin = "com.company.allprojects.${it.name.removeSuffix(".gradle.kts")}") }
But I'm not sure it's the best solution, even if it's working... Regardless of the hardcoded path, which is OK because it's only made to be used in this specific project, could someone point me to a better alternative, or just confirm if it's good enough?
m
A better way to do this would be to create a
Plugin<Settings>
and then use the new
gradle.lifecycle.beforeProject { ... }
callback (docs). That will run on every project, at which point you can just directly apply each plugin, explicitly.
v
How would that help? The problem is not, that he forgets to apply the "apply all" plugin to a project. The problem is, that his "apply all" plugin that he applies to all projects forgets to apply one of the "sub plugins". So the problem would be the same.
Maybe it would be better to have tests that ensure the plugin is doing what it is expected to do instead of doing such "auto-discovery" though. 🤷‍♂️
p
@Mike Cumings as vampire said, this is not directly answering the problem but do you mean that
gradle.lifecycle.beforeProject
is a better alternative to
all/subprojects
blocks?
@Vampire I also thought about adding tests, even if said test will run in CI (after code push) where the "auto-discovery" is just doing the job and at each run (so completely removing the need). WDUT? Also let's say the test approach is preferred, where would you put this test? (tests located in buildSrc are less user-friendly to run in my experience)
v
that gradle.lifecycle.beforeProject is a better alternative to all/subprojects callbacks?
That definitely, as any cross-project configuration is discouraged bad practice. But even better is to also not use that, but convention plugins. :-)
👍 1
Besides that I would always prefer an included build over
builsSrc
if possible, why do you think tests there are less user-friendly and less than what?
p
That definitely, as any cross-project configuration is discouraged bad practice. But even better is to also not use that, but convention plugins. 🙂
I'm actually aware of such best practice, but being the only one who has a complete overview of our Gradle approach, I try to make it as beginner-friendly as possible (one of said
allprojects
plugin is to ensure each project is applying at least 1 of our convention plugin 🦺).
Besides that I would always prefer an included build over
builsSrc
if possible,
I thought since recent Gradle versions,
buildSrc
was basically a composite build (no more difference between the 2). So is there any difference except the way to "import" it?
why do you think tests there are less user-friendly and less than what?
It's been a while I haven't compared them but it was more difficult to run a buildSrc test from Android Studio (I should try again though). Also I would need to change our testing sharding logic to cover projects outside the rootProject, so another thing to maintain...
v
plugin is to ensure each project is applying at least 1 of our convention plugin 🦺).
Similar here. :-D All plugins apply the base plugin which ensures the settings plugin is applied and the settings plugin ensures each project has at least the base plugin applied.
I thought since recent Gradle versions, buildSrc was basically a composite build (no more difference between the 2).
Not even nearly. Since 8.0 they are much more similar, but they are still special, not at all an included build and behave slightly different in several regards.
So is there any difference except the way to "import" it?
Yes, I explained it multiple times already, just search for it.
It's been a while I haven't compared them but it was more difficult to run a buildSrc test from Android Studio (I should try again though).
If that's the case, use an included build. But actually I'd wonder if it is.
Also I would need to change our testing sharding logic to cover projects outside the rootProject, so another thing to maintain...
I did not get that