[Gradle] Migrate checks for non-disambiguated targets
This commit is contained in:
-40
@@ -48,46 +48,6 @@ class MppDiagnosticsIt : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
@TestMetadata("new-mpp-lib-and-app/sample-lib-gradle-kotlin-dsl")
|
||||
fun testReportTargetsOfTheSamplePlatformAndWithTheSameAttributes(gradleVersion: GradleVersion) {
|
||||
project("new-mpp-lib-and-app/sample-lib-gradle-kotlin-dsl", gradleVersion) {
|
||||
// A hack to make project compatible with GradleTestKit infrastructure
|
||||
buildGradleKts.replaceText(
|
||||
"""id("org.jetbrains.kotlin.multiplatform").version("<pluginMarkerVersion>")""",
|
||||
"""id("org.jetbrains.kotlin.multiplatform")""",
|
||||
)
|
||||
buildGradleKts.appendText("""
|
||||
|
||||
val distinguishAttribute = Attribute.of(String::class.java)
|
||||
fun org.jetbrains.kotlin.gradle.plugin.KotlinTarget.applyDistinguishingAttributeIfSet(value: String) {
|
||||
if (project.properties.containsKey("applyDistinguishingAttribute")) {
|
||||
attributes {
|
||||
attribute(distinguishAttribute, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
kotlin {
|
||||
jvm("jvm2") { applyDistinguishingAttributeIfSet("jvm2") }
|
||||
linuxArm64("linuxArm_A") { applyDistinguishingAttributeIfSet("linuxArm_A") }
|
||||
linuxArm64("linuxArm_B") { applyDistinguishingAttributeIfSet("linuxArm_B") }
|
||||
}
|
||||
""".trimIndent())
|
||||
|
||||
val warningMessage = """w: The following targets are not distinguishable:
|
||||
| * 'jvm2', 'jvm6'
|
||||
| * 'linuxArm_A', 'linuxArm_B'""".trimMargin()
|
||||
|
||||
build {
|
||||
assertOutputContains(warningMessage)
|
||||
}
|
||||
|
||||
build(buildOptions = defaultBuildOptions.copy(freeArgs = listOf("-PapplyDistinguishingAttribute"))) {
|
||||
assertOutputDoesNotContain(warningMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestProject.checkDeprecatedProperties(isDeprecationExpected: Boolean) {
|
||||
build {
|
||||
if (isDeprecationExpected)
|
||||
|
||||
+1
@@ -99,6 +99,7 @@ internal interface KotlinGradleProjectChecker {
|
||||
MissingNativeStdlibChecker,
|
||||
UnusedSourceSetsChecker,
|
||||
AndroidSourceSetLayoutV1SourceSetsNotFoundChecker,
|
||||
TargetsWithAmbiguousConsumableConfigurationsChecker
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -186,4 +186,15 @@ object KotlinToolingDiagnostics {
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
object TargetsNeedDisambiguation : ToolingDiagnosticFactory(WARNING) {
|
||||
operator fun invoke(targetGroupsRendered: String) = build(
|
||||
"""
|
||||
|The following targets are not distinguishable:
|
||||
|$targetGroupsRendered
|
||||
|Use an additional attribute to disambiguate them
|
||||
|See https://kotlinlang.org/docs/multiplatform-set-up-targets.html#distinguish-several-targets-for-one-platform for more details
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||
import org.jetbrains.kotlin.gradle.plugin.await
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext
|
||||
import org.jetbrains.kotlin.gradle.utils.toMap
|
||||
|
||||
/**
|
||||
* Report scenario when there are two targets of the same platform without distinguishing attribute
|
||||
*/
|
||||
internal object TargetsWithAmbiguousConsumableConfigurationsChecker : KotlinGradleProjectChecker {
|
||||
override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) {
|
||||
// Need all configurations to be created/set up
|
||||
KotlinPluginLifecycle.Stage.ReadyForExecution.await()
|
||||
|
||||
val allTargets = multiplatformExtension?.targets ?: return
|
||||
|
||||
val nonDistinguishableTargets = allTargets
|
||||
.mapNotNull { target ->
|
||||
val configuration = project.configurations.findByName(target.apiElementsConfigurationName) ?: return@mapNotNull null
|
||||
target.name to configuration
|
||||
}
|
||||
.groupBy { (_, consumableConfiguration) -> consumableConfiguration.attributes.toMap() }
|
||||
.values
|
||||
.filter { targetGroup -> targetGroup.size > 1 }
|
||||
.map { targetGroup -> targetGroup.map { (targetName, _) -> targetName } }
|
||||
|
||||
if (nonDistinguishableTargets.isEmpty()) return
|
||||
|
||||
val nonUniqueTargetsString = nonDistinguishableTargets.joinToString(separator = "\n") { targets ->
|
||||
val targetsListString = targets.joinToString { targetName -> "'$targetName'" }
|
||||
" * $targetsListString"
|
||||
}
|
||||
|
||||
collector.reportOncePerGradleProject(project, KotlinToolingDiagnostics.TargetsNeedDisambiguation(nonUniqueTargetsString))
|
||||
}
|
||||
}
|
||||
-38
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_COMPATIBILITY_METADATA_VARIANT
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_GRANULAR_SOURCE_SETS_METADATA
|
||||
@@ -15,54 +14,17 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_DEPENDENCY_PROPAGATION
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.kotlinToolingDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
||||
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
|
||||
import org.jetbrains.kotlin.gradle.utils.toMap
|
||||
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
||||
|
||||
internal fun runDeprecationDiagnostics(project: Project) {
|
||||
checkAndReportDeprecatedMppProperties(project)
|
||||
handleHierarchicalStructureFlagsMigration(project)
|
||||
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
||||
reportTargetsWithNonUniqueConsumableConfigurations(project)
|
||||
checkAndReportPreHmppDependenciesUsage(project)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report scenario when there are two targets of the same platform without distinguishing attribute
|
||||
*/
|
||||
private fun reportTargetsWithNonUniqueConsumableConfigurations(project: Project) {
|
||||
// Wrap diagnostic check again to afterEvaluate to make sure that it gets executed the last
|
||||
// Since Multiplatform plugin updates consumable configurations in afterEvaluate blocks
|
||||
project.afterEvaluate {
|
||||
val allTargets = project.multiplatformExtension.targets
|
||||
|
||||
val nonDistinguishableTargets = allTargets
|
||||
.mapNotNull { target ->
|
||||
val configuration = project.configurations.findByName(target.apiElementsConfigurationName) ?: return@mapNotNull null
|
||||
target.name to configuration
|
||||
}
|
||||
.groupBy { (_, consumableConfiguration) -> consumableConfiguration.attributes.toMap() }
|
||||
.values
|
||||
.filter { targetGroup -> targetGroup.size > 1 }
|
||||
.map { targetGroup -> targetGroup.map { (targetName, _) -> targetName } }
|
||||
|
||||
if (nonDistinguishableTargets.isEmpty()) return@afterEvaluate
|
||||
|
||||
val nonUniqueTargetsString = nonDistinguishableTargets.joinToString(separator = "\n") { targets ->
|
||||
val targetsListString = targets.joinToString { targetName -> "'$targetName'" }
|
||||
" * $targetsListString"
|
||||
}
|
||||
|
||||
SingleWarningPerBuild.show(
|
||||
project, "w: The following targets are not distinguishable:\n$nonUniqueTargetsString" +
|
||||
"\nUse distinguish attribute. " +
|
||||
"See https://kotlinlang.org/docs/multiplatform-set-up-targets.html#distinguish-several-targets-for-one-platform for more details."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declared properties have to be captured during plugin application phase before the HMPP migration util sets them.
|
||||
* Warnings have to be reported only for successfully evaluated projects without errors.
|
||||
|
||||
+30
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.unitTests.diagnosticsTests
|
||||
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmWithJavaTargetPreset
|
||||
import org.jetbrains.kotlin.gradle.util.*
|
||||
import org.junit.Test
|
||||
@@ -122,4 +123,33 @@ class MppDiagnosticsFunctionalTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun targetsDisambiguation() {
|
||||
checkDiagnosticsWithMppProject("targetsDisambiguation") {
|
||||
kotlin {
|
||||
val distinguishAttribute = Attribute.of(String::class.java)
|
||||
|
||||
// Simple case: no disambiguation -> warning reported
|
||||
linuxArm64("linuxArm_A") { }
|
||||
linuxArm64("linuxArm_B") { }
|
||||
|
||||
// Some targets are disambiguated and some are not -> warning reported, only on targets without attribute
|
||||
jvm("jvm_A") { attributes { attribute(distinguishAttribute, "jvm1") } }
|
||||
jvm("jvm_B") { attributes { attribute(distinguishAttribute, "jvm2") } }
|
||||
jvm("jvm_C")
|
||||
jvm("jvm_D")
|
||||
|
||||
// Targets formally have attribute, but values are the same -> warning reported
|
||||
js("js_A") {
|
||||
browser()
|
||||
attributes { attribute(distinguishAttribute, "js") }
|
||||
}
|
||||
js("js_B") {
|
||||
browser()
|
||||
attributes { attribute(distinguishAttribute, "js") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
[TargetsNeedDisambiguation | WARNING] The following targets are not distinguishable:
|
||||
* 'js_A', 'js_B'
|
||||
* 'jvm_C', 'jvm_D'
|
||||
* 'linuxArm_A', 'linuxArm_B'
|
||||
Use an additional attribute to disambiguate them
|
||||
See https://kotlinlang.org/docs/multiplatform-set-up-targets.html#distinguish-several-targets-for-one-platform for more details
|
||||
Reference in New Issue
Block a user