Skip to content

Commit

Permalink
[gradle] If KGP >= 2.0.0-RC1 new Compose gradle plugin has to be appl…
Browse files Browse the repository at this point in the history
…ied.

To throw a configuration error if it's not, and to fail the build
  • Loading branch information
terrakok committed Apr 11, 2024
1 parent 062c9eb commit 9bc3bca
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,53 @@ package org.jetbrains.compose
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import org.jetbrains.compose.internal.ComposeCompilerArtifactProvider
import org.jetbrains.compose.internal.KOTLIN_JVM_PLUGIN_ID
import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID
import org.jetbrains.compose.internal.Version
import org.jetbrains.compose.internal.mppExtOrNull
import org.jetbrains.compose.internal.service.ConfigurationProblemReporterService
import org.jetbrains.compose.internal.webExt
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

internal fun Project.configureComposeCompilerPlugin() {
plugins.withId(KOTLIN_MPP_PLUGIN_ID) { plugin ->
configureComposeCompilerPlugin(plugin as KotlinBasePlugin)
}
plugins.withId(KOTLIN_JVM_PLUGIN_ID) { plugin ->
configureComposeCompilerPlugin(plugin as KotlinBasePlugin)
}
}

private const val newCompilerIsAvailableVersion = "2.0.0-RC1"
private const val newComposeCompilerKotlinSupportPluginId = "org.jetbrains.kotlin.plugin.compose"
internal const val newComposeCompilerError = "Since Kotlin $newCompilerIsAvailableVersion " +
"to use Compose Multiplatform you must apply \"$newComposeCompilerKotlinSupportPluginId\" plugin."

private fun Project.configureComposeCompilerPlugin(kgp: KotlinBasePlugin) {
val kgpVersion = kgp.pluginVersion

if (Version.fromString(kgpVersion) < Version.fromString(newCompilerIsAvailableVersion)) {
logger.info("Apply ComposeCompilerKotlinSupportPlugin (KGP version = $kgpVersion)")
project.plugins.apply(ComposeCompilerKotlinSupportPlugin::class.java)
} else {
//There is no other way to check that the plugin WASN'T applied!
afterEvaluate {
logger.info("Check that new '$newComposeCompilerKotlinSupportPluginId' was applied")
if (!project.plugins.hasPlugin(newComposeCompilerKotlinSupportPluginId)) {
error("e: Configuration problem: $newComposeCompilerError")
}
}
}
}

