From 287c431bc4f75e71cce93e03fc3c24a55306a02e Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Wed, 3 May 2023 18:43:53 +0200 Subject: [PATCH] [Gradle] KGP Diagnostics: Run diagnostics launched & schedule report once Project is configured KT-58275 --- .../gradle/plugin/KotlinPluginWrapper.kt | 33 +++++++------------ .../diagnostics/KotlinGradleProjectChecker.kt | 4 +-- .../KotlinGradleProjectCheckersRunner.kt | 5 +-- .../CommonMainWithDependsOnChecker.kt | 2 +- .../DeprecatedKotlinNativeTargetsChecker.kt | 4 +-- .../checkers/MissingNativeStdlibChecker.kt | 4 +-- .../checkers/UnusedSourceSetsChecker.kt | 7 ++-- .../DiagnosticsReportingFunctionalTest.kt | 8 ++--- 8 files changed, 29 insertions(+), 38 deletions(-) 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 694d872c336..b9bd7acd343 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 @@ -42,7 +42,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.report.BuildMetricsService -import org.jetbrains.kotlin.gradle.report.BuildReportsService import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin import org.jetbrains.kotlin.gradle.targets.js.npm.addNpmDependencyExtension @@ -246,7 +245,7 @@ abstract class KotlinBasePluginWrapper : DefaultKotlinBasePlugin() { project.registerBuildKotlinToolingMetadataTask() - project.scheduleDiagnosticChecksAndReporting() + project.launchDiagnosticChecksAndReporting() } internal open fun createTestRegistry(project: Project) = KotlinTestsRegistry(project) @@ -254,27 +253,17 @@ abstract class KotlinBasePluginWrapper : DefaultKotlinBasePlugin() { internal abstract fun getPlugin( project: Project, ): Plugin +} - private fun Project.scheduleDiagnosticChecksAndReporting() { - - - launchInStage(KotlinPluginLifecycle.Stage.ReadyForExecution) { - // Do not run checkers on projects which configuration finished with failure, - // as the internal state can not be trusted at this point (e.g. not entire of the - // user's buildscript could've been executed) and might produce bogus warnings - runProjectConfigurationHealthCheck { - project.runKotlinGradleProjectCheckers() - } - - // TODO: this should run even if the application of KGP has finished with errors, - // because some diagnostics might indicate specifically the root cause of an - // exception. - renderReportedDiagnostics( - project.kotlinToolingDiagnosticsCollector.getDiagnosticsForProject(project), - project.logger, - project.kotlinPropertiesProvider.internalVerboseDiagnostics - ) - } +private fun Project.launchDiagnosticChecksAndReporting() { + project.launchKotlinGradleProjectCheckers() + project.launch { + project.configured.await() + renderReportedDiagnostics( + project.kotlinToolingDiagnosticsCollector.getDiagnosticsForProject(project), + project.logger, + project.kotlinPropertiesProvider.internalVerboseDiagnostics + ) } } 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 af410785d1c..058fadfed8f 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 @@ -23,8 +23,8 @@ import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.UnusedSourceSetsC * threw an exception). If your check aims to prevent some exception, then code that check as soon as possible in the `apply`-block * of the [org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper] or appropriate inheritor */ -internal fun interface KotlinGradleProjectChecker { - fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) +internal interface KotlinGradleProjectChecker { + suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) companion object { val ALL_CHECKERS: List = listOf( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectCheckersRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectCheckersRunner.kt index 349fb7c5170..a73973931cb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectCheckersRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/KotlinGradleProjectCheckersRunner.kt @@ -9,8 +9,9 @@ import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.extraProperties +import org.jetbrains.kotlin.gradle.plugin.launch -internal fun Project.runKotlinGradleProjectCheckers() { +internal fun Project.launchKotlinGradleProjectCheckers() { val checkers = kotlinGradleProjectCheckersOverride ?: KotlinGradleProjectChecker.ALL_CHECKERS val context = KotlinGradleProjectCheckerContext( @@ -21,7 +22,7 @@ internal fun Project.runKotlinGradleProjectCheckers() { val collector = project.kotlinToolingDiagnosticsCollector for (checker in checkers) { - with(checker) { context.runChecks(collector) } + with(checker) { launch { context.runChecks(collector) } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/CommonMainWithDependsOnChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/CommonMainWithDependsOnChecker.kt index 9b6fec2ceba..6de04a20e40 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/CommonMainWithDependsOnChecker.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/CommonMainWithDependsOnChecker.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker import org.jetbrains.kotlin.gradle.plugin.sources.internal internal object CommonMainWithDependsOnChecker : KotlinGradleProjectChecker { - override fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { multiplatformExtension?.sourceSets?.all { if (it.name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) { it.internal.dependsOn.forAll { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/DeprecatedKotlinNativeTargetsChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/DeprecatedKotlinNativeTargetsChecker.kt index 3d2c2755d1f..e7a9ad0debf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/DeprecatedKotlinNativeTargetsChecker.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/DeprecatedKotlinNativeTargetsChecker.kt @@ -13,8 +13,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.konan.target.KonanTarget internal object DeprecatedKotlinNativeTargetsChecker : KotlinGradleProjectChecker { - override fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { - val targets = multiplatformExtension?.targets ?: return + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + val targets = multiplatformExtension?.awaitTargets() ?: return val usedDeprecatedTargets = targets .filter { it is KotlinNativeTarget && it.konanTarget in KonanTarget.deprecatedTargets } .map { it.name } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/MissingNativeStdlibChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/MissingNativeStdlibChecker.kt index 2d6c569495c..64d7b5b4049 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/MissingNativeStdlibChecker.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/MissingNativeStdlibChecker.kt @@ -15,8 +15,8 @@ import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCo import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget internal object MissingNativeStdlibChecker : KotlinGradleProjectChecker { - override fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { - val targets = multiplatformExtension?.targets ?: return + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + val targets = multiplatformExtension?.awaitTargets() ?: return if (targets.isEmpty() || // misconfigured project targets.none { it is KotlinNativeTarget } || // no K/N targets project.hasProperty("kotlin.native.nostdlib") || // suppressed diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/UnusedSourceSetsChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/UnusedSourceSetsChecker.kt index 2908d25f96e..b8cd8d1e7d3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/UnusedSourceSetsChecker.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/diagnostics/checkers/UnusedSourceSetsChecker.kt @@ -10,15 +10,16 @@ import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector import org.jetbrains.kotlin.gradle.plugin.sources.android.androidSourceSetInfoOrNull +import org.jetbrains.kotlin.gradle.plugin.sources.awaitPlatformCompilations import org.jetbrains.kotlin.gradle.plugin.sources.internal internal object UnusedSourceSetsChecker : KotlinGradleProjectChecker { - override fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { - val unusedSourceSets = multiplatformExtension?.sourceSets.orEmpty() + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + val unusedSourceSets = multiplatformExtension?.awaitSourceSets().orEmpty() // Ignoring Android source sets .filter { it.androidSourceSetInfoOrNull == null } - .filter { it.internal.compilations.isEmpty() } + .filter { it.internal.awaitPlatformCompilations().isEmpty() } if (unusedSourceSets.isNotEmpty()) { collector.report(project, KotlinToolingDiagnostics.UnusedSourceSetsWarning(unusedSourceSets.toSet().map { it.name })) diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DiagnosticsReportingFunctionalTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DiagnosticsReportingFunctionalTest.kt index 95ef4afe11f..79cc7d00202 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DiagnosticsReportingFunctionalTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/diagnosticsTests/DiagnosticsReportingFunctionalTest.kt @@ -152,7 +152,7 @@ class DiagnosticsReportingFunctionalTest { private fun buildProjectWithMockedCheckers( name: String? = null, parent: ProjectInternal? = null, - block: ProjectInternal.() -> Unit = { } + block: ProjectInternal.() -> Unit = { }, ): ProjectInternal { val project = buildProject( { @@ -203,19 +203,19 @@ private fun Project.reportOnePerBuildTestDiagnostic(severity: Severity = WARNING } internal object MockChecker : KotlinGradleProjectChecker { - override fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { project.reportTestDiagnostic() } } internal object MockPerProjectChecker : KotlinGradleProjectChecker { - override fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { project.reportOnePerProjectTestDiagnostic() } } internal object MockPerBuildChecker : KotlinGradleProjectChecker { - override fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { + override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) { project.reportOnePerBuildTestDiagnostic() } }