[Gradle] Deprecate case when commonMain depends on another source set

^KT-55824 Verification Pending
This commit is contained in:
Anton Lakotka
2023-01-25 21:00:55 +01:00
committed by Space Team
parent ccc3f52acf
commit 23f10a1d38
4 changed files with 69 additions and 26 deletions
@@ -13,11 +13,11 @@ import kotlin.test.assertFalse
import kotlin.test.assertTrue
@MppGradlePluginTests
class MppDeprecatedPropertiesIt : KGPBaseTest() {
class MppDiagnosticsIt : KGPBaseTest() {
@GradleTest
fun testDeprecations(gradleVersion: GradleVersion) {
fun testDeprecatedProperties(gradleVersion: GradleVersion) {
project("mppDeprecatedProperties", gradleVersion) {
checkDeprecations(isDeprecationExpected = false)
checkDeprecatedProperties(isDeprecationExpected = false)
this.gradleProperties.appendText(
defaultFlags.entries.joinToString(
@@ -26,18 +26,31 @@ class MppDeprecatedPropertiesIt : KGPBaseTest() {
separator = System.lineSeparator(),
) { (prop, value) -> "$prop=$value" }
)
checkDeprecations(isDeprecationExpected = true)
checkDeprecatedProperties(isDeprecationExpected = true)
// remove the MPP plugin from the top-level project and check the warnings are still reported in subproject
this.buildGradleKts.writeText("")
checkDeprecations(isDeprecationExpected = true)
checkDeprecatedProperties(isDeprecationExpected = true)
this.gradleProperties.appendText("kotlin.mpp.deprecatedProperties.nowarn=true${System.lineSeparator()}")
checkDeprecations(isDeprecationExpected = false)
checkDeprecatedProperties(isDeprecationExpected = false)
}
}
private fun TestProject.checkDeprecations(isDeprecationExpected: Boolean) {
@GradleTest
fun testCommonMainMustNotDependOnOtherSourceSets(gradleVersion: GradleVersion) {
project("commonMainDependsOnAnotherSourceSet", gradleVersion) {
build("tasks") {
assertOutputContains("w: 'commonMain' source set can't depend on other source sets.")
}
build("tasks", buildOptions = defaultBuildOptions.copy(freeArgs = listOf("-PcommonSourceSetDependsOnNothing"))) {
assertOutputDoesNotContain("w: 'commonMain' source set can't depend on other source sets.")
}
}
}
private fun TestProject.checkDeprecatedProperties(isDeprecationExpected: Boolean) {
build {
val assert: (Boolean, String) -> Unit = if (isDeprecationExpected) ::assertTrue else ::assertFalse
val warnings = output.lines().filter { it.startsWith("w:") }.toSet()
@@ -0,0 +1,16 @@
plugins {
kotlin("multiplatform")
}
kotlin {
jvm()
linuxX64()
sourceSets {
val commonMain by getting
if (!hasProperty("commonSourceSetDependsOnNothing")) {
val grandCommonMain by creating
commonMain.dependsOn(grandCommonMain)
}
}
}
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport
import org.jetbrains.kotlin.gradle.plugin.ide.locateOrRegisterIdeResolveDependenciesTask
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin.Companion.sourceSetFreeCompilerArgsPropertyName
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.addBuildListenerForXcode
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.checkAndReportDeprecatedMppProperties
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.checkAndReportDeprecatedNativeTargets
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.handleHierarchicalStructureFlagsMigration
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.runDeprecationDiagnostics
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
import org.jetbrains.kotlin.gradle.plugin.sources.checkSourceSetVisibilityRequirements
@@ -49,10 +46,7 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
override fun apply(project: Project) {
checkGradleCompatibility("the Kotlin Multiplatform plugin", GradleVersion.version("6.0"))
checkAndReportDeprecatedMppProperties(project)
handleHierarchicalStructureFlagsMigration(project)
checkAndReportDeprecatedNativeTargets(project)
runDeprecationDiagnostics(project)
project.plugins.apply(JavaBasePlugin::class.java)
@@ -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.multiplatformExtensionOrNull
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
@@ -14,30 +15,35 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_HIERARCHICAL_STRUCTURE_SUPPORT
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_DEPENDENCY_PROPAGATION
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.tooling.core.UnsafeApi
internal fun checkAndReportDeprecatedNativeTargets(project: Project) {
internal fun runDeprecationDiagnostics(project: Project) {
checkAndReportDeprecatedMppProperties(project)
handleHierarchicalStructureFlagsMigration(project)
project.runProjectConfigurationHealthCheckWhenEvaluated {
val targets = project.extensions.getByType(KotlinMultiplatformExtension::class.java).targets
val usedDeprecatedTargets = targets.filter { it is KotlinNativeTarget && it.konanTarget in KonanTarget.deprecatedTargets }
if (usedDeprecatedTargets.isEmpty()) return@runProjectConfigurationHealthCheckWhenEvaluated
SingleWarningPerBuild.show(
project,
"w: The following deprecated kotlin native targets were used in the project: ${usedDeprecatedTargets.joinToString { it.targetName }}"
)
checkAndReportDeprecatedNativeTargets(project)
checkAndReportDeprecatedSourceSetsLayouts(project)
}
}
private fun checkAndReportDeprecatedNativeTargets(project: Project) {
val targets = project.extensions.getByType(KotlinMultiplatformExtension::class.java).targets
val usedDeprecatedTargets = targets.filter { it is KotlinNativeTarget && it.konanTarget in KonanTarget.deprecatedTargets }
if (usedDeprecatedTargets.isEmpty()) return
SingleWarningPerBuild.show(
project,
"w: The following deprecated kotlin native targets were used in the project: ${usedDeprecatedTargets.joinToString { it.targetName }}"
)
}
/**
* 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.
*/
internal fun checkAndReportDeprecatedMppProperties(project: Project) {
private fun checkAndReportDeprecatedMppProperties(project: Project) {
val projectProperties = project.kotlinPropertiesProvider
if (projectProperties.ignoreHmppDeprecationWarnings == true) return
@@ -54,6 +60,20 @@ internal fun checkAndReportDeprecatedMppProperties(project: Project) {
}
}
private fun checkAndReportDeprecatedSourceSetsLayouts(project: Project) {
project.reportCommonMainDependsOnOtherSourceSets()
}
private fun Project.reportCommonMainDependsOnOtherSourceSets() {
val commonMain = multiplatformExtensionOrNull?.sourceSets?.getByName("commonMain") ?: return
if (commonMain.dependsOn.isNotEmpty()) {
SingleWarningPerBuild.show(
project,
"w: 'commonMain' source set can't depend on other source sets."
)
}
}
internal val deprecatedMppProperties: List<String> = listOf(
KOTLIN_MPP_ENABLE_COMPATIBILITY_METADATA_VARIANT,
KOTLIN_MPP_ENABLE_GRANULAR_SOURCE_SETS_METADATA,