From 7d5b3d3628d68c92e85528112039d56c2bb72ba4 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Mon, 19 Sep 2022 11:34:47 +0200 Subject: [PATCH] [Gradle] KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck: Use AndroidGradlePluginVersion tool ^KT-54033 WIP --- ...oidGradlePluginCompatibilityHealthCheck.kt | 104 ++++++------------ ...radlePluginCompatibilityHealthCheckTest.kt | 82 ++++++-------- 2 files changed, 65 insertions(+), 121 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.kt index 315b47c792e..6d379e8afe9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.gradle.plugin -import com.android.Version import org.gradle.api.Project import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN @@ -18,8 +17,8 @@ import java.util.concurrent.atomic.AtomicBoolean internal object KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck { val compatibleAndroidGradlePluginVersionRange = AndroidGradlePluginVersionRange( - minSupportedVersion = AndroidGradlePluginVersion(4, 0), - maxSupportedVersion = AndroidGradlePluginVersion(7, 3) + minSupportedVersion = AndroidGradlePluginVersionRange.Version(4, 0), + maxSupportedVersion = AndroidGradlePluginVersionRange.Version(7, 3) ) /** @@ -32,81 +31,47 @@ internal object KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck { */ const val PROPERTY_KEY_EXECUTED_PROJECT_PATHS = "KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.executedProjects" - data class AndroidGradlePluginVersion(val major: Int, val minor: Int) : Comparable { - override fun compareTo(other: AndroidGradlePluginVersion): Int { - if (this.major != other.major) return this.major.compareTo(other.major) - return this.minor.compareTo(other.minor) - } - - override fun toString(): String { - return "$major.$minor" - } - } - data class AndroidGradlePluginVersionRange( - val minSupportedVersion: AndroidGradlePluginVersion, - val maxSupportedVersionMajor: Int, - val maxSupportedVersionMinor: Int? + val minSupportedVersion: Version, + val maxSupportedVersion: Version ) { - constructor( - minSupportedVersionMajor: Int, - minSupportedVersionMinor: Int, - maxSupportedVersionMajor: Int, - maxSupportedVersionMinor: Int? = null - ) : this( - minSupportedVersion = AndroidGradlePluginVersion(minSupportedVersionMajor, minSupportedVersionMinor), - maxSupportedVersionMajor = maxSupportedVersionMajor, - maxSupportedVersionMinor = maxSupportedVersionMinor - ) constructor( - minSupportedVersion: AndroidGradlePluginVersion, - maxSupportedVersion: AndroidGradlePluginVersion + minSupportedVersionMajor: Int, minSupportedVersionMinor: Int = 0, + maxSupportedVersionMajor: Int, maxSupportedVersionMinor: Int = 0 ) : this( - minSupportedVersion = minSupportedVersion, - maxSupportedVersionMajor = maxSupportedVersion.major, - maxSupportedVersionMinor = maxSupportedVersion.minor + minSupportedVersion = Version(minSupportedVersionMajor, minSupportedVersionMinor), + maxSupportedVersion = Version(maxSupportedVersionMajor, maxSupportedVersionMinor) ) + data class Version(val major: Int, val minor: Int) + fun isTooHigh(version: AndroidGradlePluginVersion): Boolean { - return if (maxSupportedVersionMinor != null) - version > AndroidGradlePluginVersion(maxSupportedVersionMajor, maxSupportedVersionMinor) - else version.major > maxSupportedVersionMajor + if (version.major > this.maxSupportedVersion.major) return true + if (version.major < this.maxSupportedVersion.major) return false + return version.minor > this.maxSupportedVersion.minor } fun isTooLow(version: AndroidGradlePluginVersion): Boolean { - return version < minSupportedVersion + if (version.major < this.minSupportedVersion.major) return true + if (version.major > this.minSupportedVersion.major) return false + return version.minor < this.minSupportedVersion.minor } } - interface AndroidGradlePluginStringProvider { - fun getAndroidGradlePluginString(): String? + interface AndroidGradlePluginVersionProvider { + fun getAndroidGradlePluginVersion(): AndroidGradlePluginVersion? - object Default : AndroidGradlePluginStringProvider { - override fun getAndroidGradlePluginString(): String? = - runCatching { Version.ANDROID_GRADLE_PLUGIN_VERSION }.getOrElse { return null } - } - } - - interface AndroidGradlePluginVersionParser { - fun parseVersionString(version: String): AndroidGradlePluginVersion? - - object Default : AndroidGradlePluginVersionParser { - private val versionRegex = Regex("""(\d+)\.(\d+)(\.\d+)?(.*)""") - - override fun parseVersionString(version: String): AndroidGradlePluginVersion? { - val matchResult = versionRegex.matchEntire(version) ?: return null - val major = matchResult.groups[1]?.value?.toIntOrNull() ?: return null - val minor = matchResult.groups[2]?.value?.toIntOrNull() ?: return null - return AndroidGradlePluginVersion(major, minor) + object Default : AndroidGradlePluginVersionProvider { + override fun getAndroidGradlePluginVersion(): AndroidGradlePluginVersion? { + return AndroidGradlePluginVersion.current } } } fun Project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheckWhenAndroidIsApplied( warningLogger: (warningMessage: String) -> Unit = project.logger::warn, - androidGradlePluginStringProvider: AndroidGradlePluginStringProvider = AndroidGradlePluginStringProvider.Default, - androidGradlePluginVersionParser: AndroidGradlePluginVersionParser = AndroidGradlePluginVersionParser.Default + androidGradlePluginVersionProvider: AndroidGradlePluginVersionProvider = AndroidGradlePluginVersionProvider.Default ) { val emittedMessages = project.getOrPutRootProjectProperty(PROPERTY_KEY_EMITTED_MESSAGES) { mutableSetOf() } @@ -121,7 +86,7 @@ internal object KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck { plugins.withId(id) { if (!executed.getAndSet(true)) { runMultiplatformAndroidGradlePluginCompatibilityHealthCheck( - deduplicateWarningMessageLogger, androidGradlePluginStringProvider, androidGradlePluginVersionParser + deduplicateWarningMessageLogger, androidGradlePluginVersionProvider ) } } @@ -130,8 +95,7 @@ internal object KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck { fun Project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheck( warningLogger: (warningMessage: String) -> Unit = project.logger::warn, - androidGradlePluginStringProvider: AndroidGradlePluginStringProvider = AndroidGradlePluginStringProvider.Default, - androidGradlePluginVersionParser: AndroidGradlePluginVersionParser = AndroidGradlePluginVersionParser.Default, + androidGradlePluginVersionProvider: AndroidGradlePluginVersionProvider = AndroidGradlePluginVersionProvider.Default, compatibleAndroidGradlePluginVersionRange: AndroidGradlePluginVersionRange = KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.compatibleAndroidGradlePluginVersionRange ) = runProjectConfigurationHealthCheck check@{ @@ -141,26 +105,22 @@ internal object KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck { /* Return when no android plugin is applied */ findAppliedAndroidPluginIdOrNull() ?: return@check - val androidGradlePluginVersionString = androidGradlePluginStringProvider.getAndroidGradlePluginString() - ?: return warningLogger(Messages.FAILED_GETTING_ANDROID_GRADLE_PLUGIN_VERSION_STRING) - - val androidGradlePluginVersion = androidGradlePluginVersionParser.parseVersionString(androidGradlePluginVersionString) - ?: return warningLogger(Messages.failedParsingAndroidGradlePluginVersion(androidGradlePluginVersionString)) + val androidGradlePluginVersion = androidGradlePluginVersionProvider.getAndroidGradlePluginVersion() + ?: return warningLogger(Messages.failedGettingAndroidGradlePluginVersion()) if (compatibleAndroidGradlePluginVersionRange.isTooLow(androidGradlePluginVersion)) { - warningLogger(Messages.androidGradlePluginVersionTooLow(androidGradlePluginVersionString)) + warningLogger(Messages.androidGradlePluginVersionTooLow(androidGradlePluginVersion.toString())) } if (compatibleAndroidGradlePluginVersionRange.isTooHigh(androidGradlePluginVersion)) { - warningLogger(Messages.androidGradlePluginVersionTooHigh(androidGradlePluginVersionString)) + warningLogger(Messages.androidGradlePluginVersionTooHigh(androidGradlePluginVersion.toString())) } } object Messages { - const val FAILED_GETTING_ANDROID_GRADLE_PLUGIN_VERSION_STRING = "Failed to get the version of the applied Android Gradle Plugin" - fun failedParsingAndroidGradlePluginVersion(androidGradlePluginVersionString: String) = - "w: Failed to parse the version of the applied Android Gradle Plugin: $androidGradlePluginVersionString" + fun failedGettingAndroidGradlePluginVersion() = + "w: Failed to get AndroidGradlePluginVersion" fun androidGradlePluginVersionTooLow(androidGradlePluginVersionString: String) = createCompatibilityWarningMessage( "The applied Android Gradle Plugin version ($androidGradlePluginVersionString) is lower than the minimum supported" @@ -181,8 +141,8 @@ internal object KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck { ) appendLine( "Maximum tested Android Gradle Plugin version: " + - "${compatibleAndroidGradlePluginVersionRange.maxSupportedVersionMajor}." + - "${compatibleAndroidGradlePluginVersionRange.maxSupportedVersionMinor ?: "*"}" + "${compatibleAndroidGradlePluginVersionRange.maxSupportedVersion.major}." + + "${compatibleAndroidGradlePluginVersionRange.maxSupportedVersion.minor}" ) appendLine("To suppress this message add $KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN=true to your gradle.properties") } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest.kt index d8039ea6d71..8bfb78a5a94 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest.kt @@ -9,9 +9,8 @@ package org.jetbrains.kotlin.gradle import com.android.build.gradle.LibraryPlugin import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.AndroidGradlePluginStringProvider -import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.AndroidGradlePluginVersion -import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.AndroidGradlePluginVersionParser +import org.jetbrains.kotlin.gradle.plugin.AndroidGradlePluginVersion +import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.AndroidGradlePluginVersionProvider import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.AndroidGradlePluginVersionRange import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.Messages import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck.PROPERTY_KEY_EXECUTED_PROJECT_PATHS @@ -42,8 +41,11 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { } } - class FixedAndroidGradlePluginVersionProvider(private val version: String?) : AndroidGradlePluginStringProvider { - override fun getAndroidGradlePluginString(): String? = version + internal class FixedAndroidGradlePluginVersionProvider(private val version: String?) : AndroidGradlePluginVersionProvider { + override fun getAndroidGradlePluginVersion(): AndroidGradlePluginVersion? { + if (version == null) return null + return AndroidGradlePluginVersion(version) + } } @Test @@ -80,8 +82,8 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { @Test fun `test - version too high - major`() { val androidGradlePluginVersion = AndroidGradlePluginVersion( - major = compatibleAndroidGradlePluginVersionRange.maxSupportedVersionMajor + 1, - minor = compatibleAndroidGradlePluginVersionRange.maxSupportedVersionMinor ?: 0 + major = compatibleAndroidGradlePluginVersionRange.maxSupportedVersion.major + 1, + minor = compatibleAndroidGradlePluginVersionRange.maxSupportedVersion.minor ) project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheck( @@ -98,8 +100,8 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { val androidGradlePluginVersion = AndroidGradlePluginVersion(2, 1) val compatibleAndroidGradlePluginVersionRange = AndroidGradlePluginVersionRange( - minSupportedVersion = AndroidGradlePluginVersion(1, 0), - maxSupportedVersion = AndroidGradlePluginVersion(2, 0) + minSupportedVersion = AndroidGradlePluginVersionRange.Version(1, 0), + maxSupportedVersion = AndroidGradlePluginVersionRange.Version(2, 0) ) project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheck( @@ -120,27 +122,10 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { ) assertEquals( - Messages.FAILED_GETTING_ANDROID_GRADLE_PLUGIN_VERSION_STRING, assertSingleWarningMessage() + Messages.failedGettingAndroidGradlePluginVersion(), assertSingleWarningMessage() ) } - @Test - fun `test - failed parsing Android Gradle Plugin version`() { - val androidGradlePluginVersion = compatibleAndroidGradlePluginVersionRange.minSupportedVersion.toString() - - val failingParser = object : AndroidGradlePluginVersionParser { - override fun parseVersionString(version: String): AndroidGradlePluginVersion? { - return null - } - } - - project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheck( - testLogger, FixedAndroidGradlePluginVersionProvider(androidGradlePluginVersion), failingParser - ) - - assertEquals(Messages.failedParsingAndroidGradlePluginVersion(androidGradlePluginVersion), assertSingleWarningMessage()) - } - @Test fun `test - nowarn property`() { project.propertiesExtension.set(PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN, "true") @@ -158,14 +143,14 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { /* Test with too high AGP version */ project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheck( testLogger, - FixedAndroidGradlePluginVersionProvider("${compatibleAndroidGradlePluginVersionRange.maxSupportedVersionMajor + 1}.0") + FixedAndroidGradlePluginVersionProvider("${compatibleAndroidGradlePluginVersionRange.maxSupportedVersion.major + 1}.0") ) assertNoWarningMessage() /* Re-enable the check and test with missing AGP version */ project.propertiesExtension.set(PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN, "false") project.runMultiplatformAndroidGradlePluginCompatibilityHealthCheck(testLogger, FixedAndroidGradlePluginVersionProvider(null)) - assertEquals(Messages.FAILED_GETTING_ANDROID_GRADLE_PLUGIN_VERSION_STRING, assertSingleWarningMessage()) + assertEquals(Messages.failedGettingAndroidGradlePluginVersion(), assertSingleWarningMessage()) } @Test @@ -177,35 +162,34 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { assertNoWarningMessage() } - val minSupportedVersion = compatibleAndroidGradlePluginVersionRange.minSupportedVersion + val minSupportedVersion = compatibleAndroidGradlePluginVersionRange.minSupportedVersion.run { + AndroidGradlePluginVersion(major, minor) + } val midSupportedVersion = minSupportedVersion.copy(minor = minSupportedVersion.minor + 1) val maxSupportedVersion = AndroidGradlePluginVersion( - compatibleAndroidGradlePluginVersionRange.maxSupportedVersionMajor, - compatibleAndroidGradlePluginVersionRange.maxSupportedVersionMinor ?: 0 + compatibleAndroidGradlePluginVersionRange.maxSupportedVersion.major, + compatibleAndroidGradlePluginVersionRange.maxSupportedVersion.minor ) assertNoWarnings("$minSupportedVersion") - assertNoWarnings("$minSupportedVersion.0") - assertNoWarnings("$minSupportedVersion.0-alpha01") - assertNoWarnings("$minSupportedVersion.0-m-281") + assertNoWarnings("${minSupportedVersion.copy(classifier = "alpha01")}") + assertNoWarnings("${minSupportedVersion.copy(classifier = "m281")}") assertNoWarnings("$midSupportedVersion") - assertNoWarnings("$midSupportedVersion.0") - assertNoWarnings("$midSupportedVersion.0-alpha01") - assertNoWarnings("$midSupportedVersion.0-m-281") + assertNoWarnings("${midSupportedVersion.copy(classifier = "alpha01")})") + assertNoWarnings("${midSupportedVersion.copy(classifier = "m281")}") - assertNoWarnings("$minSupportedVersion.1") - assertNoWarnings("$minSupportedVersion.1-alpha01") + assertNoWarnings("${minSupportedVersion.copy(patch = 1)}") + assertNoWarnings("${minSupportedVersion.copy(patch = 1, classifier = "alpha01")}") assertNoWarnings("$maxSupportedVersion") - assertNoWarnings("$maxSupportedVersion.0") - assertNoWarnings("$maxSupportedVersion.0-alpha01") - assertNoWarnings("$maxSupportedVersion.0-m-281") + assertNoWarnings("${maxSupportedVersion.copy(classifier = "alpha01")}") + assertNoWarnings("${maxSupportedVersion.copy(classifier = "m281")}") - assertNoWarnings("$maxSupportedVersion.1") - assertNoWarnings("$maxSupportedVersion.1-alpha01") + assertNoWarnings("${maxSupportedVersion.copy(patch = 1)}") + assertNoWarnings("${maxSupportedVersion.copy(patch = 1, classifier = "alpha01")}") } @Test @@ -221,7 +205,7 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { addBuildEventsListenerRegistryMock(project) project.plugins.apply(LibraryPlugin::class.java) - assertEquals(Messages.FAILED_GETTING_ANDROID_GRADLE_PLUGIN_VERSION_STRING, assertSingleWarningMessage()) + assertEquals(Messages.failedGettingAndroidGradlePluginVersion(), assertSingleWarningMessage()) } @Test @@ -234,7 +218,7 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { testLogger, FixedAndroidGradlePluginVersionProvider(null) ) - assertEquals(Messages.FAILED_GETTING_ANDROID_GRADLE_PLUGIN_VERSION_STRING, assertSingleWarningMessage()) + assertEquals(Messages.failedGettingAndroidGradlePluginVersion(), assertSingleWarningMessage()) } @Test @@ -249,7 +233,7 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { ) } - assertEquals(Messages.FAILED_GETTING_ANDROID_GRADLE_PLUGIN_VERSION_STRING, assertSingleWarningMessage()) + assertEquals(Messages.failedGettingAndroidGradlePluginVersion(), assertSingleWarningMessage()) } @Test @@ -334,7 +318,7 @@ class KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheckTest { assertFalse(isTooHigh(AndroidGradlePluginVersion(3, 0))) assertFalse(isTooLow(AndroidGradlePluginVersion(4, 3))) - assertFalse(isTooHigh(AndroidGradlePluginVersion(4, 3))) + assertTrue(isTooHigh(AndroidGradlePluginVersion(4, 3))) assertFalse(isTooLow(AndroidGradlePluginVersion(5, 0))) }