From cec243ac3b818722c9fbac8470e1ac47a31ffd3c Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Wed, 21 Jun 2023 11:00:01 +0200 Subject: [PATCH] [Gradle] apply KotlinHierarchyTemplate.default, by default ^KT-58676 Verification Pending --- .../expectedOutput.txt | 18 ++++ .../gradle/plugin/PropertiesProvider.kt | 7 +- .../diagnostics/KotlinToolingDiagnostics.kt | 29 +++++++ .../hierarchy/defaultKotlinHierarchySetup.kt | 85 +++++++++++++++++++ .../plugin/mpp/KotlinMultiplatformPlugin.kt | 16 +--- .../unitTests/DefaultHierarchySetupTest.kt | 84 ++++++++++++++++++ .../KotlinNativeCompileArgumentsTest.kt | 4 + .../DefaultHierarchySetupDiagnosticTest.kt | 47 ++++++++++ .../MppDiagnosticsFunctionalTest.kt | 3 + ...ierarchyFallbackDependsOnUsageDetected.txt | 7 ++ ...ultHierarchyFallbackIllegalTargetNames.txt | 7 ++ 11 files changed, 293 insertions(+), 14 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/hierarchy/defaultKotlinHierarchySetup.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DefaultHierarchySetupDiagnosticTest.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackDependsOnUsageDetected.txt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackIllegalTargetNames.txt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/diagnosticsRenderingSmoke/expectedOutput.txt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/diagnosticsRenderingSmoke/expectedOutput.txt index 4d9ad7e78f3..21d7cf787d3 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/diagnosticsRenderingSmoke/expectedOutput.txt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/diagnosticsRenderingSmoke/expectedOutput.txt @@ -9,11 +9,29 @@ Read the details here: https://kotlinlang.org/docs/multiplatform-compatibility-g w: [CommonMainWithDependsOnDiagnostic | WARNING] commonMain can't declare dependsOn on other source sets #diagnostic-end +w: [KotlinDefaultHierarchyFallbackDependsOnUsageDetected | WARNING] The Default Kotlin Hierarchy was not applied to 'project ':subprojectA'': +Manual .dependsOn() edges were configured for the following source sets: +[commonMain] + +To suppress the 'Default Hierarchy Template' add + 'kotlin.mpp.applyDefaultHierarchyTemplate=false' +to your gradle.properties +#diagnostic-end + > Configure project :subprojectB w: [CommonMainWithDependsOnDiagnostic | WARNING] commonMain can't declare dependsOn on other source sets #diagnostic-end +w: [KotlinDefaultHierarchyFallbackDependsOnUsageDetected | WARNING] The Default Kotlin Hierarchy was not applied to 'project ':subprojectB'': +Manual .dependsOn() edges were configured for the following source sets: +[commonMain] + +To suppress the 'Default Hierarchy Template' add + 'kotlin.mpp.applyDefaultHierarchyTemplate=false' +to your gradle.properties +#diagnostic-end + w: [UnusedSourceSetsWarning | WARNING] The Kotlin source set unusedCreatedInAfterEvaluate was configured but not added to any Kotlin compilation. You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'. diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index a1ca05a3bff..a5084b7652c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_ANDROID_STYLE_NO_WARN import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION_1_NO_WARN +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_DEPRECATED_PROPERTIES_NO_WARN import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_COMPATIBILITY_METADATA_VARIANT @@ -233,6 +234,9 @@ internal class PropertiesProvider private constructor(private val project: Proje val mppEnablePlatformIntegerCommonization: Boolean get() = booleanProperty(KOTLIN_MPP_ENABLE_PLATFORM_INTEGER_COMMONIZATION) ?: false + val mppApplyDefaultHierarchyTemplate: Boolean + get() = this.booleanProperty(KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE) ?: true + val wasmStabilityNoWarn: Boolean get() = booleanProperty("kotlin.wasm.stability.nowarn") ?: false @@ -544,7 +548,7 @@ internal class PropertiesProvider private constructor(private val project: Proje private inline fun > enumProperty( propName: String, - defaultValue: T + defaultValue: T, ): T = this.property(propName)?.let { enumValueOf(it.toUpperCaseAsciiOnly()) } ?: defaultValue /** @@ -596,6 +600,7 @@ internal class PropertiesProvider private constructor(private val project: Proje const val KOTLIN_MPP_IMPORT_ENABLE_KGP_DEPENDENCY_RESOLUTION = "kotlin.mpp.import.enableKgpDependencyResolution" const val KOTLIN_MPP_IMPORT_ENABLE_SLOW_SOURCES_JAR_RESOLVER = "kotlin.mpp.import.enableSlowSourcesJarResolver" const val KOTLIN_MPP_ENABLE_INTRANSITIVE_METADATA_CONFIGURATION = "kotlin.mpp.enableIntransitiveMetadataConfiguration" + const val KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE = "kotlin.mpp.applyDefaultHierarchyTemplate" const val KOTLIN_NATIVE_DEPENDENCY_PROPAGATION = "kotlin.native.enableDependencyPropagation" const val KOTLIN_NATIVE_CACHE_ORCHESTRATION = "kotlin.native.cacheOrchestration" const val KOTLIN_NATIVE_PARALLEL_THREADS = "kotlin.native.parallelThreads" diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinToolingDiagnostics.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinToolingDiagnostics.kt index 8f79296a0a4..52be4747cfc 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinToolingDiagnostics.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinToolingDiagnostics.kt @@ -5,11 +5,13 @@ package org.jetbrains.kotlin.gradle.plugin.diagnostics +import org.gradle.api.Project import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.dsl.KotlinSourceSetConvention.isRegisteredByKotlinSourceSetConventionAt import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.* import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV1 @@ -427,6 +429,33 @@ object KotlinToolingDiagnostics { ) } + object KotlinDefaultHierarchyFallbackDependsOnUsageDetected : ToolingDiagnosticFactory(WARNING) { + operator fun invoke(project: Project, sourceSetsWithDependsOnEdges: Iterable) = build( + """ + The Default Kotlin Hierarchy was not applied to '${project.displayName}': + Manual .dependsOn() edges were configured for the following source sets: + ${sourceSetsWithDependsOnEdges.toSet().map { it.name }} + + To suppress the 'Default Hierarchy Template' add + '$KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE=false' + to your gradle.properties + """.trimIndent() + ) + } + + object KotlinDefaultHierarchyFallbackIllegalTargetNames : ToolingDiagnosticFactory(WARNING) { + operator fun invoke(project: Project, illegalTargetNamesUsed: Iterable) = build( + """ + The Default Kotlin Hierarchy was not applied to '${project.displayName}': + Illegal target names were found: + ${illegalTargetNamesUsed.toSet()} + + To suppress the 'Default Hierarchy Template' add + '$KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE=false' + to your gradle.properties + """.trimIndent() + ) + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/hierarchy/defaultKotlinHierarchySetup.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/hierarchy/defaultKotlinHierarchySetup.kt new file mode 100644 index 00000000000..aaa808e0fa1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/hierarchy/defaultKotlinHierarchySetup.kt @@ -0,0 +1,85 @@ +/* + * 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.hierarchy + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin.Companion.dynamicallyApplyWhenAndroidPluginIsApplied +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.FinaliseRefinesEdges +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider +import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.KotlinDefaultHierarchyFallbackDependsOnUsageDetected +import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.KotlinDefaultHierarchyFallbackIllegalTargetNames +import org.jetbrains.kotlin.gradle.plugin.diagnostics.kotlinToolingDiagnosticsCollector +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName + +internal suspend fun Project.setupDefaultKotlinHierarchy() = requiredStage(FinaliseRefinesEdges) setup@{ + val extension = project.multiplatformExtensionOrNull ?: return@setup + + /* User configured a target hierarchy explicitly: No need for our defaults here */ + if (extension.hierarchy.appliedTemplates.isNotEmpty()) return@setup + + /* User explicitly disabled the default target hierarchy by Gradle property */ + if (!kotlinPropertiesProvider.mppApplyDefaultHierarchyTemplate) { + setupPreMultiplatformStableDefaultDependsOnEdges() + return@setup + } + + /* + User manually added a .dependsOn: + We fall back to the old behaviour and add the commonMain/commonTest default edges + */ + run check@{ + val sourceSetsWithDependsOnEdges = extension.sourceSets.filter { sourceSet -> sourceSet.dependsOn.isNotEmpty() } + if (sourceSetsWithDependsOnEdges.isEmpty()) return@check + val diagnostic = KotlinDefaultHierarchyFallbackDependsOnUsageDetected(project, sourceSetsWithDependsOnEdges) + kotlinToolingDiagnosticsCollector.report(project, diagnostic) + setupPreMultiplatformStableDefaultDependsOnEdges() + return@setup + } + + + /* + Using a group of the 'defaultTargetHierarchy' as 'target name' will potentially lead to conflicts e.g.: + linuxX64("linux") or macosX64("native") can lead to confusion of for 'linuxMain' and 'nativeMain' SourceSets + */ + run check@{ + val illegalTargetNamesUsed = illegalTargetNamesUsed() + if (illegalTargetNamesUsed.isEmpty()) return@check + val diagnostic = KotlinDefaultHierarchyFallbackIllegalTargetNames(project, illegalTargetNamesUsed) + kotlinToolingDiagnosticsCollector.report(project, diagnostic) + setupPreMultiplatformStableDefaultDependsOnEdges() + return@setup + } + + extension.applyDefaultHierarchyTemplate() +} + +private suspend fun Project.illegalTargetNamesUsed(): Set { + val targets = multiplatformExtension.awaitTargets() + val targetNames = targets.map { it.name }.toSet() + return targets.flatMap { it.compilations }.mapNotNull { compilation -> + val hierarchy = KotlinHierarchyTemplate.default.buildHierarchy(compilation) ?: return@mapNotNull null + val nodeNames = hierarchy.childrenClosure.mapNotNull { it.node as? KotlinHierarchy.Node.Group }.map { it.name }.toSet() + nodeNames.intersect(targetNames) + }.flatten().toSet() +} + +/** + * Before 1.9.20 (and without any targetHierarchy applied), we just added default dependsOn + * edges from 'main' compilations defaultSourceSets to 'commonMain' and + * edges from 'test' compilations defaultSourceSets to 'commonTest + */ +private suspend fun Project.setupPreMultiplatformStableDefaultDependsOnEdges() = multiplatformExtension.targets + .flatMap { target -> target.compilations } + .forEach { compilation -> + val sourceSetTree = KotlinSourceSetTree.orNull(compilation) ?: return@forEach + val commonSourceSetName = lowerCamelCaseName("common", sourceSetTree.name) + val commonSourceSet = multiplatformExtension.sourceSets.findByName(commonSourceSetName) ?: return@forEach + compilation.defaultSourceSet.dependsOn(commonSourceSet) + } + diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt index af1c837c1f9..d4897190817 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.hierarchy.orNull +import org.jetbrains.kotlin.gradle.plugin.hierarchy.setupDefaultKotlinHierarchy 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 @@ -175,19 +176,8 @@ class KotlinMultiplatformPlugin : Plugin { sourceSets.create(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) sourceSets.create(KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME) - /* Create default 'dependsOn' to commonMain/commonTest (or even common{SourceSetTree}) */ - targets.all { target -> - project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseRefinesEdges) { - /* Only setup default refines edges when no KotlinTargetHierarchy was applied */ - if (project.multiplatformExtension.internalKotlinTargetHierarchy.appliedDescriptors.isNotEmpty()) return@launchInStage - if (project.multiplatformExtension.hierarchy.appliedTemplates.isNotEmpty()) return@launchInStage - - target.compilations.forEach { compilation -> - val sourceSetTree = KotlinSourceSetTree.orNull(compilation) ?: return@forEach - val commonSourceSet = sourceSets.findByName(lowerCamelCaseName("common", sourceSetTree.name)) ?: return@forEach - compilation.defaultSourceSet.dependsOn(commonSourceSet) - } - } + project.launch { + project.setupDefaultKotlinHierarchy() } project.launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/DefaultHierarchySetupTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/DefaultHierarchySetupTest.kt index e69de29bb2d..e9d48c17685 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/DefaultHierarchySetupTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/DefaultHierarchySetupTest.kt @@ -0,0 +1,84 @@ +/* + * 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.unitTests + +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.commonMain +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.jvmMain +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE +import org.jetbrains.kotlin.gradle.plugin.hierarchy.default +import org.jetbrains.kotlin.gradle.util.assertNoDiagnostics +import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP +import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.fail + +class DefaultHierarchySetupTest { + @Test + fun `test - default target hierarchy is applied for simple project`() = buildProjectWithMPP().runLifecycleAwareTest { + val kotlin = multiplatformExtension + kotlin.jvm() + kotlin.linuxX64() + kotlin.linuxArm64() + + launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { + assertEquals( + setOf(KotlinHierarchyTemplate.default), kotlin.hierarchy.appliedTemplates, + "Expected 'defaultKotlinTargetHierarchy' to be applied" + ) + } + } + + @Test + fun `test - default target hierarchy is disabled by flag`() = buildProjectWithMPP().runLifecycleAwareTest { + project.extraProperties.set(KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE, false.toString()) + + val kotlin = multiplatformExtension + kotlin.jvm() + kotlin.linuxX64() + kotlin.linuxArm64() + + launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { + if (kotlin.hierarchy.appliedTemplates.isNotEmpty()) { + fail("Expected *no* hierarchy template to be applied") + } + + project.assertNoDiagnostics() + } + } + + @Test + fun `test - no hierarchy descriptor applied - when a custom dependsOn edge was configured`() = + buildProjectWithMPP().runLifecycleAwareTest { + val kotlin = multiplatformExtension + kotlin.jvm() + kotlin.sourceSets.jvmMain.get().dependsOn(kotlin.sourceSets.commonMain.get()) + + launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { + if (kotlin.hierarchy.appliedTemplates.isNotEmpty()) { + fail("Expected *no* hierarchy template to be applied") + } + } + } + + @Test + fun `test - no hierarchy descriptor applied - when a targetName clashes with a default group`() { + buildProjectWithMPP().runLifecycleAwareTest { + val kotlin = multiplatformExtension + kotlin.linuxX64("linux") // <- group in default hierarchy is also called 'linux' + + launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { + if (kotlin.hierarchy.appliedTemplates.isNotEmpty()) { + fail("Expected *no* hierarchy template to be applied") + } + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/compilerArgumetns/KotlinNativeCompileArgumentsTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/compilerArgumetns/KotlinNativeCompileArgumentsTest.kt index 4b3b49179ca..85ae3b7f0b3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/compilerArgumetns/KotlinNativeCompileArgumentsTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/compilerArgumetns/KotlinNativeCompileArgumentsTest.kt @@ -166,6 +166,10 @@ class KotlinNativeCompileArgumentsTest { linuxX64SourceFile.parentFile.mkdirs() linuxX64SourceFile.writeText("object Linux") + project.multiplatformExtension.applyHierarchyTemplate { + common { withLinux() } + } + project.evaluate() val nativeCompilation = kotlin.linuxX64().compilations.main diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DefaultHierarchySetupDiagnosticTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DefaultHierarchySetupDiagnosticTest.kt new file mode 100644 index 00000000000..69067eded1b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DefaultHierarchySetupDiagnosticTest.kt @@ -0,0 +1,47 @@ +/* + * 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.unitTests.diagnosticsTests + +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.commonMain +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.jvmMain +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.launchInStage +import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP +import org.jetbrains.kotlin.gradle.util.checkDiagnostics +import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest +import kotlin.test.Test + +class DefaultHierarchySetupDiagnosticTest { + @Test + fun `test - warning KotlinTargetHierarchyFallbackDependsOnUsageDetected`() = buildProjectWithMPP().runLifecycleAwareTest { + val kotlin = multiplatformExtension + kotlin.jvm() + + /* Create intermediate SourceSet using custom .dependsOn calls */ + val intermediateMain = kotlin.sourceSets.create("intermediateMain") + intermediateMain.dependsOn(kotlin.sourceSets.commonMain.get()) + kotlin.sourceSets.jvmMain.get().dependsOn(intermediateMain) + + project.launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { + project.checkDiagnostics("KotlinDefaultHierarchyFallbackDependsOnUsageDetected") + } + } + + @Test + fun `test - warning KotlinTargetHierarchyFallbackIllegalTargetNames`() = buildProjectWithMPP().runLifecycleAwareTest { + val kotlin = multiplatformExtension + kotlin.linuxX64("linux") // <- illegal: Will clash with 'linux' group + kotlin.linuxArm64("native") // <-- illegal: Will clash with 'native' group + kotlin.jvm() + + project.launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { + project.checkDiagnostics("KotlinDefaultHierarchyFallbackIllegalTargetNames") + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/MppDiagnosticsFunctionalTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/MppDiagnosticsFunctionalTest.kt index dbe2cee6bb2..8c4fa432216 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/MppDiagnosticsFunctionalTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/MppDiagnosticsFunctionalTest.kt @@ -18,6 +18,7 @@ class MppDiagnosticsFunctionalTest { kotlin { jvm() linuxX64() + applyDefaultHierarchyTemplate() sourceSets.apply { val myCustomCommonMain = create("myCustomCommonMain") @@ -47,6 +48,7 @@ class MppDiagnosticsFunctionalTest { kotlin { jvm() linuxX64() + applyDefaultHierarchyTemplate() sourceSets.apply { val unused1 = create("unused1") @@ -86,6 +88,7 @@ class MppDiagnosticsFunctionalTest { kotlin { androidTarget() linuxX64() + applyDefaultHierarchyTemplate() sourceSets.apply { val intermediateBetweenAndroid = create("intermediate") diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackDependsOnUsageDetected.txt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackDependsOnUsageDetected.txt new file mode 100644 index 00000000000..45fd7c441a4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackDependsOnUsageDetected.txt @@ -0,0 +1,7 @@ +[KotlinDefaultHierarchyFallbackDependsOnUsageDetected | WARNING] The Default Kotlin Hierarchy was not applied to 'root project 'test'': +Manual .dependsOn() edges were configured for the following source sets: +[intermediateMain, jvmMain] + +To suppress the 'Default Hierarchy Template' add + 'kotlin.mpp.applyDefaultHierarchyTemplate=false' +to your gradle.properties \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackIllegalTargetNames.txt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackIllegalTargetNames.txt new file mode 100644 index 00000000000..fa3b0bacc3d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/KotlinDefaultHierarchyFallbackIllegalTargetNames.txt @@ -0,0 +1,7 @@ +[KotlinDefaultHierarchyFallbackIllegalTargetNames | WARNING] The Default Kotlin Hierarchy was not applied to 'root project 'test'': +Illegal target names were found: +[native, linux] + +To suppress the 'Default Hierarchy Template' add + 'kotlin.mpp.applyDefaultHierarchyTemplate=false' +to your gradle.properties \ No newline at end of file