Is it possible to apply `kotlin-dsl` plugin from a...
# plugin-development
s
Is it possible to apply
kotlin-dsl
plugin from a regular Project plugin with the default version? I tried this way, it requires adding an explicit dependency
org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin
which I want to avoid.
Copy code
class MyConventionPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.pluginManager.apply("org.gradle.kotlin.kotlin-dsl")
    }
}
e
it's part of Gradle so you shouldn't be applying a specific version anyway
s
that's not possible from a Plugin as far as I can tell
e
if you need to, you can try
Copy code
dependencies {
    implementation(gradleKotlinDsl())
}
in your
plugin/build.gradle.kts
or however you have it set up, but
Copy code
plugins {
    `kotlin-dsl`
}
in a precompiled script plugin or
Copy code
pluginManager.apply(org.gradle.kotlin.dsl.plugins.dsl.KotlinDslPlugin::class)
should just work, because it gets pulled in by
gradleApi()
which is a default dependency of
java-gradle-plugin
builds
👀 1
or
pluginManager.apply("kotlin-dsl")
?
still, for what purpose is this? a Kotlin build script will have the DSL applied to it already, and it's not useful for a Groovy build script
s
unfortunately, none of these is able to find the plugin:
Copy code
pluginManager.apply(KotlinDslPlugin::class)
pluginManager.apply("org.gradle.kotlin.kotlin-dsl")
pluginManager.apply("kotlin-dsl")
pluginManager.apply("`kotlin-dsl`")
still, for what purpose is this?
I have a convention plugin which applies kotlin-dsl internally. I can probably replace kotlin-dsl with a combination of java-gradle-plugin, sam-with-receiver and gradleKotlinDsl() dependency
a
try adding this as a dependency:
Copy code
implementation("org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:6.1.2")
(coordinates from https://plugins.gradle.org/plugin/org.gradle.kotlin.kotlin-dsl, under "Adding the plugin to build logic for usage in precompiled script plugins.")
s
@Adam that works well within a project with an included build. however the problem I'm facing is when the plugin gets published, a user with a different version of Gradle would see a warning that the version of the applied kotlin-dsl plugin mismatches the expected one for that version of Gradle
a
Ahh I see, sorry, I misunderstood.
Could you say more about what you want to configure about the kotlin-dsl plugin? By itself it doesn't have very many configurable options.
You could consider this instead: create a 'CustomBaseConventionPlugin' (like an in-house version of the regular
base
plugin). It has a compileOnly dependency on kotlin-dsl. Users would still have to apply the kotlin-dsl plugin, but would also have to apply the custom-base plugin. And then the custom-base plugin would have a
plugins.withType<KotlinDslPlugin>().configureEach {}
(using the correct kotlin-dsl plugin class).
Another option (but I think it's a very complicated/overkill route) is to use the
org.gradle.plugin.api‑version
attribute to create variants per Gradle version. Each variant would use the correct kotlin-dsl version (
org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion
) per Gradle version https://docs.gradle.org/8.14.2/userguide/variant_attributes.html#sec:gradle-plugins-default-attributes
v
@ephemient unfortunately is not right here. Just using "apply" does not work, because the
kotlin-dsl
plugin is not a built-in plugin. It is an external plugin pulled in from plugin central which just has a special build-time generated accessor that applies that external plugin with a specific version and checks that is the plugin is applied it is applied in a specific version. I have no idea why it is made like that, but it should probably better be built-in. Even for a specific Gradle version there is no way to get the version to depend on besides an internal constant: https://github.com/gradle/gradle/issues/17825 It probably indeed would be the only option currently to have one variant per Gradle version that depends on the according plugin version. Most probably it would be much easier to just not do it but let the customer apply the plugin himself.
plugins.wthType
should practically never be used, look at the JavaDoc of
plugins.
(i.e.
getPlugins()
). You should not use it, but
pluginManager.withPlugin
instead.