class ComposeCompilerKotlinSupportPlugin : KotlinCompilerPluginSupportPlugin {
private lateinit var composeCompilerArtifactProvider: ComposeCompilerArtifactProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.jetbrains.compose.internal.utils.currentTarget
import org.jetbrains.compose.resources.ResourcesExtension
import org.jetbrains.compose.resources.configureComposeResources
import org.jetbrains.compose.web.WebExtension
import org.jetbrains.kotlin.com.github.gundy.semver4j.SemVer
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
import org.jetbrains.kotlin.gradle.plugin.*
Expand Down Expand Up @@ -57,7 +58,7 @@ abstract class ComposePlugin : Plugin<Project> {
project.initializePreview(desktopExtension)
composeExtension.extensions.create("web", WebExtension::class.java)

project.plugins.apply(ComposeCompilerKotlinSupportPlugin::class.java)
project.configureComposeCompilerPlugin()
project.configureNativeCompilerCaching()

project.configureComposeResources(resourcesExtension)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.jetbrains.compose.internal

internal data class Version(
val major: Int,
val minor: Int,
val patch: Int,
val meta: String
): Comparable<Version> {
override fun compareTo(other: Version): Int = when {
major != other.major -> major - other.major
minor != other.minor -> minor - other.minor
patch != other.patch -> patch - other.patch
else -> {
if (meta.isEmpty()) 1
else if (other.meta.isEmpty()) -1
else meta.compareTo(other.meta)
}
}

companion object {
private val SEMVER_REGEXP = """^(\d+)(?:\.(\d*))?(?:\.(\d*))?(?:-(.*))?${'$'}""".toRegex()
fun fromString(versionString: String): Version {
val matchResult: MatchResult = SEMVER_REGEXP.matchEntire(versionString) ?: return Version(0,0,0, "")
val major: Int = matchResult.groups[1]?.value?.toInt() ?: 0
val minor: Int = matchResult.groups[2]?.value?.toInt() ?: 0
val patch: Int = matchResult.groups[3]?.value?.toInt() ?: 0
val meta: String = matchResult.groups[4]?.value ?: ""
return Version(major, minor, patch, meta)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ internal const val KOTLIN_MPP_PLUGIN_ID = "org.jetbrains.kotlin.multiplatform"
internal const val KOTLIN_JVM_PLUGIN_ID = "org.jetbrains.kotlin.jvm"
internal const val KOTLIN_JS_PLUGIN_ID = "org.jetbrains.kotlin.js"
internal const val COMPOSE_PLUGIN_ID = "org.jetbrains.compose"

internal const val IDEA_IMPORT_TASK_NAME = "prepareKotlinIdeaImport"
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import org.jetbrains.compose.internal.KOTLIN_JVM_PLUGIN_ID
import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.extraProperties
import java.io.File
Expand All @@ -29,11 +31,11 @@ private val androidPluginIds = listOf(

internal fun Project.configureComposeResources(extension: ResourcesExtension) {
val config = provider { extension }
plugins.withId(KOTLIN_MPP_PLUGIN_ID) { onKgpApplied(config) }
plugins.withId(KOTLIN_MPP_PLUGIN_ID) { onKgpApplied(config, it as KotlinBasePlugin) }
plugins.withId(KOTLIN_JVM_PLUGIN_ID) { onKotlinJvmApplied(config) }
}

private fun Project.onKgpApplied(config: Provider<ResourcesExtension>) {
private fun Project.onKgpApplied(config: Provider<ResourcesExtension>, kgp: KotlinBasePlugin) {
val kotlinExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java)

val hasKmpResources = extraProperties.has(KMP_RES_EXT)
Expand All @@ -47,7 +49,7 @@ private fun Project.onKgpApplied(config: Provider<ResourcesExtension>) {
if (!hasKmpResources) logger.info(
"""
Compose resources publication requires Kotlin Gradle Plugin >= 2.0
Current Kotlin Gradle Plugin is ${kotlinExtension.coreLibrariesVersion}
Current Kotlin Gradle Plugin is ${kgp.pluginVersion}
""".trimIndent()
)
if (currentGradleVersion < minGradleVersion) logger.info(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.jetbrains.compose.resources
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import org.jetbrains.compose.ComposePlugin
import org.jetbrains.compose.internal.IDEA_IMPORT_TASK_NAME
import org.jetbrains.compose.internal.utils.uppercaseFirstChar
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
Expand Down Expand Up @@ -67,7 +68,7 @@ internal fun Project.configureComposeResourcesGeneration(

//setup task execution during IDE import
tasks.configureEach { importTask ->
if (importTask.name == "prepareKotlinIdeaImport") {
if (importTask.name == IDEA_IMPORT_TASK_NAME) {
importTask.dependsOn(tasks.withType(CodeGenerationTask::class.java))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package org.jetbrains.compose.test.tests.integration

import org.jetbrains.compose.newComposeCompilerError
import org.jetbrains.compose.test.utils.GradlePluginTestBase
import org.jetbrains.compose.test.utils.TestProjects
import org.jetbrains.compose.test.utils.checks
Expand Down Expand Up @@ -46,4 +47,15 @@ class KotlinCompatibilityTest : GradlePluginTestBase() {
check.taskSuccessful(":compileKotlinJs")
}
}

@Test
fun testNewCompilerPluginError() {
val testProject = testProject(
TestProjects.mpp,
testEnvironment = defaultTestEnvironment.copy(kotlinVersion = "2.0.0-RC1")
)
testProject.gradleFailure("tasks").checks {
check.logContains(newComposeCompilerError)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jetbrains.compose.test.tests.unit

import org.jetbrains.compose.internal.Version
import kotlin.test.Test

class SemVerTest {
@Test
fun testSemVersionParser() {
assert(Version.fromString("0") < Version.fromString("1.2.3"))
assert(Version.fromString("2") > Version.fromString("1.2.3"))
assert(Version.fromString("1.1") > Version.fromString("1-abc"))
assert(Version.fromString("1.1") > Version.fromString("1"))
assert(Version.fromString("2.0.0-RC1") > Version.fromString("2.0.0-Beta5"))
assert(Version.fromString("2.0.0-RC2") > Version.fromString("2.0.0-RC1"))
assert(Version.fromString("2.0.0-RC1") > Version.fromString("1.9.23"))
assert(Version.fromString("2.0.0") > Version.fromString("2.0.0-RC1"))
assert(Version.fromString("2.0.0-RC1") == Version.fromString("2.0.0-RC1"))
}
}

0 comments on commit 9bc3bca

Please sign in to comment.