From 92bfb839eaefe841a3161116f82e255a8986ee8d Mon Sep 17 00:00:00 2001 From: Konstantin Tskhovrebov Date: Tue, 12 Jan 2021 20:00:59 +0300 Subject: [PATCH] Update Kotlin plugin version parser for new semantic GitOrigin-RevId: 269a83c23477f1d3f5d004f36950fbf9dd32ab33 --- .../jetbrains/kotlin/idea/PlatformVersion.kt | 11 +- .../idea/KotlinPluginCompatibilityVerifier.kt | 55 ++++++-- ...patibilityVerifierVersionComparisonTest.kt | 122 ++++++++++++------ 3 files changed, 134 insertions(+), 54 deletions(-) diff --git a/plugins/kotlin/common/src/org/jetbrains/kotlin/idea/PlatformVersion.kt b/plugins/kotlin/common/src/org/jetbrains/kotlin/idea/PlatformVersion.kt index 7f5cf8b04220..e1913c35c7dc 100644 --- a/plugins/kotlin/common/src/org/jetbrains/kotlin/idea/PlatformVersion.kt +++ b/plugins/kotlin/common/src/org/jetbrains/kotlin/idea/PlatformVersion.kt @@ -7,8 +7,10 @@ data class PlatformVersion(val platform: Platform, val version: String /* 3.1 or companion object { fun parse(platformString: String): PlatformVersion? { for (platform in Platform.values()) { - if (platformString.startsWith(platform.qualifier)) { - return PlatformVersion(platform, platformString.drop(platform.qualifier.length)) + for (qualifier in platform.qualifiers) { + if (platformString.startsWith(qualifier)) { + return PlatformVersion(platform, platformString.drop(qualifier.length)) + } } } @@ -29,8 +31,9 @@ data class PlatformVersion(val platform: Platform, val version: String /* 3.1 or fun isAndroidStudio(): Boolean = getCurrent()?.platform == Platform.ANDROID_STUDIO } - enum class Platform(val qualifier: String, val presentableText: String) { - IDEA("IJ", "IDEA"), ANDROID_STUDIO("Studio", "Android Studio") + enum class Platform(val qualifiers: List, val presentableText: String) { + IDEA(listOf("IJ"), "IDEA"), + ANDROID_STUDIO(listOf("Studio", "AS"), "Android Studio") } override fun toString() = platform.presentableText + " " + version diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt index 0599cfd86a85..d6bc93cb580c 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/KotlinPluginCompatibilityVerifier.kt @@ -24,39 +24,72 @@ object KotlinPluginCompatibilityVerifier { } interface KotlinPluginVersion { + val kotlinVersion: String // 1.2.3 + val status: String? val platformVersion: PlatformVersion val buildNumber: String? companion object { fun parse(version: String): KotlinPluginVersion? { - return OldKotlinPluginVersion.parse(version) ?: KidKotlinPluginVersion.parse(version) + return OldKotlinPluginVersion.parse(version) ?: NewKotlinPluginVersion.parse(version) } fun getCurrent(): KotlinPluginVersion? = parse(KotlinPluginUtil.getPluginVersion()) } } -data class KidKotlinPluginVersion( +data class NewKotlinPluginVersion( + override val kotlinVersion: String, // 1.2.3 + override val status: String?, // release, eap, rc + val kotlinBuildNumber: String?, override val buildNumber: String?, // 53 override val platformVersion: PlatformVersion, + val patchNumber: String? ) : KotlinPluginVersion { companion object { - private val KID_KOTLIN_VERSION_REGEX = "([\\d]{3}).([\\d]+)-kid".toRegex() + //203-1.4.20-dev-4575-IJ1234.45-1 + private const val KID_KOTLIN_VERSION_REGEX_STRING = + "^(\\d{3})" + // IDEA_VERSION_ID, like '202' + "-([\\d.]+)" + // COMPILER_VERSION name, like '1.4.10' + "(?:-([A-Za-z]+))?" + // (Optional) COMPILER_VERSION milestone, like 'eap/dev/release' + "(?:-(\\d+))?" + // (Optional) COMPILER_VERSION build number, like '4242' + "-([A-Z]{2})" + // Platform kind, like 'IJ' + "(?:(\\d+)\\.)?" + // (Optional) BRANCH_SUFFIX, like '1234' + "(\\d*)" + // Build number, like '45' + "(?:-(\\d+))?" // (Optional) Tooling update, like '-1' - fun parse(version: String): KidKotlinPluginVersion? { + private val KID_KOTLIN_VERSION_REGEX = KID_KOTLIN_VERSION_REGEX_STRING.toRegex() + + fun parse(version: String): NewKotlinPluginVersion? { val matchResult = KID_KOTLIN_VERSION_REGEX.matchEntire(version) ?: return null - val (platformNumber, buildNumber) = matchResult.destructured - val platformVersionText = "20" + platformNumber.take(2) + "." + platformNumber.takeLast(1) - val platformVersion = PlatformVersion(PlatformVersion.Platform.IDEA, platformVersionText) - return KidKotlinPluginVersion(buildNumber, platformVersion) + val (ideaVersionId, kotlinVersion, kotlinMilestone, kotlinBuild, ideaKind, branchSuffix, buildNumber, update) = matchResult.destructured + + val platformVersionString = buildString { + append(ideaKind) + append(ideaVersionId) + branchSuffix.nullize()?.let { + append(".") + append(it) + } + } + val platformVersion = PlatformVersion.parse(platformVersionString) ?: return null + + return NewKotlinPluginVersion( + kotlinVersion, + kotlinMilestone.nullize(), + kotlinBuild.nullize(), + buildNumber.nullize(), + platformVersion, + update.nullize() + ) } } } data class OldKotlinPluginVersion( - val kotlinVersion: String, // 1.2.3 + override val kotlinVersion: String, // 1.2.3 val milestone: String?, // M1 - val status: String?, // release, eap, rc + override val status: String?, // release, eap, rc override val buildNumber: String?, // 53 override val platformVersion: PlatformVersion, val patchNumber: String // usually '1' @@ -79,7 +112,7 @@ data class OldKotlinPluginVersion( return OldKotlinPluginVersion( kotlinVersion, milestone.nullize(), - status, + status.nullize(), buildNumber.nullize(), platformVersion, patchNumber diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt index 2f3cbc5f277d..af15612ae823 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/test/CompatibilityVerifierVersionComparisonTest.kt @@ -12,16 +12,20 @@ import org.junit.runner.RunWith @RunWith(JUnit38ClassRunner::class) class CompatibilityVerifierVersionComparisonTest : LightPlatformTestCase() { - fun testKotlinVersionParsing() { - val version = OldKotlinPluginVersion.parse("1.2.40-dev-193-Studio3.0-1") ?: throw AssertionError("Version should not be null") + fun testValidVersion() { + testVersion("203-1.4.20-dev-4575-IJ1234.45-1", "1.4.20", "dev", PlatformVersion.Platform.IDEA, "203.1234", "45") + testVersion("211-1.4.30-release-AS193", "1.4.30", "release", PlatformVersion.Platform.ANDROID_STUDIO, "211", "193") + testVersion("202-1.4.30-AS", "1.4.30", null, PlatformVersion.Platform.ANDROID_STUDIO, "202", null) + testVersion("1.2.40-dev-193-Studio3.0-1", "1.2.40", "dev", PlatformVersion.Platform.ANDROID_STUDIO, "3.0", "193") + testVersion("1.4-M1-42-IJ2020.1-1", "1.4", null, PlatformVersion.Platform.IDEA, "2020.1", "42") + testVersion("1.4-M1-eap-27-IJ2020.1-1", "1.4", "eap", PlatformVersion.Platform.IDEA, "2020.1", "27") + } - assertEquals("1.2.40", version.kotlinVersion) - assertNull(version.milestone) - assertEquals("dev", version.status) - assertEquals("193", version.buildNumber) - assertEquals(PlatformVersion.Platform.ANDROID_STUDIO, version.platformVersion.platform) - assertEquals("3.0", version.platformVersion.version) - assertEquals("1", version.patchNumber) + fun testInvalidVersion() { + testInvalidVersion("203-1.4.20-dev-M5-4575-IJ1234.45-1") + testInvalidVersion("203-1.4.20-IJ.45") + testInvalidVersion("203-1.4.20-1234.45") + testInvalidVersion("1.4-release-M5-IJ2020.1-1") } fun testReleaseVersionDoesntHaveBuildNumber() { @@ -30,35 +34,6 @@ class CompatibilityVerifierVersionComparisonTest : LightPlatformTestCase() { assertNull(version.buildNumber) } - fun testMilestoneVersion() { - val version = OldKotlinPluginVersion.parse("1.4-M1-eap-27-IJ2020.1-1") ?: throw AssertionError("Version should not be null") - - assertEquals("1.4", version.kotlinVersion) - assertEquals("M1", version.milestone) - assertEquals("eap", version.status) - assertEquals("27", version.buildNumber) - assertEquals(PlatformVersion.Platform.IDEA, version.platformVersion.platform) - assertEquals("2020.1", version.platformVersion.version) - assertEquals("1", version.patchNumber) - } - - fun testMilestoneVersionWithoutStatus() { - val version = OldKotlinPluginVersion.parse("1.4-M1-42-IJ2020.1-1") ?: throw AssertionError("Version should not be null") - - assertEquals("1.4", version.kotlinVersion) - assertEquals("M1", version.milestone) - assertEquals("42", version.buildNumber) - assertEquals(PlatformVersion.Platform.IDEA, version.platformVersion.platform) - assertEquals("2020.1", version.platformVersion.version) - assertEquals("1", version.patchNumber) - } - - fun testInvalidVersion() { - val version = OldKotlinPluginVersion.parse("1.4-release-M5-IJ2020.1-1") - - assertNull(version) - } - fun testPlatformVersionParsing() { PlatformVersion.getCurrent() ?: throw AssertionError("Version should not be null") } @@ -68,6 +43,75 @@ class CompatibilityVerifierVersionComparisonTest : LightPlatformTestCase() { if (pluginVersion == "@snapshot@") return val currentVersion = KotlinPluginVersion.getCurrent() - assert(currentVersion is KidKotlinPluginVersion) { "Can not parse current Kotlin Plugin version: $pluginVersion" } + assert(currentVersion is NewKotlinPluginVersion) { "Can not parse current Kotlin Plugin version: $pluginVersion" } + } + + + fun testNewParser() { + val version = KotlinPluginVersion.parse("203-1.4.20-dev-4575-IJ1234.45-7") as? NewKotlinPluginVersion ?: throw AssertionError("Version should not be null") + + assertEquals("1.4.20", version.kotlinVersion) + assertEquals("dev", version.status) + assertEquals("4575", version.kotlinBuildNumber) + assertEquals("45", version.buildNumber) + assertEquals(PlatformVersion.Platform.IDEA, version.platformVersion.platform) + assertEquals("203.1234", version.platformVersion.version) + assertEquals("7", version.patchNumber) + } + + fun testOldParser() { + val version = KotlinPluginVersion.parse("1.2.40-dev-193-Studio3.0-1") as? OldKotlinPluginVersion ?: throw AssertionError("Version should not be null") + + assertEquals("1.2.40", version.kotlinVersion) + assertNull(version.milestone) + assertEquals("dev", version.status) + assertEquals("193", version.buildNumber) + assertEquals(PlatformVersion.Platform.ANDROID_STUDIO, version.platformVersion.platform) + assertEquals("3.0", version.platformVersion.version) + assertEquals("1", version.patchNumber) + } + + fun testOldParserMilestoneVersion() { + val version = OldKotlinPluginVersion.parse("1.4-M1-eap-27-IJ2020.1-1") ?: throw AssertionError("Version should not be null") + + assertEquals("1.4", version.kotlinVersion) + assertEquals("M1", version.milestone) + assertEquals("eap", version.status) + assertEquals("27", version.buildNumber) + assertEquals(PlatformVersion.Platform.IDEA, version.platformVersion.platform) + assertEquals("2020.1", version.platformVersion.version) + assertEquals("1", version.patchNumber) + } + + fun testOldParserMilestoneVersionWithoutStatus() { + val version = OldKotlinPluginVersion.parse("1.4-M1-42-IJ2020.1-1") ?: throw AssertionError("Version should not be null") + + assertEquals("1.4", version.kotlinVersion) + assertEquals("M1", version.milestone) + assertEquals("42", version.buildNumber) + assertEquals(PlatformVersion.Platform.IDEA, version.platformVersion.platform) + assertEquals("2020.1", version.platformVersion.version) + assertEquals("1", version.patchNumber) + } + + private fun testVersion( + version: String, + expectedKotlinVersion: String, + expectedStatus: String?, + expectedPlatform: PlatformVersion.Platform, + expectedPlatformVersion: String, + expectedBuildNumber: String? + ) { + val parsed = KotlinPluginVersion.parse(version) ?: throw AssertionError("Version should not be null") + + assertEquals(expectedKotlinVersion, parsed.kotlinVersion) + assertEquals(expectedStatus, parsed.status) + assertEquals(expectedPlatform, parsed.platformVersion.platform) + assertEquals(expectedPlatformVersion, parsed.platformVersion.version) + assertEquals(expectedBuildNumber, parsed.buildNumber) + } + + private fun testInvalidVersion(version: String) { + assertNull(KotlinPluginVersion.parse(version)) } } \ No newline at end of file