From 529230ce88b1307b0d0201b4c2635447c32b3b51 Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Thu, 6 Oct 2022 15:32:12 +0200 Subject: [PATCH 1/6] Rename COMPOSE_CORE_VERSION and COMPOSE_WEB_VERSION to compose.version (#2365) as in the other places --- web/build.gradle.kts | 2 +- web/compose-compiler-integration/README.md | 2 +- web/compose-compiler-integration/build.gradle.kts | 4 ++-- .../main-template/settings.gradle.kts | 4 ++-- web/gradle.properties | 3 +-- web/settings.gradle.kts | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/web/build.gradle.kts b/web/build.gradle.kts index 41ba5189e6..4c325bf9d2 100644 --- a/web/build.gradle.kts +++ b/web/build.gradle.kts @@ -8,7 +8,7 @@ plugins { kotlin("multiplatform") apply false } -val COMPOSE_WEB_VERSION: String by project +val COMPOSE_WEB_VERSION: String = extra["compose.version"] as String val COMPOSE_REPO_USERNAME: String? by project val COMPOSE_REPO_KEY: String? by project val COMPOSE_WEB_BUILD_WITH_SAMPLES = project.property("compose.web.buildSamples")!!.toString().toBoolean() diff --git a/web/compose-compiler-integration/README.md b/web/compose-compiler-integration/README.md index f8d63f0094..bc0f8ad811 100644 --- a/web/compose-compiler-integration/README.md +++ b/web/compose-compiler-integration/README.md @@ -2,7 +2,7 @@ RUN from project root directory: `./gradlew :compose-compiler-integration:checkComposeCases` To use specific version: -`./gradlew :compose-compiler-integration:checkComposeCases -PCOMPOSE_CORE_VERSION=1.0.1-rc2 -PCOMPOSE_WEB_VERSION=1.0.1-rc2 +`./gradlew :compose-compiler-integration:checkComposeCases -Pcompose.version=1.2.0-beta03 To fun only filtered cases (check for contained in file path): `./gradlew :compose-compiler-integration:checkComposeCases -PFILTER_CASES=CaseName` diff --git a/web/compose-compiler-integration/build.gradle.kts b/web/compose-compiler-integration/build.gradle.kts index b770099633..8f4c88fabc 100644 --- a/web/compose-compiler-integration/build.gradle.kts +++ b/web/compose-compiler-integration/build.gradle.kts @@ -61,7 +61,7 @@ fun build( ) { val isWin = System.getProperty("os.name").startsWith("Win") val arguments = buildCmd.toMutableList().also { - it.add("-PCOMPOSE_CORE_VERSION=$composeVersion") + it.add("-Pcompose.version=$composeVersion") it.add("-Pkotlin.version=$kotlinVersion") }.toTypedArray() @@ -176,7 +176,7 @@ fun runCasesInDirectory( tasks.register("checkComposeCases") { doLast { val filterCases = project.findProperty("FILTER_CASES")?.toString() ?: "" - val composeVersion = project.findProperty("COMPOSE_CORE_VERSION")?.toString() ?: "0.0.0-SNASPHOT" + val composeVersion = project.findProperty("compose.version")?.toString() ?: "0.0.0-SNASPHOT" val kotlinVersion = kotlin.coreLibrariesVersion val expectedFailingCasesDir = File("${projectDir.absolutePath}/testcases/failing") diff --git a/web/compose-compiler-integration/main-template/settings.gradle.kts b/web/compose-compiler-integration/main-template/settings.gradle.kts index fcfdf8f809..c554a78781 100644 --- a/web/compose-compiler-integration/main-template/settings.gradle.kts +++ b/web/compose-compiler-integration/main-template/settings.gradle.kts @@ -12,8 +12,8 @@ pluginManagement { println("KotlinVersion=[$kotlinVersion]") eachPlugin { if (requested.id.id == "org.jetbrains.compose") { - val useVersion = if (extra.has("COMPOSE_CORE_VERSION")) { - extra["COMPOSE_CORE_VERSION"].toString() + val useVersion = if (extra.has("compose.version")) { + extra["compose.version"].toString() } else { "0.0.0-SNASPHOT" } diff --git a/web/gradle.properties b/web/gradle.properties index 18004c5d53..1838132f93 100644 --- a/web/gradle.properties +++ b/web/gradle.properties @@ -1,5 +1,4 @@ -COMPOSE_CORE_VERSION=1.1.0 -COMPOSE_WEB_VERSION=1.1.0 +compose.version=1.1.0 compose.web.buildSamples=false compose.web.tests.integration.withFirefox compose.web.tests.skip.benchmarks=false diff --git a/web/settings.gradle.kts b/web/settings.gradle.kts index 6059e52a65..ad4c210e79 100644 --- a/web/settings.gradle.kts +++ b/web/settings.gradle.kts @@ -1,5 +1,5 @@ pluginManagement { - val COMPOSE_CORE_VERSION: String by settings + val COMPOSE_CORE_VERSION = extra["compose.version"] as String println("[build] compose core version: $COMPOSE_CORE_VERSION") // pluginManagement section won't see outer scope, hence the FQ names From ecbd0ef7d0e646bd56cdc36ba3d87feef95a6a4e Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Thu, 6 Oct 2022 19:05:13 +0200 Subject: [PATCH 2/6] Update FEATURES.md --- FEATURES.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index e8354b71d8..0d7a784719 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -6,8 +6,6 @@ * Linux (x86-64, arm64) * Web browsers -Follow individual tutorials to understand how to use particular feature. - ### Limitations Following limitations apply to 1.0 release. From fd4673a155a931df03093745cb63f37643479b4f Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Thu, 6 Oct 2022 23:18:24 +0200 Subject: [PATCH 3/6] Update Compose --- compose/frameworks/support | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/frameworks/support b/compose/frameworks/support index 52ab0066b5..24287113c7 160000 --- a/compose/frameworks/support +++ b/compose/frameworks/support @@ -1 +1 @@ -Subproject commit 52ab0066b5c61de1f55890122c584cbf20e6fee5 +Subproject commit 24287113c7c7d9e0138fb5c645a732ee6109cdc6 From 7067f5cffce866119cef6d92fc1f701e6582e27b Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Fri, 7 Oct 2022 13:47:03 +0200 Subject: [PATCH 4/6] Remove redirecting to Jetpack Compose in android target in Gradle plugin (#2364) We redirect to Jetpack Compose overriding in the Gradle Metadata: https://maven.pkg.jetbrains.space/public/p/compose/dev/org/jetbrains/compose/runtime/runtime/1.2.0-beta03/runtime-1.2.0-beta03.module So we don't need this functionality in the plugin --- .../src/main/kotlin/BuildProperties.kt | 4 -- gradle-plugins/compose/build.gradle.kts | 2 - .../org/jetbrains/compose/ComposePlugin.kt | 54 ------------------- 3 files changed, 60 deletions(-) diff --git a/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt b/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt index 07e5a32cdc..ce59fc0ba6 100644 --- a/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt +++ b/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt @@ -26,8 +26,4 @@ object BuildProperties { fun deployVersion(project: Project): String = System.getenv("COMPOSE_GRADLE_PLUGIN_VERSION") ?: project.findProperty("deploy.version") as String - fun experimentalOELPublication(project: Project): Boolean = - project.findProperty("oel.publication") == "true" - fun oelAndroidXVersion(project: Project): String? = - project.findProperty("oel.androidx.version") as String? } diff --git a/gradle-plugins/compose/build.gradle.kts b/gradle-plugins/compose/build.gradle.kts index 4a2914768a..d4a1efd661 100644 --- a/gradle-plugins/compose/build.gradle.kts +++ b/gradle-plugins/compose/build.gradle.kts @@ -31,8 +31,6 @@ val buildConfig = tasks.register("buildConfig", GenerateBuildConfig::class.java) fieldsToGenerate.put("composeVersion", BuildProperties.composeVersion(project)) fieldsToGenerate.put("composeCompilerVersion", BuildProperties.composeCompilerVersion(project)) fieldsToGenerate.put("composeGradlePluginVersion", BuildProperties.deployVersion(project)) - fieldsToGenerate.put("experimentalOELPublication", BuildProperties.experimentalOELPublication(project)) - fieldsToGenerate.put("oelAndroidXVersion", BuildProperties.oelAndroidXVersion(project).orEmpty()) } tasks.named("compileKotlin") { dependsOn(buildConfig) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt index 06db686731..b80fc58e3d 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt @@ -69,60 +69,6 @@ class ComposePlugin : Plugin { } } - //redirecting all android artifacts to androidx.compose - project.dependencies.modules { - if (!androidExtension.useAndroidX && !ComposeBuildConfig.experimentalOELPublication) { - // Replace 'androidx.compose' artifacts by 'org.jetbrains.compose' artifacts. - // It is needed, because 'org.jetbrains.compose' artifacts are the same artifacts as 'androidx.compose' - // (but with different version). - // And Gradle will throw an error when it cannot determine which class from which artifact should it use. - // - // Note that we don't provide a configuration parameter to disable dependency replacement, - // because without replacement, gradle will fail anyway because classpath contains two incompatible artifacts. - // - // We should define all replacements, even for transitive dependencies. - // For example, a library can depend on androidx.compose.foundation:foundation-layout - // - // List of all org.jetbrains.compose libraries is here: - // https://maven.pkg.jetbrains.space/public/p/compose/dev/org/jetbrains/compose/ - // - // (use ./gradle printAllAndroidxReplacements to know what dependencies should be here) - // - // It is temporarily solution until we will be publishing all MPP artifacts in Google Maven repository. - // Or align versions with androidx artifacts and point MPP-android artifacts to androidx artifacts (is it possible?) - - listOf( - "androidx.compose.animation:animation", - "androidx.compose.animation:animation-core", - "androidx.compose.animation:animation-graphics", - "androidx.compose.compiler:compiler", - "androidx.compose.compiler:compiler-hosted", - "androidx.compose.foundation:foundation", - "androidx.compose.foundation:foundation-layout", - "androidx.compose.material:material", - "androidx.compose.material:material-icons-core", - "androidx.compose.material:material-icons-extended", - "androidx.compose.material:material-ripple", - "androidx.compose.material:material3", - "androidx.compose.runtime:runtime", - "androidx.compose.runtime:runtime-saveable", - "androidx.compose.ui:ui", - "androidx.compose.ui:ui-geometry", - "androidx.compose.ui:ui-graphics", - "androidx.compose.ui:ui-test", - "androidx.compose.ui:ui-test-junit4", - "androidx.compose.ui:ui-text", - "androidx.compose.ui:ui-unit", - "androidx.compose.ui:ui-util" - ).forEach() { module -> - it.replaceAndroidx( - module, - module.replace("androidx.compose", "org.jetbrains.compose") - ) - } - } - } - val overrideDefaultJvmTarget = ComposeProperties.overrideKotlinJvmTarget(project.providers).get() project.tasks.withType(KotlinCompile::class.java) { it.kotlinOptions.apply { From 87df95cbe9c1ef890a72298782da9ab9815f0dc2 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov <654232+AlexeyTsvetkov@users.noreply.github.com> Date: Wed, 23 Feb 2022 18:56:20 +0300 Subject: [PATCH 5/6] Don't add public.app-category. prefix to appCategory by default (#1887) --- .../compose/desktop/application/tasks/AbstractJPackageTask.kt | 4 ++-- tutorials/Native_distributions_and_local_execution/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt index b26cf12d05..764570e6d1 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt @@ -579,8 +579,8 @@ abstract class AbstractJPackageTask @Inject constructor( val packageVersion = packageVersion.get()!! plist[PlistKeys.CFBundleShortVersionString] = packageVersion // If building for the App Store, use "utilities" as default just like jpackage. - val category = macAppCategory.orNull ?: (if (macAppStore.orNull == true) "utilities" else null) - plist[PlistKeys.LSApplicationCategoryType] = category?.let { "public.app-category.$it" } ?: "Unknown" + val category = macAppCategory.orNull ?: (if (macAppStore.orNull == true) "public.app-category.utilities" else null) + plist[PlistKeys.LSApplicationCategoryType] = category ?: "Unknown" val packageBuildVersion = packageBuildVersion.orNull ?: packageVersion plist[PlistKeys.CFBundleVersion] = packageBuildVersion val year = Calendar.getInstance().get(Calendar.YEAR) diff --git a/tutorials/Native_distributions_and_local_execution/README.md b/tutorials/Native_distributions_and_local_execution/README.md index b7c8cd2253..b62a6d4fbc 100755 --- a/tutorials/Native_distributions_and_local_execution/README.md +++ b/tutorials/Native_distributions_and_local_execution/README.md @@ -447,7 +447,7 @@ The following platform-specific options are available for details; * `appStore = true` — build and sign for the Apple App Store. Requires at least JDK 17; * `appCategory` — category of the app for the Apple App Store. - Default value is `utilities` when building for the App Store, `Unknown` otherwise. + Default value is `public.app-category.utilities` when building for the App Store, `Unknown` otherwise. See [LSApplicationCategoryType](https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype) for a list of valid categories; * `entitlementsFile.set(File("PATH_TO_ENTITLEMENTS"))` — a path to file containing entitlements to use when signing. When a custom file is provided, make sure to add the entitlements that are required for Java apps. From 3996233b032772a5afb8ceceafc4affae793e480 Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Sat, 8 Oct 2022 15:50:51 +0200 Subject: [PATCH 6/6] Allow to use Compose on multiple Kotlin versions (#2366) JS target supports a lower version (1.7.10), because we have a bug in Koltin 1.7.20 Compose 1.2.0 will support: 1.7.20 and 1.7.10 for Android and Desktop 1.7.10 for JS We will release the new patchset (1.2.1) with 1.7.2X support for JS later --- README.md | 12 +-- FEATURES.md => VERSIONING.md | 19 ++--- examples/validateExamples.sh | 3 - examples/validateExamplesWithJs.sh | 24 ++++++ .../src/main/kotlin/BuildProperties.kt | 4 - gradle-plugins/compose/build.gradle.kts | 1 - .../compose/ComposeCompilerCompatability.kt | 19 +++++ .../ComposeCompilerKotlinSupportPlugin.kt | 10 ++- .../ComposeCompilerArtifactProvider.kt | 77 ++++++++++++++----- .../tests/integration/GradlePluginTest.kt | 9 ++- .../integration/KotlinCompatabilityTest.kt | 56 ++++++++++++++ .../ComposeCompilerArtifactProviderTest.kt | 26 ++++--- .../test/utils/GradlePluginTestBase.kt | 2 +- ...KotlinVersion.kt => TestKotlinVersions.kt} | 7 +- .../compose/test/utils/TestProject.kt | 4 +- .../compose/test/utils/TestProperties.kt | 7 +- gradle-plugins/gradle.properties | 13 ++-- tutorials/checker/build.gradle.kts | 47 ++++++----- 18 files changed, 251 insertions(+), 89 deletions(-) rename FEATURES.md => VERSIONING.md (62%) create mode 100644 examples/validateExamplesWithJs.sh create mode 100644 gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatability.kt create mode 100644 gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatabilityTest.kt rename gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/{TestKotlinVersion.kt => TestKotlinVersions.kt} (50%) diff --git a/README.md b/README.md index 028d82af36..1cebe2567f 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,9 @@ # Compose Multiplatform, by JetBrains ![](artwork/readme/apps.png) -Compose Kotlin UI framework port for desktop platforms (macOS, Linux, Windows) and Web, components outside of the core Compose repository -at https://android.googlesource.com/platform/frameworks/support. +Compose Kotlin UI framework port for desktop platforms (macOS, Linux, Windows) and Web, components outside of the core [Compose repository](https://android.googlesource.com/platform/frameworks/support). -Preview functionality (check your application UI without building/running it) for desktop platforms is available via IDEA plugin (https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support). +Preview functionality (check your application UI without building/running it) for desktop platforms is available via [IDEA plugin](https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support). ## Tutorials ### Compose for Desktop @@ -70,6 +69,9 @@ Note that when you use Compose Multiplatform, you setup your project differently * [LWJGL integration](experimental/lwjgl-integration) - An example showing how to integrate Compose with [LWJGL](https://www.lwjgl.org) * [CLI example](experimental/build_from_cli) - An example showing how to build Compose without Gradle -## Getting latest version of Compose Multiplatform ## +## Versions ## -See https://github.com/JetBrains/compose-jb/releases/latest for the latest stable release or https://github.com/JetBrains/compose-jb/releases for all stable and dev releases. +* [The latest stable release](https://github.com/JetBrains/compose-jb/releases/latest) +* [The latest dev release](https://github.com/JetBrains/compose-jb/releases) +* [Compatability and versioning overview](VERSIONING.md) +* [Changelog](CHANGELOG.md) diff --git a/FEATURES.md b/VERSIONING.md similarity index 62% rename from FEATURES.md rename to VERSIONING.md index 0d7a784719..5a7d836536 100644 --- a/FEATURES.md +++ b/VERSIONING.md @@ -21,12 +21,13 @@ Knowing issues on older versions: ### Kotlin compatibility -Compose version | Kotlin version ---- | --- -1.0.0+ | 1.5.31 -1.0.1-rc2+ | 1.6.10 - - -### Gradle plugin compatibility - -* 1.0.0 works with Gradle 6.7 or later (7.2 is the latest tested version). +A new version of Kotlin may be not supported immediately after its release. But after some time we will release a version of Compose Multiplatform +that supports it. +Starting from 1.2.0, Compose Multiplatform supports multiple versions of Kotlin. + +Kotlin version | Minimal Compose version | Notes +--- | --- | --- +1.5.31 | 1.0.0 +1.6.20 | 1.1.1 +1.7.10 | 1.2.0 +1.7.20 | 1.2.0 | JS is not supported (will be fixed in the next versions) diff --git a/examples/validateExamples.sh b/examples/validateExamples.sh index c970e81e66..83b61d17e9 100755 --- a/examples/validateExamples.sh +++ b/examples/validateExamples.sh @@ -25,7 +25,4 @@ runGradle issues package runGradle notepad package runGradle todoapp-lite package runGradle visual-effects package -runGradle web-compose-bird build -runGradle web-landing build -runGradle web-with-react build runGradle widgets-gallery package diff --git a/examples/validateExamplesWithJs.sh b/examples/validateExamplesWithJs.sh new file mode 100644 index 0000000000..30957744fe --- /dev/null +++ b/examples/validateExamplesWithJs.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Script to build most of the examples, to verify if they can compile. +# Don't add examples, which don't depend on maven.pkg.jetbrains.space, because they won't be able to compile. + +set -euo pipefail + +if [ "$#" -ne 2 ]; then +echo "Specify Compose and Kotlin version. For example: ./validateExamplesWithJs.sh 1.1.1 1.6.10" +exit 1 +fi +COMPOSE_VERSION=$1 +KOTLIN_VERSION=$2 + + +runGradle() { + pushd $1 + ./gradlew $2 -Pcompose.version=$COMPOSE_VERSION -Pkotlin.version=$KOTLIN_VERSION + popd +} + +runGradle web-compose-bird build +runGradle web-landing build +runGradle web-with-react build diff --git a/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt b/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt index ce59fc0ba6..1564f73c14 100644 --- a/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt +++ b/gradle-plugins/buildSrc/src/main/kotlin/BuildProperties.kt @@ -15,10 +15,6 @@ object BuildProperties { fun composeVersion(project: Project): String = System.getenv("COMPOSE_GRADLE_PLUGIN_COMPOSE_VERSION") ?: project.findProperty("compose.version") as String - fun composeCompilerVersion(project: Project): String = - project.findProperty("compose.compiler.version") as String - fun composeCompilerCompatibleKotlinVersion(project: Project): String = - project.findProperty("compose.compiler.compatible.kotlin.version") as String fun testsAndroidxCompilerVersion(project: Project): String = project.findProperty("compose.tests.androidx.compiler.version") as String fun testsAndroidxCompilerCompatibleVersion(project: Project): String = diff --git a/gradle-plugins/compose/build.gradle.kts b/gradle-plugins/compose/build.gradle.kts index d4a1efd661..0bc5c7f91a 100644 --- a/gradle-plugins/compose/build.gradle.kts +++ b/gradle-plugins/compose/build.gradle.kts @@ -29,7 +29,6 @@ val buildConfig = tasks.register("buildConfig", GenerateBuildConfig::class.java) classFqName.set("org.jetbrains.compose.ComposeBuildConfig") generatedOutputDir.set(buildConfigDir) fieldsToGenerate.put("composeVersion", BuildProperties.composeVersion(project)) - fieldsToGenerate.put("composeCompilerVersion", BuildProperties.composeCompilerVersion(project)) fieldsToGenerate.put("composeGradlePluginVersion", BuildProperties.deployVersion(project)) } tasks.named("compileKotlin") { diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatability.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatability.kt new file mode 100644 index 0000000000..06e16e85fe --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatability.kt @@ -0,0 +1,19 @@ +package org.jetbrains.compose + +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType + +internal object ComposeCompilerCompatability { + fun compilerVersionFor(kotlinVersion: String): ComposeCompilerVersion? = when (kotlinVersion) { + "1.7.10" -> ComposeCompilerVersion("1.3.0-alpha01") + "1.7.20" -> ComposeCompilerVersion( + "1.3.2-alpha01", + unsupportedPlatforms = setOf(KotlinPlatformType.js) + ) + else -> null + } +} + +internal data class ComposeCompilerVersion( + val version: String, + val unsupportedPlatforms: Set = emptySet() +) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt index e33c1628f3..d2855675c3 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt @@ -13,13 +13,18 @@ import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget class ComposeCompilerKotlinSupportPlugin : KotlinCompilerPluginSupportPlugin { - private var composeCompilerArtifactProvider = ComposeCompilerArtifactProvider { null } + private lateinit var composeCompilerArtifactProvider: ComposeCompilerArtifactProvider override fun apply(target: Project) { super.apply(target) target.plugins.withType(ComposePlugin::class.java) { val composeExt = target.extensions.getByType(ComposeExtension::class.java) - composeCompilerArtifactProvider = ComposeCompilerArtifactProvider { composeExt.kotlinCompilerPlugin.orNull } + + composeCompilerArtifactProvider = ComposeCompilerArtifactProvider( + kotlinVersion = target.getKotlinPluginVersion() + ) { + composeExt.kotlinCompilerPlugin.orNull + } } } @@ -52,6 +57,7 @@ class ComposeCompilerKotlinSupportPlugin : KotlinCompilerPluginSupportPlugin { override fun applyToCompilation(kotlinCompilation: KotlinCompilation<*>): Provider> { val target = kotlinCompilation.target + composeCompilerArtifactProvider.checkTargetSupported(target) return target.project.provider { platformPluginOptions[target.platformType] ?: emptyList() } diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/ComposeCompilerArtifactProvider.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/ComposeCompilerArtifactProvider.kt index 4e3ea64f49..7a49001bda 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/ComposeCompilerArtifactProvider.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/ComposeCompilerArtifactProvider.kt @@ -5,33 +5,67 @@ package org.jetbrains.compose.internal -import org.jetbrains.compose.ComposeBuildConfig +import org.jetbrains.compose.ComposeCompilerCompatability +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact -internal class ComposeCompilerArtifactProvider(private val customPluginString: () -> String?) { +private const val KOTLIN_COMPATABILITY_LINK = + "https://github.com/JetBrains/compose-jb/blob/master/VERSIONING.md#kotlin-compatibility" + +internal class ComposeCompilerArtifactProvider( + private val kotlinVersion: String, + customPluginString: () -> String? +) { + fun checkTargetSupported(target: KotlinTarget) { + require(!unsupportedPlatforms.contains(target.platformType)) { + "This version of Compose Multiplatform doesn't support Kotlin " + + "$kotlinVersion for ${target.platformType} target. " + + "Please see $KOTLIN_COMPATABILITY_LINK " + + "to know the latest supported version of Kotlin." + } + } + + private var unsupportedPlatforms: Set = emptySet() + val compilerArtifact: SubpluginArtifact - get() { - val customPlugin = customPluginString() - val customCoordinates = customPlugin?.split(":") - return when (customCoordinates?.size) { - null -> DefaultCompiler.pluginArtifact - 1 -> { - val customVersion = customCoordinates[0] - check(customVersion.isNotBlank()) { "'compose.kotlinCompilerPlugin' cannot be blank!" } - DefaultCompiler.pluginArtifact.copy(version = customVersion) + + init { + val customPlugin = customPluginString() + val customCoordinates = customPlugin?.split(":") + when (customCoordinates?.size) { + null -> { + val version = requireNotNull( + ComposeCompilerCompatability.compilerVersionFor(kotlinVersion) + ) { + "This version of Compose Multiplatform doesn't support Kotlin " + + "$kotlinVersion. " + + "Please see $KOTLIN_COMPATABILITY_LINK " + + "to know the latest supported version of Kotlin." } - 3 -> DefaultCompiler.pluginArtifact.copy( - groupId = customCoordinates[0], - artifactId = customCoordinates[1], - version = customCoordinates[2] + + compilerArtifact = DefaultCompiler.pluginArtifact( + version = version.version ) - else -> error(""" + unsupportedPlatforms = version.unsupportedPlatforms + } + 1 -> { + val customVersion = customCoordinates[0] + check(customVersion.isNotBlank()) { "'compose.kotlinCompilerPlugin' cannot be blank!" } + compilerArtifact = DefaultCompiler.pluginArtifact(version = customVersion) + } + 3 -> compilerArtifact = DefaultCompiler.pluginArtifact( + version = customCoordinates[2], + groupId = customCoordinates[0], + artifactId = customCoordinates[1], + ) + else -> error(""" Illegal format of 'compose.kotlinCompilerPlugin' property. Expected format: either '' or '::' Actual value: '$customPlugin' """.trimIndent()) - } } + } val compilerHostedArtifact: SubpluginArtifact get() = compilerArtifact.run { @@ -47,10 +81,13 @@ internal class ComposeCompilerArtifactProvider(private val customPluginString: ( const val GROUP_ID = "org.jetbrains.compose.compiler" const val ARTIFACT_ID = "compiler" const val HOSTED_ARTIFACT_ID = "compiler-hosted" - const val VERSION = ComposeBuildConfig.composeCompilerVersion - val pluginArtifact: SubpluginArtifact - get() = SubpluginArtifact(groupId = GROUP_ID, artifactId = ARTIFACT_ID, version = VERSION) + fun pluginArtifact( + version: String, + groupId: String = GROUP_ID, + artifactId: String = ARTIFACT_ID, + ): SubpluginArtifact = + SubpluginArtifact(groupId = groupId, artifactId = artifactId, version = version) } } diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt index 0656251938..98cf5e7949 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt @@ -22,7 +22,14 @@ import org.junit.jupiter.api.Test class GradlePluginTest : GradlePluginTestBase() { @Test fun jsMppIsNotBroken() = - with(testProject(TestProjects.jsMpp)) { + with( + testProject( + TestProjects.jsMpp, + testEnvironment = defaultTestEnvironment.copy( + kotlinVersion = TestProperties.composeJsCompilerCompatibleKotlinVersion + ) + ) + ) { gradle(":compileKotlinJs").build().checks { check -> check.taskOutcome(":compileKotlinJs", TaskOutcome.SUCCESS) } diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatabilityTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatabilityTest.kt new file mode 100644 index 0000000000..2d45460d4b --- /dev/null +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatabilityTest.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package org.jetbrains.compose.test.tests.integration + +import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure +import org.jetbrains.compose.test.utils.GradlePluginTestBase +import org.jetbrains.compose.test.utils.TestProjects +import org.jetbrains.compose.test.utils.checks +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class KotlinCompatabilityTest : GradlePluginTestBase() { + @Test + fun testKotlinMpp_1_7_10() = testMpp("1.7.10") + + @Test + fun testKotlinJsMpp_1_7_10() = testJsMpp("1.7.10") + + @Test + fun testKotlinMpp_1_7_20() = testMpp("1.7.20") + + @Test + fun testKotlinJsMpp_1_7_20() { + assertThrows { + testJsMpp("1.7.20") + } + } + + private fun testMpp(kotlinVersion: String) = with( + testProject( + TestProjects.mpp, + testEnvironment = defaultTestEnvironment.copy(kotlinVersion = kotlinVersion) + ) + ) { + val logLine = "Kotlin MPP app is running!" + gradle("run").build().checks { check -> + check.taskOutcome(":run", TaskOutcome.SUCCESS) + check.logContains(logLine) + } + } + + private fun testJsMpp(kotlinVersion: String) = with( + testProject( + TestProjects.jsMpp, + testEnvironment = defaultTestEnvironment.copy(kotlinVersion = kotlinVersion) + ) + ) { + gradle(":compileKotlinJs").build().checks { check -> + check.taskOutcome(":compileKotlinJs", TaskOutcome.SUCCESS) + } + } +} diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/unit/ComposeCompilerArtifactProviderTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/unit/ComposeCompilerArtifactProviderTest.kt index 9c848d2db5..7648fe1bcc 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/unit/ComposeCompilerArtifactProviderTest.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/unit/ComposeCompilerArtifactProviderTest.kt @@ -18,7 +18,7 @@ internal class ComposeCompilerArtifactProviderTest { fun defaultCompilerArtifact() { assertArtifactEquals( Expected.jbCompiler, - Actual.compiler(null) + Actual.compiler(null, TestProperties.composeCompilerCompatibleKotlinVersion) ) } @@ -26,7 +26,7 @@ internal class ComposeCompilerArtifactProviderTest { fun defaultCompilerHostedArtifact() { assertArtifactEquals( Expected.jbCompilerHosted, - Actual.compilerHosted(null) + Actual.compilerHosted(null, TestProperties.composeCompilerCompatibleKotlinVersion) ) } @@ -34,7 +34,7 @@ internal class ComposeCompilerArtifactProviderTest { fun customVersion() { assertArtifactEquals( Expected.jbCompiler.copy(version = "10.20.30"), - Actual.compiler("10.20.30") + Actual.compiler("10.20.30", TestProperties.composeCompilerCompatibleKotlinVersion) ) } @@ -42,7 +42,10 @@ internal class ComposeCompilerArtifactProviderTest { fun customCompiler() { assertArtifactEquals( Expected.googleCompiler.copy(version = "1.3.1"), - Actual.compiler("androidx.compose.compiler:compiler:1.3.1") + Actual.compiler( + "androidx.compose.compiler:compiler:1.3.1", + TestProperties.androidxCompilerCompatibleKotlinVersion + ) ) } @@ -51,7 +54,10 @@ internal class ComposeCompilerArtifactProviderTest { // check that we don't replace artifactId for non-jb compiler assertArtifactEquals( Expected.googleCompiler.copy(version = "1.3.1"), - Actual.compilerHosted("androidx.compose.compiler:compiler:1.3.1") + Actual.compilerHosted( + "androidx.compose.compiler:compiler:1.3.1", + TestProperties.composeCompilerCompatibleKotlinVersion + ) ) } @@ -64,7 +70,7 @@ internal class ComposeCompilerArtifactProviderTest { private fun testIllegalCompiler(pluginString: String?) { try { - Actual.compiler(pluginString) + Actual.compiler(pluginString, "") } catch (e: Exception) { return } @@ -73,11 +79,11 @@ internal class ComposeCompilerArtifactProviderTest { } object Actual { - fun compiler(pluginString: String?) = - ComposeCompilerArtifactProvider { pluginString }.compilerArtifact + fun compiler(pluginString: String?, kotlinVersion: String) = + ComposeCompilerArtifactProvider(kotlinVersion) { pluginString }.compilerArtifact - fun compilerHosted(pluginString: String?) = - ComposeCompilerArtifactProvider { pluginString }.compilerHostedArtifact + fun compilerHosted(pluginString: String?, kotlinVersion: String) = + ComposeCompilerArtifactProvider(kotlinVersion) { pluginString }.compilerHostedArtifact } object Expected { diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/GradlePluginTestBase.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/GradlePluginTestBase.kt index 17bdfaa0fc..9b5d0ba48b 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/GradlePluginTestBase.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/GradlePluginTestBase.kt @@ -17,7 +17,7 @@ abstract class GradlePluginTestBase { val defaultAndroidxCompilerEnvironment: TestEnvironment get() = defaultTestEnvironment.copy( - kotlinVersion = TestKotlinVersion.AndroidxCompatible, + kotlinVersion = TestKotlinVersions.AndroidxCompatible, composeCompilerArtifact = "androidx.compose.compiler:compiler:${TestProperties.androidxCompilerVersion}" ) diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersion.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersions.kt similarity index 50% rename from gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersion.kt rename to gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersions.kt index f2b24d983f..e1f37b09f4 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersion.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestKotlinVersions.kt @@ -5,8 +5,7 @@ package org.jetbrains.compose.test.utils -@Suppress("EnumEntryName") -enum class TestKotlinVersion(val versionString: String) { - Default(TestProperties.composeCompilerCompatibleKotlinVersion), - AndroidxCompatible(TestProperties.androidxCompilerCompatibleKotlinVersion) +object TestKotlinVersions { + val Default = TestProperties.composeCompilerCompatibleKotlinVersion + val AndroidxCompatible = TestProperties.androidxCompilerCompatibleKotlinVersion } \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProject.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProject.kt index dc775b35ce..f02c612027 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProject.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProject.kt @@ -11,7 +11,7 @@ import java.io.File data class TestEnvironment( val workingDir: File, - val kotlinVersion: TestKotlinVersion = TestKotlinVersion.Default, + val kotlinVersion: String = TestKotlinVersions.Default, val composeGradlePluginVersion: String = TestProperties.composeGradlePluginVersion, val composeCompilerArtifact: String? = null ) @@ -41,7 +41,7 @@ class TestProject( val origContent = orig.readText() var newContent = origContent .replace("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER", testEnvironment.composeGradlePluginVersion) - .replace("KOTLIN_VERSION_PLACEHOLDER", testEnvironment.kotlinVersion.versionString) + .replace("KOTLIN_VERSION_PLACEHOLDER", testEnvironment.kotlinVersion) if (testEnvironment.composeCompilerArtifact != null) { newContent = newContent.replace("COMPOSE_COMPILER_ARTIFACT_PLACEHOLDER", testEnvironment.composeCompilerArtifact) } diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProperties.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProperties.kt index 84814a6af7..fe857842f8 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProperties.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/utils/TestProperties.kt @@ -7,10 +7,13 @@ package org.jetbrains.compose.test.utils object TestProperties { val composeCompilerVersion: String - get() = notNullSystemProperty("compose.compiler.version") + get() = notNullSystemProperty("compose.tests.compiler.version") val composeCompilerCompatibleKotlinVersion: String - get() = notNullSystemProperty("compose.compiler.compatible.kotlin.version") + get() = notNullSystemProperty("compose.tests.compiler.compatible.kotlin.version") + + val composeJsCompilerCompatibleKotlinVersion: String + get() = notNullSystemProperty("compose.tests.js.compiler.compatible.kotlin.version") val androidxCompilerVersion: String get() = notNullSystemProperty("compose.tests.androidx.compiler.version") diff --git a/gradle-plugins/gradle.properties b/gradle-plugins/gradle.properties index b604dcff64..e6a53ad112 100644 --- a/gradle-plugins/gradle.properties +++ b/gradle-plugins/gradle.properties @@ -1,13 +1,16 @@ org.gradle.parallel=true kotlin.code.style=official -# __LATEST_COMPOSE_RELEASE_VERSION__ # Default version of Compose Libraries used by Gradle plugin compose.version=1.2.0-beta02 -# Default version of Compose Compiler used by Gradle plugin -compose.compiler.version=1.3.2-alpha01 -# Default version of Kotlin compatible with compose.compiler.version -compose.compiler.compatible.kotlin.version=1.7.20 +# The latest version of Compose Compiler used by Gradle plugin. Used only in tests. +compose.tests.compiler.version=1.3.2-alpha01 +# The latest version of Kotlin compatible with compose.tests.compiler.version. Used only in tests. +compose.tests.compiler.compatible.kotlin.version=1.7.20 +# The latest version of Kotlin compatible with compose.tests.compiler.version for JS target. Used only on CI. +compose.tests.js.compiler.compatible.kotlin.version=1.7.10 +# Version of Compose Compiler published by Google. +# Used to check if our plugin is compatible with it. # https://developer.android.com/jetpack/androidx/releases/compose-kotlin compose.tests.androidx.compiler.version=1.3.1 compose.tests.androidx.compiler.compatible.kotlin.version=1.7.10 diff --git a/tutorials/checker/build.gradle.kts b/tutorials/checker/build.gradle.kts index b1ba6ef0e7..37e8f24dd8 100644 --- a/tutorials/checker/build.gradle.kts +++ b/tutorials/checker/build.gradle.kts @@ -70,7 +70,7 @@ fun maybeFail(tutorial: String, message: String) { } @OptIn(ExperimentalStdlibApi::class) -fun checkDirs(dirs: List, template: String, buildCmd: String = "build") { +fun checkDirs(dirs: List, template: String, buildCmd: String, kotlinVersion: String?) { val snippets = findSnippets(dirs) snippets.forEachIndexed { index, snippet -> println("process snippet $index at ${snippet.file}:${snippet.lineNumber} with $template") @@ -86,7 +86,7 @@ fun checkDirs(dirs: List, template: String, buildCmd: String = "build") add(buildCmd) - project.findProperty("kotlin.version")?.also { + kotlinVersion?.also { add("-Pkotlin.version=$it") } project.findProperty("compose.version")?.also { @@ -110,7 +110,7 @@ fun checkDirs(dirs: List, template: String, buildCmd: String = "build") // NOTICE: currently we use a bit hacky approach, when "```kotlin" marks code that shall be checked, while "``` kotlin" // with whitespace marks code that shall not be checked. tasks.register("check") { - val checks = CheckSpec.createCheckSpecs( + val checks = createCheckSpecs( checkTargets = (project.property("CHECK_TARGET")?.toString() ?: "all").toLowerCase() ) @@ -129,29 +129,36 @@ tasks.register("check") { checkDirs( dirs = subdirs.map { "${check.dir}/$it" }, template = check.template, - buildCmd = check.gradleCmd + buildCmd = check.gradleCmd, + kotlinVersion = check.kotlinVersion ) } } } -data class CheckSpec( - val gradleCmd: String, - val dir: String, - val template: String -) { - companion object { - fun desktop() = CheckSpec(gradleCmd = "build", dir = ".", template = "desktop-template") - fun web() = CheckSpec(gradleCmd = "compileKotlinJs", dir = "Web", template = "web-template") - fun all() = listOf(desktop(), web()) +fun createCheckSpecs(checkTargets: String = "all"): List { + fun desktop() = CheckSpec( + gradleCmd = "build", dir = ".", template = "desktop-template", + kotlinVersion = project.findProperty("kotlin.version")?.toString() + ) + fun web() = CheckSpec( + gradleCmd = "compileKotlinJs", dir = "Web", template = "web-template", + kotlinVersion = project.findProperty("kotlin.js.version")?.toString() ?: + project.findProperty("kotlin.version")?.toString() + ) + fun all() = listOf(desktop(), web()) - fun createCheckSpecs(checkTargets: String = "all"): List { - return when (checkTargets) { - "web" -> listOf(web()) - "desktop" -> listOf(desktop()) - else -> all() - } - } + return when (checkTargets) { + "web" -> listOf(web()) + "desktop" -> listOf(desktop()) + else -> all() } } + +data class CheckSpec( + val gradleCmd: String, + val dir: String, + val template: String, + val kotlinVersion: String? +) \ No newline at end of file