[Gradle, JS] Throw error in JS part when plugins goes from different classloaders

^KT-39210 fixed
^KT-31669 fixed
This commit is contained in:
Ilya Goncharov
2020-05-28 00:18:27 +03:00
parent 2e39c1164d
commit 39869f009e
4 changed files with 64 additions and 27 deletions
@@ -133,7 +133,7 @@ internal class KotlinGradleBuildServices private constructor(
val onRegister = {
gradle.taskGraph.whenReady {
if (multipleProjectsHolder.isInMultipleProjects(project, kotlinPluginVersion)) {
val loadedInProjects = multipleProjectsHolder.getAffectedProjects(project, kotlinPluginVersion)
val loadedInProjects = multipleProjectsHolder.getAffectedProjects(project, kotlinPluginVersion)!!
if (PropertiesProvider(project).ignorePluginLoadedInMultipleProjects != true) {
project.logger.warn(MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING)
project.logger.warn(
@@ -16,22 +16,13 @@ internal class KotlinPluginInMultipleProjectsHolder(
fun addProject(
project: Project,
kotlinPluginVersion: String? = null,
onRegister: () -> Unit
onRegister: () -> Unit = {}
) {
require(differentVersionsInDifferentProject == (kotlinPluginVersion != null))
val projectPath = project.path
val loadedInProjectsPropertyName = listOf(
"kotlin",
"plugin",
"loaded",
"in",
"projects",
kotlinPluginVersion
)
.filterNotNull()
.joinToString(".")
val loadedInProjectsPropertyName = getPropertyName(kotlinPluginVersion)
if (!differentVersionsInDifferentProject || loadedInProjectPath == null) {
loadedInProjectPath = projectPath
@@ -52,29 +43,47 @@ internal class KotlinPluginInMultipleProjectsHolder(
kotlinPluginVersion: String? = null
): Boolean {
require(differentVersionsInDifferentProject == (kotlinPluginVersion != null))
return getAffectedProjects(project, kotlinPluginVersion).size > 1
return getAffectedProjects(project, kotlinPluginVersion)?.let {
it.size > 1
} ?: false
}
fun getAffectedProjects(
project: Project,
kotlinPluginVersion: String? = null
): List<String> {
): List<String>? {
require(differentVersionsInDifferentProject == (kotlinPluginVersion != null))
val ext = getExt(project)
val loadedInProjectsPropertyName = "kotlin.plugin.loaded.in.projects.${kotlinPluginVersion}"
val propertyName = getPropertyName(kotlinPluginVersion)
return (ext.get(loadedInProjectsPropertyName) as String).split(";")
if (!ext.has(propertyName)) {
return null
}
return (ext.get(propertyName) as String).split(";")
}
private fun getExt(project: Project): ExtraPropertiesExtension {
return project.rootProject.extensions.getByType(ExtraPropertiesExtension::class.java)
}
private fun getPropertyName(version: String?): String {
return listOfNotNull(
"kotlin",
"plugin",
"loaded",
"in",
"projects",
version
)
.joinToString(".")
}
}
const val MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING: String =
"\nThe Kotlin Gradle plugin was loaded multiple times in different subprojects, which is not supported and may break the build. \n" +
"The Kotlin Gradle plugin was loaded multiple times in different subprojects, which is not supported and may break the build. \n" +
"This might happen in subprojects that apply the Kotlin plugins with the Gradle 'plugins { ... }' DSL if they specify " +
"explicit versions, even if the versions are equal.\n" +
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.
*/
@@ -10,10 +10,7 @@ import org.gradle.api.Task
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.tasks.TaskProvider
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTests
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlatformTestRun
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryType
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl
@@ -31,6 +28,23 @@ abstract class KotlinJsIrSubTarget(
private val disambiguationClassifier: String
) : KotlinJsSubTargetDsl {
val project get() = target.project
init {
val kotlinPluginInMultipleProjectsHolder = KotlinPluginInMultipleProjectsHolder(
differentVersionsInDifferentProject = false
)
val anyProjectAffected = kotlinPluginInMultipleProjectsHolder.getAffectedProjects(project)
?.isNotEmpty() ?: false
if (anyProjectAffected) {
error(MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING)
}
kotlinPluginInMultipleProjectsHolder
.addProject(project)
}
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
abstract val testTaskDescription: String
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.
*/
@@ -10,11 +10,8 @@ import org.gradle.api.Task
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.tasks.TaskProvider
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTests
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlatformTestRun
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl
@@ -33,6 +30,23 @@ abstract class KotlinJsSubTarget(
private val disambiguationClassifier: String
) : KotlinJsSubTargetDsl {
val project get() = target.project
init {
val kotlinPluginInMultipleProjectsHolder = KotlinPluginInMultipleProjectsHolder(
differentVersionsInDifferentProject = false
)
val anyProjectAffected = kotlinPluginInMultipleProjectsHolder.getAffectedProjects(project)
?.isNotEmpty() ?: false
if (anyProjectAffected) {
error(MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING)
}
kotlinPluginInMultipleProjectsHolder
.addProject(project)
}
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
abstract val testTaskDescription: String