diff --git a/buildSrc/src/main/kotlin/GradleCommon.kt b/buildSrc/src/main/kotlin/GradleCommon.kt index b177a1b5767..d3aef9da307 100644 --- a/buildSrc/src/main/kotlin/GradleCommon.kt +++ b/buildSrc/src/main/kotlin/GradleCommon.kt @@ -124,7 +124,8 @@ fun Project.createGradleCommonSourceSet(): SourceSet { compileOnlyConfigurationName(kotlinStdlib()) "commonGradleApiCompileOnly"("dev.gradleplugins:gradle-api:7.6") if (this@createGradleCommonSourceSet.name != "kotlin-gradle-plugin-api" && - this@createGradleCommonSourceSet.name != "android-test-fixes" + this@createGradleCommonSourceSet.name != "android-test-fixes" && + this@createGradleCommonSourceSet.name != "gradle-warnings-detector" ) { compileOnlyConfigurationName(project(":kotlin-gradle-plugin-api")) { capabilities { @@ -276,7 +277,8 @@ fun Project.reconfigureMainSourcesSetForGradlePlugin( // gradle plugin variants "compileOnly"("dev.gradleplugins:gradle-api:${GradlePluginVariant.GRADLE_MIN.gradleApiVersion}") if (this@reconfigureMainSourcesSetForGradlePlugin.name != "kotlin-gradle-plugin-api" && - this@reconfigureMainSourcesSetForGradlePlugin.name != "android-test-fixes" + this@reconfigureMainSourcesSetForGradlePlugin.name != "android-test-fixes" && + this@reconfigureMainSourcesSetForGradlePlugin.name != "gradle-warnings-detector" ) { "api"(project(":kotlin-gradle-plugin-api")) } @@ -461,7 +463,8 @@ fun Project.createGradlePluginVariant( variantSourceSet.compileOnlyConfigurationName(kotlinStdlib()) variantSourceSet.compileOnlyConfigurationName("dev.gradleplugins:gradle-api:${variant.gradleApiVersion}") if (this@createGradlePluginVariant.name != "kotlin-gradle-plugin-api" && - this@createGradlePluginVariant.name != "android-test-fixes" + this@createGradlePluginVariant.name != "android-test-fixes" && + this@createGradlePluginVariant.name != "gradle-warnings-detector" ) { variantSourceSet.apiConfigurationName(project(":kotlin-gradle-plugin-api")) { capabilities { @@ -559,6 +562,7 @@ fun Project.addBomCheckTask() { val bomBuildFile = project(":kotlin-gradle-plugins-bom").projectDir.resolve("build.gradle.kts") val exceptions = listOf( project(":gradle:android-test-fixes").path, + project(":gradle:gradle-warnings-detector").path, project(":kotlin-gradle-build-metrics").path, project(":kotlin-gradle-statistics").path, ) diff --git a/libraries/tools/gradle/gradle-warnings-detector/Readme.md b/libraries/tools/gradle/gradle-warnings-detector/Readme.md new file mode 100644 index 00000000000..eb70cc11e15 --- /dev/null +++ b/libraries/tools/gradle/gradle-warnings-detector/Readme.md @@ -0,0 +1,6 @@ +## Description + +Contains a plugin for Gradle integration tests +that helps us to detect deprecation warnings presence regardless of the configured warning mode + +Please don't use this module in real projects and don't rely on it as an example. It uses undocumented internal Gradle API. \ No newline at end of file diff --git a/libraries/tools/gradle/gradle-warnings-detector/build.gradle.kts b/libraries/tools/gradle/gradle-warnings-detector/build.gradle.kts new file mode 100644 index 00000000000..200f14ceee6 --- /dev/null +++ b/libraries/tools/gradle/gradle-warnings-detector/build.gradle.kts @@ -0,0 +1,29 @@ +import plugins.KotlinBuildPublishingPlugin + +plugins { + id("gradle-plugin-common-configuration") +} + +gradlePlugin { + plugins { + create("gradle-warnings-detector") { + id = "org.jetbrains.kotlin.test.gradle-warnings-detector" + displayName = "GradleWarningsDetectorPlugin" + description = displayName + implementationClass = "org.jetbrains.kotlin.gradle.test.GradleWarningsDetectorPlugin" + } + } +} + +// Disable releasing for this plugin +// It is not intended to be released publicly +tasks.withType() + .configureEach { + if (name.endsWith("PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository")) { + enabled = false + } + } + +tasks.named("publishPlugins") { + enabled = false +} \ No newline at end of file diff --git a/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/DeprecationBuildOperationListener.kt b/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/DeprecationBuildOperationListener.kt new file mode 100644 index 00000000000..49c28a7081c --- /dev/null +++ b/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/DeprecationBuildOperationListener.kt @@ -0,0 +1,36 @@ +/* + * 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.test + +import org.gradle.api.provider.Provider + +internal class DeprecationBuildOperationListener( + private val warningsReporter: Provider +) : org.gradle.internal.operations.BuildOperationListener { + override fun started( + buildOperation: org.gradle.internal.operations.BuildOperationDescriptor, + startEvent: org.gradle.internal.operations.OperationStartEvent + ) { + // no-op + } + + override fun progress( + operationIdentifier: org.gradle.internal.operations.OperationIdentifier, + progressEvent: org.gradle.internal.operations.OperationProgressEvent + ) { + val details = progressEvent.details + if (details is org.gradle.internal.featurelifecycle.DefaultDeprecatedUsageProgressDetails) { + warningsReporter.get().hasWarnings = true + } + } + + override fun finished( + buildOperation: org.gradle.internal.operations.BuildOperationDescriptor, + finishEvent: org.gradle.internal.operations.OperationFinishEvent + ) { + // no-op + } +} \ No newline at end of file diff --git a/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/GradleWarningsDetectorPlugin.kt b/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/GradleWarningsDetectorPlugin.kt new file mode 100644 index 00000000000..56ea02a33b7 --- /dev/null +++ b/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/GradleWarningsDetectorPlugin.kt @@ -0,0 +1,29 @@ +/* + * 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.test + +import org.gradle.api.Plugin +import org.gradle.api.initialization.Settings +import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging +import org.gradle.internal.operations.BuildOperationListenerManager +import javax.inject.Inject + +class GradleWarningsDetectorPlugin @Inject constructor( + private val buildOperationListenerManager: BuildOperationListenerManager +) : Plugin { + private val logger: Logger = Logging.getLogger(this.javaClass) + + override fun apply(target: Settings) { + logger.warn("[${GradleWarningsDetectorPlugin::class.java.simpleName}] The plugin is being applied") + val warningsReporter = GradleWarningsReporter.registerIfAbsent(target.gradle) + val deprecationBuildOperationListener = DeprecationBuildOperationListener(warningsReporter) + buildOperationListenerManager.addListener(deprecationBuildOperationListener) + warningsReporter.get().executeAtBuildFinish = { + buildOperationListenerManager.removeListener(deprecationBuildOperationListener) + } + } +} \ No newline at end of file diff --git a/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/GradleWarningsReporter.kt b/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/GradleWarningsReporter.kt new file mode 100644 index 00000000000..60547154a1c --- /dev/null +++ b/libraries/tools/gradle/gradle-warnings-detector/src/common/kotlin/org/jetbrains/kotlin/gradle/test/GradleWarningsReporter.kt @@ -0,0 +1,35 @@ +/* + * 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.test + +import org.gradle.api.invocation.Gradle +import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging +import org.gradle.api.provider.Provider +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters + +internal abstract class GradleWarningsReporter : BuildService, AutoCloseable { + internal var hasWarnings = false + + private val logger: Logger = Logging.getLogger(this.javaClass) + internal var executeAtBuildFinish: (() -> Unit)? = null + + override fun close() { + executeAtBuildFinish?.invoke() + if (hasWarnings) { + logger.warn("[${GradleWarningsDetectorPlugin::class.java.simpleName}] Some deprecation warnings were found during this build.") + } + } + + internal companion object { + private val serviceName = + "${GradleWarningsReporter::class.java.canonicalName}_${GradleWarningsReporter::class.java.classLoader.hashCode()}" + + fun registerIfAbsent(gradle: Gradle): Provider = + gradle.sharedServices.registerIfAbsent(serviceName, GradleWarningsReporter::class.java) {} + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts index bc996bb75ce..c1b5e18ae72 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts @@ -323,6 +323,7 @@ tasks.withType { dependsOn(":kotlin-gradle-plugin:validatePlugins") dependsOnKotlinGradlePluginInstall() dependsOn(":gradle:android-test-fixes:install") + dependsOn(":gradle:gradle-warnings-detector:install") dependsOn(":examples:annotation-processor-example:install") systemProperty("kotlinVersion", rootProject.extra["kotlinVersion"] as String) diff --git a/repo/codebase-tests/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt b/repo/codebase-tests/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt index 411665977ef..66a3e6d240c 100644 --- a/repo/codebase-tests/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt +++ b/repo/codebase-tests/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt @@ -109,6 +109,7 @@ class CodeConformanceTest : TestCase() { "libraries/stdlib/wasm/build", "libraries/tools/atomicfu/build", "libraries/tools/gradle/android-test-fixes/build", + "libraries/tools/gradle/gradle-warnings-detector/build", "libraries/tools/kotlin-allopen/build", "libraries/tools/kotlin-assignment/build", "libraries/tools/kotlin-gradle-build-metrics/build", diff --git a/settings.gradle b/settings.gradle index 119ef9bfbb0..dd14e7a495c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -249,6 +249,7 @@ include ":kotlin-imports-dumper-compiler-plugin", ":kotlin-gradle-plugin-integration-tests", ":kotlin-gradle-plugins-bom", ":gradle:android-test-fixes", + ":gradle:gradle-warnings-detector", ":gradle:regression-benchmark-templates", ":gradle:regression-benchmarks", ":kotlin-tooling-metadata", @@ -755,6 +756,7 @@ project(':kotlin-gradle-plugin-test-utils-embeddable').projectDir = "$rootDir/li project(':kotlin-gradle-plugin-integration-tests').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-integration-tests" as File project(':kotlin-gradle-plugins-bom').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugins-bom" as File project(':gradle:android-test-fixes').projectDir = "$rootDir/libraries/tools/gradle/android-test-fixes" as File +project(':gradle:gradle-warnings-detector').projectDir = "$rootDir/libraries/tools/gradle/gradle-warnings-detector" as File project(":gradle:regression-benchmark-templates").projectDir = "$rootDir/libraries/tools/gradle/regression-benchmark-templates" as File project(":gradle:regression-benchmarks").projectDir = "$rootDir/libraries/tools/gradle/regression-benchmarks" as File project(':kotlin-tooling-metadata').projectDir = "$rootDir/libraries/tools/kotlin-tooling-metadata" as File