I’m trying to migrate a configuration like: ```plu...
# gradle
g
I’m trying to migrate a configuration like:
Copy code
plugins {
    kotlin("multiplatform")
    id("org.jetbrains.compose") version Versions.JetBrains.Compose.desktop
}
to a convention plugin where:
Copy code
with(pluginManager) {
  apply("org.jetbrains.kotlin.multiplatform:${catalog.findVersion("kotlin").get()}")
  apply("org.jetbrains.compose:${catalog.findVersion("desktopCompose").get()}")
}
but when I run it throws saying (same for the second line if I comment the first):
Copy code
Caused by: org.gradle.api.plugins.UnknownPluginException: Plugin with id 'org.jetbrains.kotlin.multiplatform:1.7.10' not found.
	at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:144)
I’ve checked here and the syntax of the plugin is correct. What am I missing here? 🤔 Thanks!
s
To use the legacy plugin application method you need both the
apply
call and the
buildscript
dependency. (And the version number goes in the buildscript dependency).
Why are you trying to move from the new way to the old way? 🤔
g
sorry my code snipet missed a part, I’ve updated (also gonna post here)
Copy code
with(pluginManager) {
    apply("org.jetbrains.kotlin.multiplatform:${catalog.findVersion("kotlin").get()}")
    apply("org.jetbrains.compose:${catalog.findVersion("desktopCompose").get()}")
}
it’s the kotlin apply extension function and not the “gradle apply plugin” dsl
my bad 😅
e
it's apply(id), not apply(id:version) - that's why it's complaining
g
how can i specify a version then or it’s not needed?
e
if you need to provide a default version, put it in the plugin dependencies, not in the plugin
g
can you help me with the syntax or point me to the docs? Trying this last part in your response and I’m struggling with the version part:
Copy code
with(pluginManager) {
    dependencies {
        add(
e
Copy code
// plugin/build.gradle
dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
}

// plugin/src/main/kotlin/my-convention-plugin.gradle.kts
plugins {
    kotlin("multiplatform")
}

// or plugins/src/main/kotlin/my/convention/MyPlugin.kt
class MyPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.pluginManager.apply("org.jetbrains.kotlin.multiplatform")
g
yes that’s working 🙂 my code is just like yours
regarding the compose for desktop, is the one who needs a version
I need to translate this:
Copy code
id("org.jetbrains.compose") version Versions.JetBrains.Compose.desktop
into to a convention plugin “import”
and the version part it’s tricky for me
I was trying something like:
Copy code
with(pluginManager) {
 val catalog = extensions.getByType<VersionCatalogsExtension>().named("libs")
    dependencies {
        add("implementation", "org.jetbrains.compose") {
            setVersion(catalog.findVersion("desktopCompose"))
        }
    }
    apply("org.jetbrains.kotlin.multiplatform")
    ...
}
e
in general, a plugin may be applied to any project and can't assume the presence of a version catalog
g
that’s a good point
but that means that I have to “hard code” the version in every module that uses compose desktop. I was using buildSrc that let’s me do this: Constants.version
up on migration to versions.toml I was trying to remove this “buildSrc” dependency but maintaining a single source of truth for dependencies.
it also helps with this kind of configurations:
Copy code
android {
    compileSdk = libs.findVersion("androidCompileSdk").get().toString().toInt()
}
that can be used in shared modules that require android library, etc.
e
if you are assuming that it's only going to be applied to the same project, you could do something like
Copy code
// plugin/settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

// plugins/build.gradle.kts
dependencies {
    implementation("org.jetbrains.compose:compose-gradle-plugin:${libs.versions.desktopCompose.get()}"
i
I ended up with the following setup (multi-module build, using buildSrc, script plugins and version catalog)
Copy code
// buildSrc/settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            // enable sharing of libs catalog between buildSrc stuff and app modules
            from(files("../gradle/libs.versions.toml"))
        }
    }
}
Copy code
// buildSrc/build.gradle.kts
plugins {
    `kotlin-dsl`
}

repositories {
    gradlePluginPortal()
}

dependencies {
    // plugins applied from script plugins need to be defined as dependencies here
    implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
    implementation("com.github.ben-manes:gradle-versions-plugin:0.42.0")
    implementation("org.owasp:dependency-check-gradle:7.0.0")
}

kotlin {
    jvmToolchain {
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(libs.versions.jvm.get()))
    }
}
Copy code
// buildSrc/src/main/kotlin/myapp.conventions.gradle.kts
plugins {
    // NOTE: no version definitions here, versions are defined as part of dependencies in buildSrc/build.gradle.kts,
    // in plugins block there's no Project, so the Ext.kt approach (see below) does no work here
    java
    kotlin("jvm")
}

// NOTE: libs are not directly accessible in script plugins, but we can get to them via Project, see Ext.kt
val jvmVersion = requiredVersionFromLibs("jvm")
kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(jvmVersion))
    }
}
Copy code
// buildSrc/src/main/kotlin/Ext.kt

// <https://github.com/gradle/gradle/issues/15383>
private val Project.libsCatalog get() = the<VersionCatalogsExtension>().named("libs")
fun Project.requiredVersionFromLibs(name: String) = libsCatalog.findVersion(name).get().requiredVersion
fun Project.dependencyFromLibs(name: String) = libsCatalog.findLibrary(name).get()
Copy code
// myapp/build.gradle.kts

// NOTE: here libs is available
plugins {
    id("myapp.conventions")
    alias(libs.plugins.somePluginDefinedInCatalogThatsNotAppliedByScriptPlugins)
}
g
I had to pause my tests for a bit, but I’ll get back at you with my results ASAP. Thanks in advance both @ephemient and @isto for your time 🙂
I’m back with my working solution. I forgot that I could use versions catalogs plugins to achieve what I wanted, example: :desktopCompose
Copy code
plugins {
    kotlin("multiplatform")
    alias(libs.plugins.jetbrains.compose)
}
:sharedComposables
Copy code
plugins {
    id("buildlogic.plugins.conventions.kmp.library.android")
    alias(libs.plugins.jetbrains.compose)
}
where my versions are declared as:
Copy code
[plugins]
jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "desktopCompose" }
🥳 ps: My KMPAndroidLibraryConventionPlugin `id("buildlogic.plugins.conventions.kmp.library.android")`it’s also used in :shared (KMM module) and it contains Android configurations like
defaultConfig
,
compileOptions
,
lint
, etc… and it also applies:
Copy code
pluginManager.apply("org.jetbrains.kotlin.multiplatform")
pluginManager.apply("com.android.library")
I’ve also kept the compose version outside the plugin 🙂
401 Views