[Gradle] Recreate KotlinPluginInMultipleProjectsHolder on each build

#KT-50598 Fixed
This commit is contained in:
Alexander Likhachev
2022-09-07 17:14:38 +02:00
committed by Space
parent 4b92d2e76c
commit a20fbf867f
4 changed files with 44 additions and 45 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Project
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logging
import org.gradle.api.provider.Provider
import org.gradle.api.services.BuildService
@@ -24,15 +25,43 @@ internal abstract class KotlinGradleBuildServices : BuildService<KotlinGradleBui
private val log = Logging.getLogger(this.javaClass)
private val buildHandler: KotlinGradleFinishBuildHandler = KotlinGradleFinishBuildHandler()
private val CLASS_NAME = KotlinGradleBuildServices::class.java.simpleName
val INIT_MESSAGE = "Initialized $CLASS_NAME"
val DISPOSE_MESSAGE = "Disposed $CLASS_NAME"
private val multipleProjectsHolder = KotlinPluginInMultipleProjectsHolder(
trackPluginVersionsSeparately = true
)
init {
log.kotlinDebug(INIT_MESSAGE)
buildHandler.buildStart()
}
@Synchronized
internal fun detectKotlinPluginLoadedInMultipleProjects(project: Project, kotlinPluginVersion: String) {
val onRegister = {
project.gradle.taskGraph.whenReady {
if (multipleProjectsHolder.isInMultipleProjects(project, kotlinPluginVersion)) {
val loadedInProjects = multipleProjectsHolder.getAffectedProjects(project, kotlinPluginVersion)!!
if (PropertiesProvider(project).ignorePluginLoadedInMultipleProjects != true) {
project.logger.warn("\n$MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING")
project.logger.warn(
MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING + loadedInProjects.joinToString(limit = 4) { "'$it'" }
)
}
project.logger.info(
"$MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_INFO: " +
loadedInProjects.joinToString { "'$it'" }
)
}
}
}
multipleProjectsHolder.addProject(
project,
kotlinPluginVersion,
onRegister
)
}
override fun close() {
buildHandler.buildFinished(parameters.buildDir, parameters.rootDir)
log.kotlinDebug(DISPOSE_MESSAGE)
@@ -42,48 +71,19 @@ internal abstract class KotlinGradleBuildServices : BuildService<KotlinGradleBui
}
companion object {
fun registerIfAbsent(project: Project): Provider<KotlinGradleBuildServices> =
project.gradle.sharedServices.registerIfAbsent(
private val CLASS_NAME = KotlinGradleBuildServices::class.java.simpleName
private val INIT_MESSAGE = "Initialized $CLASS_NAME"
private val DISPOSE_MESSAGE = "Disposed $CLASS_NAME"
fun registerIfAbsent(gradle: Gradle): Provider<KotlinGradleBuildServices> =
gradle.sharedServices.registerIfAbsent(
"kotlin-build-service-${KotlinGradleBuildServices::class.java.canonicalName}_${KotlinGradleBuildServices::class.java.classLoader.hashCode()}",
KotlinGradleBuildServices::class.java
) { service ->
service.parameters.rootDir = project.rootProject.rootDir
service.parameters.buildDir = project.rootProject.buildDir
service.parameters.rootDir = gradle.rootProject.rootDir
service.parameters.buildDir = gradle.rootProject.buildDir
}
private val multipleProjectsHolder = KotlinPluginInMultipleProjectsHolder(
trackPluginVersionsSeparately = true
)
@Synchronized
internal fun detectKotlinPluginLoadedInMultipleProjects(project: Project, kotlinPluginVersion: String) {
val onRegister = {
project.gradle.taskGraph.whenReady {
if (multipleProjectsHolder.isInMultipleProjects(project, kotlinPluginVersion)) {
val loadedInProjects = multipleProjectsHolder.getAffectedProjects(project, kotlinPluginVersion)!!
if (PropertiesProvider(project).ignorePluginLoadedInMultipleProjects != true) {
project.logger.warn("\n$MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING")
project.logger.warn(
MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING + loadedInProjects.joinToString(limit = 4) { "'$it'" }
)
}
project.logger.info(
"$MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_INFO: " +
loadedInProjects.joinToString { "'$it'" }
)
}
}
}
multipleProjectsHolder.addProject(
project,
kotlinPluginVersion,
onRegister
)
}
}
}
@@ -11,9 +11,6 @@ import org.gradle.api.plugins.ExtraPropertiesExtension
internal class KotlinPluginInMultipleProjectsHolder(
private val trackPluginVersionsSeparately: Boolean
) {
// Storing this property here might be considered the reason
// why the corresponding warning message is just shown in the first build
// https://youtrack.jetbrains.com/issue/KT-50598
private var loadedInProjectPath: String? = null
fun addProject(
@@ -88,8 +88,7 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin {
addGradlePluginMetadataAttributes(project)
}
KotlinGradleBuildServices.registerIfAbsent(project).get()
KotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
KotlinGradleBuildServices.registerIfAbsent(project.gradle).get().detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
BuildMetricsService.registerIfAbsent(project)?.also {
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it)
@@ -22,14 +22,17 @@ internal abstract class SingleAction {
}
}
// Warning: if KGP is loaded multiple times by different classloaders, actions may be executed more than once
internal object SingleActionPerBuild : SingleAction() {
override fun selectKey(project: Project): Project = project.rootProject
}
// Warning: if KGP is loaded multiple times by different classloaders, actions may be executed more than once
internal object SingleActionPerProject : SingleAction() {
override fun selectKey(project: Project) = project
}
// Warning: if KGP is loaded multiple times by different classloaders, messages may be shown more than once
internal object SingleWarningPerBuild {
private const val ACTION_ID_SHOW_WARNING = "show-warning:"