From 63f61685c0e7a5120c4480446150f9ddbcf31395 Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Wed, 19 Apr 2023 17:21:55 +0200 Subject: [PATCH] [Gradle] Migrate diagnostic about empty Kotlin targets in an MPP project Also demote it from FATAL to ERROR, as FATAL leads to pretty disruptive UX in IDE (import fails, and you don't get a broken project, which makes it hard to fix the root cause and declare a target) --- .../kotlin/gradle/mpp/MppDiagnosticsIt.kt | 4 +--- .../gradle/plugin/KotlinPluginWrapper.kt | 1 - .../diagnostics/KotlinGradleProjectChecker.kt | 3 ++- .../diagnostics/KotlinToolingDiagnostics.kt | 12 ++++++++-- .../NoKotlinTargetsDeclaredChecker.kt | 22 +++++++++++++++++++ .../MppDiagnosticsFunctionalTest.kt | 11 ++++++++++ .../expectedDiagnostics/noTargetsDeclared.txt | 8 +++++++ 7 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/NoKotlinTargetsDeclaredChecker.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/noTargetsDeclared.txt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt index b6731ad202d..9391ffecd29 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt @@ -8,8 +8,6 @@ package org.jetbrains.kotlin.gradle.mpp import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics import org.jetbrains.kotlin.gradle.testbase.* -import org.jetbrains.kotlin.gradle.util.replaceText -import org.jetbrains.kotlin.test.TestMetadata import kotlin.io.path.appendText import kotlin.io.path.writeText @@ -26,7 +24,7 @@ class MppDiagnosticsIt : KGPBaseTest() { } @GradleTest - fun testDeprecatedProperties(gradleVersion: GradleVersion) { + fun testDeprecatedMppProperties(gradleVersion: GradleVersion) { project("mppDeprecatedProperties", gradleVersion) { checkDeprecatedProperties(isDeprecationExpected = false) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index b1fbfe5825b..da3c4f475a5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -387,7 +387,6 @@ abstract class AbstractKotlinMultiplatformPluginWrapper : KotlinBasePluginWrappe get() = KotlinMultiplatformExtension::class override fun whenBuildEvaluated(project: Project) { - project.runMissingKotlinTargetsProjectConfigurationHealthCheck() project.runDisabledCInteropCommonizationOnHmppProjectConfigurationHealthCheck() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectChecker.kt index 28752d8d70f..bc65de260e6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectChecker.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectChecker.kt @@ -100,7 +100,8 @@ internal interface KotlinGradleProjectChecker { UnusedSourceSetsChecker, AndroidSourceSetLayoutV1SourceSetsNotFoundChecker, TargetsWithAmbiguousConsumableConfigurationsChecker, - AndroidPluginWithoutAndroidTargetChecker + AndroidPluginWithoutAndroidTargetChecker, + NoKotlinTargetsDeclaredChecker ) } } 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 0d24da60922..b12b9faaa92 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 @@ -7,8 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.diagnostics import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider -import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.ERROR -import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.WARNING +import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.* import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV1 import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV2 @@ -240,4 +239,13 @@ object KotlinToolingDiagnostics { """.trimIndent() ) } + + object NoKotlinTargetsDeclared : ToolingDiagnosticFactory(ERROR) { + operator fun invoke(projectName: String, projectPath: String) = build( + """ + Please initialize at least one Kotlin target in '${projectName} (${projectPath})'. + Read more https://kotl.in/set-up-targets + """.trimIndent() + ) + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/NoKotlinTargetsDeclaredChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/NoKotlinTargetsDeclaredChecker.kt new file mode 100644 index 00000000000..17fb06d864d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/NoKotlinTargetsDeclaredChecker.kt @@ -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.plugin.diagnostics.checkers + +import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker +import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext +import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics +import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget + +internal object NoKotlinTargetsDeclaredChecker : KotlinGradleProjectChecker { + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + val isNoTargetsInitialized = (multiplatformExtension ?: return).awaitTargets().none { it !is KotlinMetadataTarget } + + if (isNoTargetsInitialized) { + collector.report(project, KotlinToolingDiagnostics.NoKotlinTargetsDeclared(project.name, project.path)) + } + } +} 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 aa8d88f93b4..ee5f2fd6249 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 @@ -5,10 +5,14 @@ package org.jetbrains.kotlin.gradle.unitTests.diagnosticsTests +import org.gradle.api.InvalidUserCodeException import org.gradle.api.attributes.Attribute +import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmWithJavaTargetPreset import org.jetbrains.kotlin.gradle.util.* import org.junit.Test +import kotlin.jvm.Throws +import kotlin.test.assertTrue class MppDiagnosticsFunctionalTest { @@ -152,4 +156,11 @@ class MppDiagnosticsFunctionalTest { } } } + + @Test + fun testNoTargetsDeclared() { + checkDiagnosticsWithMppProject("noTargetsDeclared") { + kotlin { } + } + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/noTargetsDeclared.txt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/noTargetsDeclared.txt new file mode 100644 index 00000000000..b0e7d66b867 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/resources/expectedDiagnostics/noTargetsDeclared.txt @@ -0,0 +1,8 @@ +[NoKotlinTargetsDeclared | ERROR] Please initialize at least one Kotlin target in 'noTargetsDeclared (:)'. +Read more https://kotl.in/set-up-targets +---- +[UnusedSourceSetsWarning | WARNING] The following Kotlin source sets were configured but not added to any Kotlin compilation: + * commonMain + * commonTest +You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'. +See https://kotl.in/connecting-source-sets