From f09b149b5bf6834609dec1eb70789539c5e61896 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Fri, 10 Feb 2023 14:59:33 +0100 Subject: Update Kotlin to 1.8.10 (#2797) --- .../gradle/kotlin/KotlinGradlePluginVersion.kt | 30 +++++++++ .../dokka/gradle/kotlin/kotlinClasspathUtils.kt | 44 +++++++++---- .../gradle/kotlin/KotlinGradlePluginVersionTest.kt | 75 ++++++++++++++++++++++ 3 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersion.kt create mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt (limited to 'runners/gradle-plugin/src') diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersion.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersion.kt new file mode 100644 index 00000000..bd2de4bd --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersion.kt @@ -0,0 +1,30 @@ +package org.jetbrains.dokka.gradle.kotlin + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion + +internal typealias KotlinGradlePluginVersion = KotlinVersion + +internal fun Project.getKgpVersion(): KotlinGradlePluginVersion? = parseKotlinVersion(this.getKotlinPluginVersion()) + +/** + * Accepts a full version string that contains the major, minor + * and patch versions divided by dots, such as "1.7.10". + * + * Does NOT parse and store custom suffixes, so `1.8.20-RC2` + * or `1.8.20-dev-42` will be viewed as `1.8.20`. + */ +internal fun parseKotlinVersion(fullVersionString: String): KotlinVersion? { + val versionParts = fullVersionString + .split(".", "-", limit = 4) + .takeIf { parts -> parts.size >= 3 && parts.subList(0, 3).all { it.isNumeric() } } + ?: return null + + return KotlinVersion( + major = versionParts[0].toInt(), + minor = versionParts[1].toInt(), + patch = versionParts[2].toInt() + ) +} + +private fun String.isNumeric() = this.isNotEmpty() && this.all { it.isDigit() } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt index 9ef268f2..ed77324f 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/kotlin/kotlinClasspathUtils.kt @@ -3,7 +3,6 @@ package org.jetbrains.dokka.gradle.kotlin import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.jetbrains.dokka.gradle.isAndroidTarget -import org.jetbrains.dokka.utilities.cast import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation @@ -25,7 +24,7 @@ internal fun Project.classpathOf(sourceSet: KotlinSourceSet): FileCollection { * Ignore [org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation] for `commonMain` sourceSet with name `main` */ .filterNot { compilation -> isHMPPEnabled && compilation is KotlinCommonCompilation && compilation.name == "main" } - .map { compilation -> compileClasspathOf(compilation) } + .map { compilation -> compilation.compileClasspathOf(project = this) } .reduce { acc, fileCollection -> acc + fileCollection } } else { sourceSet.withAllDependentSourceSets() @@ -35,19 +34,38 @@ internal fun Project.classpathOf(sourceSet: KotlinSourceSet): FileCollection { } } -private fun Project.compileClasspathOf(compilation: KotlinCompilation): FileCollection { - if (compilation.target.isAndroidTarget()) { - // This is a workaround for https://youtrack.jetbrains.com/issue/KT-33893 - @Suppress("DEPRECATION") // for compatibility - return compilation.compileKotlinTask.cast().classpath +private fun KotlinCompilation.compileClasspathOf(project: Project): FileCollection { + if (this.target.isAndroidTarget()) { // Workaround for https://youtrack.jetbrains.com/issue/KT-33893 + return this.classpathOf(project) } - val platformDependencyFiles: FileCollection = (compilation as? AbstractKotlinNativeCompilation) + val platformDependencyFiles: FileCollection = (this as? AbstractKotlinNativeCompilation) ?.target?.project?.configurations - ?.findByName(compilation.defaultSourceSet.implementationMetadataConfigurationName) - ?: files() + ?.findByName(this.defaultSourceSet.implementationMetadataConfigurationName) + ?: project.files() - return compilation.compileDependencyFiles + platformDependencyFiles + - @Suppress("DEPRECATION") // for compatibility - (compilation.compileKotlinTask.run { this as? KotlinCompile }?.classpath ?: files()) + return this.compileDependencyFiles + platformDependencyFiles + this.classpathOf(project) +} + +private fun KotlinCompilation.classpathOf(project: Project): FileCollection { + val kgpVersion = project.getKgpVersion() + val kotlinCompile = this.getKotlinCompileTask(kgpVersion) ?: return project.files() + + val shouldKeepBackwardsCompatibility = (kgpVersion != null && kgpVersion < KotlinGradlePluginVersion(1, 7, 0)) + return if (shouldKeepBackwardsCompatibility) { + @Suppress("DEPRECATION_ERROR") + kotlinCompile.classpath // deprecated with error since 1.8.0, left for compatibility with < Kotlin 1.7 + } else { + kotlinCompile.libraries // introduced in 1.7.0 + } +} + +private fun KotlinCompilation.getKotlinCompileTask(kgpVersion: KotlinGradlePluginVersion? = null): KotlinCompile? { + val shouldKeepBackwardsCompatibility = (kgpVersion != null && kgpVersion < KotlinGradlePluginVersion(1, 8, 0)) + return if (shouldKeepBackwardsCompatibility) { + @Suppress("DEPRECATION") // for `compileKotlinTask` property, deprecated with warning since 1.8.0 + this.compileKotlinTask as? KotlinCompile + } else { + this.compileTaskProvider.get() as? KotlinCompile // introduced in 1.8.0 + } } diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt new file mode 100644 index 00000000..b24524f1 --- /dev/null +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/kotlin/KotlinGradlePluginVersionTest.kt @@ -0,0 +1,75 @@ +package org.jetbrains.dokka.gradle.kotlin + +import kotlin.test.* + +class KotlinGradlePluginVersionTest { + + @Test + fun `should parse versions`() { + assertParsedVersion(input = "1.7.22", expectedMajor = 1, expectedMinor = 7, expectedPatch = 22) + assertParsedVersion(input = "2.0.0", expectedMajor = 2, expectedMinor = 0, expectedPatch = 0) + assertParsedVersion(input = "1.8.22-RC2", expectedMajor = 1, expectedMinor = 8, expectedPatch = 22) + assertParsedVersion(input = "1.5.22-Beta", expectedMajor = 1, expectedMinor = 5, expectedPatch = 22) + assertParsedVersion(input = "2.7.22-mercury-500", expectedMajor = 2, expectedMinor = 7, expectedPatch = 22) + assertParsedVersion(input = "1.7.100-dev-800", expectedMajor = 1, expectedMinor = 7, expectedPatch = 100) + } + + @Test + fun `should return null on non parsable string`() { + assertNull(parse("1.7")) + assertNull(parse("1")) + assertNull(parse("6")) + assertNull(parse("17.0")) + assertNull(parse("1..7.0")) + assertNull(parse("1.7-Beta")) + assertNull(parse("1.7.0Beta")) + } + + @Test + fun `should compare simple versions`() { + assertEquals(0, KotlinGradlePluginVersion(1, 7, 0).compareTo(KotlinGradlePluginVersion(1, 7, 0))) + + assertTrue(KotlinGradlePluginVersion(1, 6, 10) >= KotlinGradlePluginVersion(1, 6, 10)) + assertTrue(KotlinGradlePluginVersion(1, 6, 10) < KotlinGradlePluginVersion(1, 6, 20)) + assertTrue(KotlinGradlePluginVersion(1, 6, 10) > KotlinGradlePluginVersion(1, 6, 0)) + + assertTrue(KotlinGradlePluginVersion(1, 4, 32) <= KotlinGradlePluginVersion(1, 4, 32)) + assertTrue(KotlinGradlePluginVersion(1, 4, 32) < KotlinGradlePluginVersion(1, 6, 20)) + assertTrue(KotlinGradlePluginVersion(1, 4, 32) > KotlinGradlePluginVersion(1, 3, 0)) + + assertTrue(KotlinGradlePluginVersion(2, 1, 0) > KotlinGradlePluginVersion(1, 8, 0)) + assertTrue(KotlinGradlePluginVersion(1, 5, 31) < KotlinGradlePluginVersion(1, 7, 0)) + } + + @Test + fun `should compare custom dev versions with trailing strings`() { + assertEquals(0, KotlinGradlePluginVersion(1, 7, 0).compareTo(parseNotNull("1.7.0"))) + + assertTrue(KotlinGradlePluginVersion(1, 6, 10) >= parseNotNull("1.6.10-Beta")) + assertTrue(KotlinGradlePluginVersion(1, 6, 10) < parseNotNull("1.6.20")) + assertTrue(KotlinGradlePluginVersion(1, 6, 10) > parseNotNull("1.6.0-RC2")) + + assertTrue(KotlinGradlePluginVersion(1, 4, 32) <= parseNotNull("1.4.32-dev-142")) + assertTrue(KotlinGradlePluginVersion(1, 4, 32) < parseNotNull("1.6.20-Beta")) + assertTrue(KotlinGradlePluginVersion(1, 4, 32) > parseNotNull("1.3.0-RC")) + + assertTrue(KotlinGradlePluginVersion(2, 1, 0) > parseNotNull("1.8.0-mercury-500")) + } + + private fun assertParsedVersion( + input: String, + expectedMajor: Int, + expectedMinor: Int, + expectedPatch: Int + ) { + val kgpVersion = parseNotNull(input) + assertEquals(expectedMajor, kgpVersion.major) + assertEquals(expectedMinor, kgpVersion.minor) + assertEquals(expectedPatch, kgpVersion.patch) + assertEquals(KotlinGradlePluginVersion(expectedMajor, expectedMinor, expectedPatch), kgpVersion) + } + + private fun parseNotNull(input: String): KotlinGradlePluginVersion = assertNotNull(parse(input)) + + private fun parse(input: String): KotlinGradlePluginVersion? = parseKotlinVersion(input) +} -- cgit