[Gradle] Report warning when targets are not distinguishable
^KT-55751 Verification Pending
This commit is contained in:
committed by
Space Team
parent
58959951d3
commit
b9f0ad0e58
+40
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.mpp
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||
import kotlin.io.path.appendText
|
||||
import kotlin.io.path.writeText
|
||||
import kotlin.test.assertFalse
|
||||
@@ -50,6 +51,45 @@ class MppDiagnosticsIt : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
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 {
|
||||
val assert: (Boolean, String) -> Unit = if (isDeprecationExpected) ::assertTrue else ::assertFalse
|
||||
|
||||
+32
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet.Companion.COMMON_MAIN_SOURCE_SET_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||
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.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
||||
|
||||
@@ -28,6 +30,7 @@ internal fun runDeprecationDiagnostics(project: Project) {
|
||||
checkAndReportDeprecatedSourceSetsLayouts(project)
|
||||
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
||||
checkAndReportDeprecatedNativeTargets(project)
|
||||
reportTargetsWithNonUniqueConsumableConfigurations(project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +44,35 @@ private fun checkAndReportDeprecatedNativeTargets(project: 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
|
||||
.groupBy { target -> project.configurations.getByName(target.apiElementsConfigurationName).attributes.toMap() }
|
||||
.values
|
||||
.filter { targetGroup -> targetGroup.size > 1 }
|
||||
|
||||
if (nonDistinguishableTargets.isEmpty()) return@afterEvaluate
|
||||
|
||||
val nonUniqueTargetsString = nonDistinguishableTargets.joinToString(separator = "\n") { targets ->
|
||||
val targetsListString = targets.joinToString { "'${it.name}'" }
|
||||
" * $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.
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.utils
|
||||
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
|
||||
/**
|
||||
* KGP's internal analog of [org.gradle.api.internal.attributes.AttributeContainerInternal.asMap]
|
||||
* Can be used to compare attributes
|
||||
*/
|
||||
internal fun AttributeContainer.toMap(): Map<Attribute<*>, Any?> {
|
||||
val result = mutableMapOf<Attribute<*>, Any?>()
|
||||
for (key in keySet()) {
|
||||
result[key] = getAttribute(key)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user