I am migrating a single module android project to kmp multi modular project for which I have used composite build and wrote a script conventional plugin.
inside the build-logic folder, I have settings.gradle.kts file which defined a variable libs
Well, I have found a way to use the dependencies declared in the version catalog, but I still want to understand why libs isn’t available in the plugin by default.
I solved it by manually creating a libs variable within the plugin, similar to how we do it in a precompiled Kotlin DSL script plugin:
val libs: VersionCatalog = extensions
.getByType(VersionCatalogsExtension::class.java)
.named(“libs”)
and in the dependency block
“conventional plugin” is not sufficient here as it does not mean whatever you meant to say.
Most people saying “conventional plugin” actually do mean precompiled Kotlin DSL script plugin.
But actually “conventional plugin” or better “convention plugin” just means a plugin that applies your convention and says nothing about how it is implemented.
It can be written as precompiled Kotlin DSL script plugin, precompiled Groovy DSL script plugin, Java class, Kotlin class, Groovy class, any other JVM language class, legacy script plugin, …
Thanks for pointing that out — you’re right that I used the term conventional plugin loosely.
What I actually meant is a convention script plugin located inside a composite build (build-logic), which I’m using to define my project conventions for a KMP multi-module setup.
So in my case:
The plugins such as core-library and feature-compose are convention script plugins inside build-logic
build-logic has its own settings.gradle.kts
I defined the version catalog (libs) there
I expected the libs accessor to be automatically available inside those script plugins, the same way it is in normal module build.gradle.kts files
You are still using it loosely.
It still sounds like when you say “convention script plugin” you mean “precompiled Kotlin DSL script plugin”.
So I still don’t understand what you mean with “similar to how we do it in a precompiled Kotlin DSL script plugin”.
Or do you mean “normal module build.gradle.kts files” when you say “precompiled Kotlin DSL script plugin”?
That would also not make much sense though, as there you don’t need to use the VersionCatalogsExtension.
Either way, a version catalog is for the build where you define it, so it makes not really much sense to have the accessors by default, as it is totally unclear what version catalog will be available when the built plugin is applied.
Imagine the included build as a totally standalone build (which it more or less is) that you publish somewhere and then use in another build fun that publishing location. At the time you build the plugin it is not clear what version catalog will be available at runtime.
If you happen to know that the identical version catalog will be applied at runtime too, you can either use the extension you used, that is the official way, or you can use my hack-around to use the accessors, or you can use the version catalog to generate accessors for usage in the plugin, either yourself or using the plugin someone wrote (I did not test it and have no idea about its quality). Both options beside the extension usage are also documented in the according issue Make generated type-safe version catalogs accessors accessible from precompiled script plugins · Issue #15383 · gradle/gradle · GitHub.
Thanks for the detailed explanation and for sharing the issue discussion.
I realize now that my confusion came from not understanding that build-logic / buildSrc / included builds are effectively standalone builds that are compiled without any knowledge of the version catalogs of the build where the plugin will eventually be applied.
Because of that, it makes sense that Gradle cannot generate type-safe libs accessors there — it simply cannot know what catalog will exist at runtime.
The issue thread you linked is what made this click for me. Even though my terminology earlier was imprecise, that discussion clarified the underlying design decision and answered my question.