[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.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.testbase.*
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
|
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||||
import kotlin.io.path.appendText
|
import kotlin.io.path.appendText
|
||||||
import kotlin.io.path.writeText
|
import kotlin.io.path.writeText
|
||||||
import kotlin.test.assertFalse
|
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) {
|
private fun TestProject.checkDeprecatedProperties(isDeprecationExpected: Boolean) {
|
||||||
build {
|
build {
|
||||||
val assert: (Boolean, String) -> Unit = if (isDeprecationExpected) ::assertTrue else ::assertFalse
|
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.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
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.dsl.multiplatformExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet.Companion.COMMON_MAIN_SOURCE_SET_NAME
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet.Companion.COMMON_MAIN_SOURCE_SET_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
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.plugin.sources.internal
|
||||||
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
||||||
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
|
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.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
||||||
|
|
||||||
@@ -28,6 +30,7 @@ internal fun runDeprecationDiagnostics(project: Project) {
|
|||||||
checkAndReportDeprecatedSourceSetsLayouts(project)
|
checkAndReportDeprecatedSourceSetsLayouts(project)
|
||||||
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
||||||
checkAndReportDeprecatedNativeTargets(project)
|
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.
|
* 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.
|
* 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