From 728c3f2ad29889dab2317bbbf606db7c471a31dd Mon Sep 17 00:00:00 2001 From: Frederik Haselmeier Date: Tue, 1 Aug 2023 07:07:25 +0000 Subject: [PATCH] [kotlin] Fixed Kotlin version defined in pluginManagement block not being reused when configuring Kotlin in new module ^KTIJ-26425 fixed Merge-request: IJ-MR-112104 Merged-by: Frederik Haselmeier GitOrigin-RevId: 8c4cdabcf3d09265988868607f955058e8efaa14 --- .../GradleBuildScriptManipulator.kt | 2 + .../KotlinWithGradleConfigurator.kt | 22 +++- .../groovy/GroovyGradleBuildScriptSupport.kt | 64 ++++++---- .../KotlinBuildScriptManipulator.kt | 113 +++++++++++------- .../gradle/ConversionToKotlinTest.kt | 97 ++++++++++++++- .../app1/build.gradle.kts.after | 4 +- .../build.gradle | 21 ++++ .../build.gradle.after | 25 ++++ .../settings.gradle | 10 ++ .../build.gradle.kts | 20 ++++ .../build.gradle.kts.after | 24 ++++ .../settings.gradle.kts | 11 ++ .../app1/build.gradle.after | 2 +- .../build.gradle | 21 ++++ .../build.gradle.after | 25 ++++ .../settings.gradle | 10 ++ .../build.gradle.kts | 20 ++++ .../build.gradle.kts.after | 24 ++++ .../settings.gradle.kts | 11 ++ 19 files changed, 452 insertions(+), 74 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle.after create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/settings.gradle create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts.after create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/settings.gradle.kts create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle.after create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/settings.gradle create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts.after create mode 100644 plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/settings.gradle.kts diff --git a/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/GradleBuildScriptManipulator.kt b/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/GradleBuildScriptManipulator.kt index 6e0eb2a792d1..18bec7be5810 100644 --- a/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/GradleBuildScriptManipulator.kt +++ b/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/GradleBuildScriptManipulator.kt @@ -56,6 +56,8 @@ interface GradleBuildScriptManipulator { fun findAndRemoveKotlinVersionFromBuildScript(): Boolean + fun findKotlinPluginManagementVersion(): IdeKotlinVersion? + fun changeLanguageFeatureConfiguration(feature: LanguageFeature, state: LanguageFeature.State, forTests: Boolean): PsiElement? fun changeLanguageVersion(version: String, forTests: Boolean): PsiElement? diff --git a/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/KotlinWithGradleConfigurator.kt b/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/KotlinWithGradleConfigurator.kt index 97347ca29be3..bd8b9e28a6a8 100644 --- a/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/KotlinWithGradleConfigurator.kt +++ b/plugins/kotlin/gradle/code-insight-common/src/org/jetbrains/kotlin/idea/gradleCodeInsightCommon/KotlinWithGradleConfigurator.kt @@ -250,16 +250,23 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator { ): ChangedConfiguratorFiles { val changedFiles = ChangedConfiguratorFiles() val topLevelBuildScript = project.getTopLevelBuildScriptPsiFile() - var addVersionToModuleBuildScript = true val modulesWithTheSameKotlin = kotlinVersionsAndModules[kotlinVersion.artifactVersion] val modulesToRemoveKotlinVersion = mutableListOf() // Remove version from modules with the same version as the version to configure: modulesWithTheSameKotlin?.values?.let { modulesToRemoveKotlinVersion.addAll(it) } + val rootModule = getRootModule(project) + val definedVersionInPluginSettings = rootModule?.getBuildScriptSettingsPsiFile()?.let { + GradleBuildScriptSupport.getManipulator(it) + .findKotlinPluginManagementVersion() + } + var addVersionToModuleBuildScript = definedVersionInPluginSettings != kotlinVersion + if (rootModule != null) { + val hasDefinedVersion = kotlinVersionsAndModules.filter { it.key != kotlinVersion.artifactVersion }.isNotEmpty() val addVersionToSettings: Boolean // If there are different Kotlin versions in the project, don't add to settings - if (kotlinVersionsAndModules.filter { it.key != kotlinVersion.artifactVersion }.isNotEmpty()) { + if (hasDefinedVersion || definedVersionInPluginSettings != null) { addVersionToSettings = false } else { // If we have any version in the root module, don't need to add the version to the settings file @@ -347,7 +354,16 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator { } else { getTargetBytecodeVersionFromModule(module, kotlinVersion) } - configureModule(module, file, false, kotlinVersion, jvmTarget, collector, changedFiles, addVersionToModuleBuildScript) + configureModule( + module = module, + file = file, + isTopLevelProjectFile = false, + ideKotlinVersion = kotlinVersion, + jvmTarget = jvmTarget, + collector = collector, + changedFiles = changedFiles, + addVersion = addVersionToModuleBuildScript + ) } else { showErrorMessage( project, diff --git a/plugins/kotlin/gradle/code-insight-groovy/src/org/jetbrains/kotlin/idea/groovy/GroovyGradleBuildScriptSupport.kt b/plugins/kotlin/gradle/code-insight-groovy/src/org/jetbrains/kotlin/idea/groovy/GroovyGradleBuildScriptSupport.kt index 8d7758e81f85..b9d4e99c44d9 100644 --- a/plugins/kotlin/gradle/code-insight-groovy/src/org/jetbrains/kotlin/idea/groovy/GroovyGradleBuildScriptSupport.kt +++ b/plugins/kotlin/gradle/code-insight-groovy/src/org/jetbrains/kotlin/idea/groovy/GroovyGradleBuildScriptSupport.kt @@ -31,6 +31,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner @@ -189,23 +192,39 @@ class GroovyBuildScriptManipulator( override fun findAndRemoveKotlinVersionFromBuildScript(): Boolean { val pluginsBlock = scriptFile.getBlockByName("plugins") return pluginsBlock?.let { - pluginsBlock.findAndRemoveVersionExpressionInPluginsGroup("id 'org.jetbrains.kotlin.jvm'") || - pluginsBlock.findAndRemoveVersionExpressionInPluginsGroup("id \"org.jetbrains.kotlin.jvm\"") + pluginsBlock.findAndRemoveVersionExpressionInPluginsGroup("org.jetbrains.kotlin.jvm") } ?: false } - private fun GrClosableBlock.findAndRemoveVersionExpressionInPluginsGroup(pluginName: String): Boolean { - getChildrenOfType().forEach { - val textWithoutWhitespaces = it.text.filter { letter -> !letter.isWhitespace() } - val pluginNameWithoutWhitespaces = pluginName.filter { letter -> !letter.isWhitespace() } - if (textWithoutWhitespaces.contains(pluginNameWithoutWhitespaces) && textWithoutWhitespaces.contains("version")) { - val psiFactory = GroovyPsiElementFactory.getInstance(project) - val newStatement = psiFactory.createStatementFromText(pluginName) - it.replace(newStatement) - return true + private class PluginExpression(val entireExpression: GrApplicationStatement, val callExpression: GrCallExpression, val versionExpression: GrExpression?) + + private fun GrClosableBlock.findPluginExpressions(pluginName: String): PluginExpression? { + getChildrenOfType().forEach { statement -> + val outerInvokedExpression = statement.invokedExpression as? GrReferenceExpression ?: return@forEach + val outerArgument = statement.expressionArguments.singleOrNull() ?: return@forEach + + if (outerInvokedExpression.referenceName == "id") { + if (outerArgument.text.extractTextFromQuotes() != pluginName) return@forEach + return PluginExpression(statement, statement, null) + } else if (outerInvokedExpression.referenceName != "version") { + return@forEach } + + val innerExpression = outerInvokedExpression.qualifierExpression as? GrApplicationStatement ?: return@forEach + val innerInvokedExpression = innerExpression.invokedExpression as? GrReferenceExpression ?: return@forEach + if (innerInvokedExpression.referenceName != "id") return@forEach + val innerArgument = innerExpression.expressionArguments.singleOrNull() ?: return@forEach + if (innerArgument.text.extractTextFromQuotes() != pluginName) return@forEach + return PluginExpression(statement, innerExpression, outerArgument) } - return false + return null + } + + private fun GrClosableBlock.findAndRemoveVersionExpressionInPluginsGroup(pluginName: String): Boolean { + val pluginExpression = findPluginExpressions(pluginName) ?: return false + if (pluginExpression.versionExpression == null) return false + pluginExpression.entireExpression.replace(pluginExpression.callExpression) + return true } override fun configureSettingsFile(kotlinPluginName: String, version: IdeKotlinVersion): Boolean { @@ -216,6 +235,11 @@ class GroovyBuildScriptManipulator( return originalText != scriptFile.text } + override fun findKotlinPluginManagementVersion(): IdeKotlinVersion? { + val block = scriptFile.getBlockByName("pluginManagement")?.getBlockByName("plugins") ?: return null + val kotlinVersionExpression = block.findPluginExpressions("org.jetbrains.kotlin.jvm")?.versionExpression ?: return null + return IdeKotlinVersion.opt(kotlinVersionExpression.text.extractTextFromQuotes()) + } override fun changeLanguageFeatureConfiguration( feature: LanguageFeature, @@ -374,17 +398,15 @@ class GroovyBuildScriptManipulator( } ?: addLastExpressionInBlockIfNeeded("$parameterName = $defaultValue") } - private fun String.extractTextFromQuotes(quoteCharacter: Char): String? { - val quoteIndex = indexOf(quoteCharacter) - if (quoteIndex != -1) { - val lastQuoteIndex = lastIndexOf(quoteCharacter) - return if (lastQuoteIndex > quoteIndex) substring(quoteIndex + 1, lastQuoteIndex) else null - } - return null + private fun String.extractTextFromQuotes(): String { + val withoutParens = trim(' ', '\t', '(', ')') + val firstChar = withoutParens.firstOrNull() ?: return this + val lastChar = withoutParens.lastOrNull() ?: return this + return if (firstChar == lastChar && (firstChar == '"' || firstChar == '\'')) { + return withoutParens.removeSurrounding(firstChar.toString()) + } else withoutParens } - private fun String.extractTextFromQuotes(): String = extractTextFromQuotes('\'') ?: extractTextFromQuotes('"') ?: this - private fun addOrReplaceKotlinTaskParameter( gradleFile: GroovyFile, parameterName: String, diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/KotlinBuildScriptManipulator.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/KotlinBuildScriptManipulator.kt index bdd82e05f0a6..130eb8dc8679 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/KotlinBuildScriptManipulator.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/KotlinBuildScriptManipulator.kt @@ -64,7 +64,7 @@ class KotlinBuildScriptManipulator( override fun configureSettingsFile(pluginName: String, version: IdeKotlinVersion): Boolean { val originalText = scriptFile.text - scriptFile.getPluginManagementBlock()?.findOrCreateBlock("plugins")?.let { + scriptFile.getOrCreatePluginManagementBlock()?.findOrCreateBlock("plugins")?.let { if (it.findPluginInPluginsGroup(pluginName) == null) { it.addExpressionIfMissing( "$pluginName version \"${version.artifactVersion}\"" @@ -79,11 +79,15 @@ class KotlinBuildScriptManipulator( } override fun findAndRemoveKotlinVersionFromBuildScript(): Boolean { - val pluginsBlock = scriptFile.findScriptInitializer("plugins")?.getBlock() - return pluginsBlock?.let { - it.findAndRemoveVersionExpressionInPluginsGroup("kotlin(\"jvm\")") || - it.findAndRemoveVersionExpressionInPluginsGroup("id(\"org.jetbrains.kotlin.jvm\")") - } ?: false + val pluginsBlock = scriptFile.findScriptInitializer("plugins")?.getBlock() ?: return false + val pluginExpression = pluginsBlock.findPluginExpressions { + it.isKotlinPluginIdentifier() + } + if (pluginExpression?.versionExpression != null) { + pluginExpression.entireExpression.replace(pluginExpression.callExpression) + return true + } + return false } override fun PsiElement.findParentBlock(name: String): PsiElement? { @@ -258,7 +262,7 @@ class KotlinBuildScriptManipulator( ) as? KtCallExpression private fun addPluginRepositoryExpression(expression: String) { - scriptFile.getPluginManagementBlock()?.findOrCreateBlock("repositories")?.addExpressionIfMissing(expression) + scriptFile.getOrCreatePluginManagementBlock()?.findOrCreateBlock("repositories")?.addExpressionIfMissing(expression) } override fun addMavenCentralPluginRepository() { @@ -271,7 +275,7 @@ class KotlinBuildScriptManipulator( override fun addResolutionStrategy(pluginId: String) { scriptFile - .getPluginManagementBlock() + .getOrCreatePluginManagementBlock() ?.findOrCreateBlock("resolutionStrategy") ?.findOrCreateBlock("eachPlugin") ?.addExpressionIfMissing( @@ -324,7 +328,7 @@ class KotlinBuildScriptManipulator( private fun KtBlockExpression.findClassPathDependencyVersion(pluginName: String): String? { return PsiTreeUtil.getChildrenOfAnyType(this, KtCallExpression::class.java).mapNotNull { if (it?.calleeExpression?.text == "classpath") { - val dependencyName = it.valueArguments.firstOrNull()?.text?.removeSurrounding("\"") + val dependencyName = it.valueArguments.firstOrNull()?.text?.extractStringValue() if (dependencyName?.startsWith(pluginName) == true) dependencyName.substringAfter("$pluginName:") else null } else null }.singleOrNull() @@ -338,12 +342,12 @@ class KotlinBuildScriptManipulator( val receiverCalleeExpressionText = receiverCalleeExpression?.calleeExpression?.text?.trim() val receivedPluginName = when { receiverCalleeExpressionText == "id" -> - receiverCalleeExpression.valueArguments.firstOrNull()?.text?.trim()?.removeSurrounding("\"") + receiverCalleeExpression.valueArguments.firstOrNull()?.text?.trim()?.extractStringValue() operatorName == "version" -> receiverCalleeExpressionText else -> null } - val pluginVersionText = pluginVersion?.text?.trim()?.removeSurrounding("\"") ?: return null + val pluginVersionText = pluginVersion?.text?.trim()?.extractStringValue() ?: return null return receivedPluginName?.to(pluginVersionText) } @@ -373,60 +377,77 @@ class KotlinBuildScriptManipulator( return versionsToPluginNames.getOrDefault(pluginName, null) } - private fun KtBlockExpression.findPluginInPluginsGroup(pluginName: String): KtCallExpression? { - return PsiTreeUtil.getChildrenOfAnyType( - this, - KtCallExpression::class.java, - KtBinaryExpression::class.java, - KtDotQualifiedExpression::class.java - ).mapNotNull { - when (it) { - is KtCallExpression -> it - is KtBinaryExpression -> { - if (it.operationReference.text == "version") it.left as? KtCallExpression else null - } + private fun String.extractStringValue(): String { + // Two steps because we want to keep parenthesis inside the string + return trim('(', ')', ' ', '\t').trim('"') + } - is KtDotQualifiedExpression -> { - if ((it.selectorExpression as? KtCallExpression)?.calleeExpression?.text == "version") { - it.receiverExpression as? KtCallExpression - } else null - } - - else -> null - } - }.find { + private fun KtBlockExpression.findPluginInPluginsGroup(pluginName: String): PluginExpression? { + return findPluginExpressions { "${it.calleeExpression?.text?.trim() ?: ""}(${it.valueArguments.firstOrNull()?.text ?: ""})" == pluginName } } - private fun KtBlockExpression.findAndRemoveVersionExpressionInPluginsGroup(pluginName: String): Boolean { - val pluginNameWithoutWhitespaces = pluginName.filter { letter -> !letter.isWhitespace() } + private class PluginExpression( + val entireExpression: KtExpression, + val callExpression: KtCallExpression, + val versionExpression: KtExpression? + ) + + private fun KtBlockExpression.findPluginExpressions(pluginSelector: (KtCallExpression) -> Boolean): PluginExpression? { PsiTreeUtil.getChildrenOfAnyType( this, + KtCallExpression::class.java, KtBinaryExpression::class.java, KtDotQualifiedExpression::class.java ).forEach { when (it) { is KtBinaryExpression -> { - val textWithoutWhitespaces = it.text.filter { letter -> !letter.isWhitespace() } - if (textWithoutWhitespaces.contains(pluginNameWithoutWhitespaces) && textWithoutWhitespaces.contains("version")) { - it.replace(scriptFile.psiFactory.createExpression(pluginName)) - return true - } + val callExpression = it.left as? KtCallExpression ?: return@forEach + if (it.operationReference.text != "version" || !callExpression.let(pluginSelector)) return@forEach + return PluginExpression(it, callExpression, it.right) } is KtDotQualifiedExpression -> { - val textWithoutWhitespaces = it.text.filter { letter -> !letter.isWhitespace() } - if (textWithoutWhitespaces.contains(pluginNameWithoutWhitespaces) && textWithoutWhitespaces.contains("version")) { - it.replace(scriptFile.psiFactory.createExpression(pluginName)) - return true + val selectorExpression = it.selectorExpression as? KtCallExpression ?: return@forEach + if (selectorExpression.calleeExpression?.text != "version") return@forEach + val callExpression = it.receiverExpression as? KtCallExpression ?: return@forEach + if (!callExpression.let(pluginSelector)) return@forEach + val versionExpression = selectorExpression.valueArguments.singleOrNull()?.getArgumentExpression() ?: return@forEach + return PluginExpression(it, callExpression, versionExpression) + } + + is KtCallExpression -> { + if (pluginSelector(it)) { + return PluginExpression(it, it, null) } } } } + return null + } + + private fun KtCallExpression.isKotlinPluginIdentifier(): Boolean { + val valueArguments = valueArguments + if (valueArguments.size != 1) return false + val firstArgumentText = valueArguments.first().text.extractStringValue() + if (calleeExpression?.text == "id") { + return firstArgumentText == "org.jetbrains.kotlin.jvm" + } else if (calleeExpression?.text == "kotlin") { + return firstArgumentText == "jvm" + } return false } + override fun findKotlinPluginManagementVersion(): IdeKotlinVersion? { + val versionExpression = scriptFile.getPluginManagementBlock() + ?.findBlock("plugins") + ?.findPluginExpressions { + it.isKotlinPluginIdentifier() + }?.versionExpression ?: return null + return IdeKotlinVersion.opt(versionExpression.text.extractStringValue()) + } + private fun KtFile.findScriptInitializer(startsWith: String): KtScriptInitializer? = PsiTreeUtil.findChildrenOfType(this, KtScriptInitializer::class.java).find { it.text.startsWith(startsWith) } @@ -473,7 +494,9 @@ class KotlinBuildScriptManipulator( else -> false } - private fun KtFile.getPluginManagementBlock(): KtBlockExpression? = findOrCreateScriptInitializer("pluginManagement", true) + private fun KtFile.getOrCreatePluginManagementBlock(): KtBlockExpression? = findOrCreateScriptInitializer("pluginManagement", true) + + private fun KtFile.getPluginManagementBlock(): KtBlockExpression? = findScriptInitializer("pluginManagement")?.getBlock() private fun KtFile.getKotlinBlock(): KtBlockExpression? = findOrCreateScriptInitializer("kotlin") @@ -507,7 +530,7 @@ class KotlinBuildScriptManipulator( version: IdeKotlinVersion ): KtCallExpression? = getPluginsBlock()?.let { - it.findPluginInPluginsGroup(pluginName) + it.findPluginInPluginsGroup(pluginName)?.callExpression ?: it.addExpressionIfMissing( if (addVersion) { "$pluginName version \"${version.artifactVersion}\"" diff --git a/plugins/kotlin/gradle/gradle-java/tests/test/org/jetbrains/kotlin/idea/codeInsight/gradle/ConversionToKotlinTest.kt b/plugins/kotlin/gradle/gradle-java/tests/test/org/jetbrains/kotlin/idea/codeInsight/gradle/ConversionToKotlinTest.kt index 8d285534f4d2..e7b47423c5e2 100644 --- a/plugins/kotlin/gradle/gradle-java/tests/test/org/jetbrains/kotlin/idea/codeInsight/gradle/ConversionToKotlinTest.kt +++ b/plugins/kotlin/gradle/gradle-java/tests/test/org/jetbrains/kotlin/idea/codeInsight/gradle/ConversionToKotlinTest.kt @@ -7,12 +7,11 @@ import com.intellij.testFramework.runInEdtAndWait import org.jetbrains.kotlin.idea.compiler.configuration.IdeKotlinVersion import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator import org.jetbrains.kotlin.idea.configuration.NotificationMessageCollector +import org.jetbrains.kotlin.idea.configuration.getKotlinVersionsAndModules import org.jetbrains.kotlin.idea.gradleJava.configuration.KotlinGradleModuleConfigurator import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions import org.junit.Test -import org.jetbrains.kotlin.idea.configuration.* - class ConversionToKotlinTest : KotlinGradleImportingTestCase() { @Test @@ -432,6 +431,100 @@ class ConversionToKotlinTest : KotlinGradleImportingTestCase() { } } + @Test + @TargetVersions("7.6+") + fun testReusePluginManagementVersionGroovy() { + val files = importProjectFromTestData() + + runInEdtAndWait { + runWriteAction { + val moduleApp = ModuleManager.getInstance(myProject).findModuleByName("project")!! + val configurator = findGradleModuleConfigurator() + val collector = NotificationMessageCollector.create(myProject) + val (kotlinVersionsAndModules, rootModuleKotlinVersion) = getKotlinVersionsAndModules(myProject, configurator) + configurator.configureWithVersion( + myProject, + listOf(moduleApp), + IdeKotlinVersion.get("1.9.0"), + collector, + kotlinVersionsAndModules, + ) + checkFiles(files) + } + } + } + + + @Test + @TargetVersions("7.6+") + fun testReusePluginManagementVersionKts() { + val files = importProjectFromTestData() + + runInEdtAndWait { + runWriteAction { + val moduleApp = ModuleManager.getInstance(myProject).findModuleByName("project")!! + val configurator = findGradleModuleConfigurator() + val collector = NotificationMessageCollector.create(myProject) + val (kotlinVersionsAndModules, rootModuleKotlinVersion) = getKotlinVersionsAndModules(myProject, configurator) + configurator.configureWithVersion( + myProject, + listOf(moduleApp), + IdeKotlinVersion.get("1.9.0"), + collector, + kotlinVersionsAndModules, + ) + checkFiles(files) + } + } + } + + @Test + @TargetVersions("7.6+") + fun testDontReusePluginManagementDiffVersionGroovy() { + val files = importProjectFromTestData() + + runInEdtAndWait { + runWriteAction { + val moduleApp = ModuleManager.getInstance(myProject).findModuleByName("project")!! + val configurator = findGradleModuleConfigurator() + val collector = NotificationMessageCollector.create(myProject) + val (kotlinVersionsAndModules, rootModuleKotlinVersion) = getKotlinVersionsAndModules(myProject, configurator) + configurator.configureWithVersion( + myProject, + listOf(moduleApp), + IdeKotlinVersion.get("1.8.22"), + collector, + kotlinVersionsAndModules, + ) + checkFiles(files) + } + } + } + + + @Test + @TargetVersions("7.6+") + fun testDontReusePluginManagementDiffVersionKts() { + val files = importProjectFromTestData() + + runInEdtAndWait { + runWriteAction { + val moduleApp = ModuleManager.getInstance(myProject).findModuleByName("project")!! + val configurator = findGradleModuleConfigurator() + val collector = NotificationMessageCollector.create(myProject) + val (kotlinVersionsAndModules, rootModuleKotlinVersion) = getKotlinVersionsAndModules(myProject, configurator) + configurator.configureWithVersion( + myProject, + listOf(moduleApp), + IdeKotlinVersion.get("1.8.22"), + collector, + kotlinVersionsAndModules, + ) + checkFiles(files) + } + } + } + /** * This test fails expectedly because the root module contains 1.8.0 and a submodule contains 1.7.0: * Error resolving plugin [id: 'org.jetbrains.kotlin.jvm', version: '1.7.0'] diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/buildScriptWithWhitespacesKts/app1/build.gradle.kts.after b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/buildScriptWithWhitespacesKts/app1/build.gradle.kts.after index 8b4ca78e6c80..462f6637a231 100644 --- a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/buildScriptWithWhitespacesKts/app1/build.gradle.kts.after +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/buildScriptWithWhitespacesKts/app1/build.gradle.kts.after @@ -1,6 +1,6 @@ plugins { id("java") - kotlin("jvm") + kotlin ("jvm") } group = "org.example" @@ -21,4 +21,4 @@ tasks.test { } kotlin { jvmToolchain(11) -} \ No newline at end of file +} diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle new file mode 100644 index 000000000000..9420f6352ae5 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java' +} + +group 'testgroup' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +java { + setTargetCompatibility(JavaVersion.VERSION_11) +} + +dependencies { +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle.after b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle.after new file mode 100644 index 000000000000..6d97b8a3c85d --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/build.gradle.after @@ -0,0 +1,25 @@ +plugins { + id 'java' + id 'org.jetbrains.kotlin.jvm' version '1.8.22' +} + +group 'testgroup' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +java { +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" +} + +test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(11) +} diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/settings.gradle b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/settings.gradle new file mode 100644 index 000000000000..3fb186606bd7 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionGroovy/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + plugins { + id 'org.jetbrains.kotlin.jvm' version '1.9.0' + } +} +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' +} +rootProject.name = 'project' +include 'app' \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts new file mode 100644 index 000000000000..7e89bdb28977 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts @@ -0,0 +1,20 @@ +plugins { + id("java") +} + +group = "testgroup" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} +java { + setTargetCompatibility(JavaVersion.VERSION_11) +} + +dependencies { +} + +tasks.test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts.after b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts.after new file mode 100644 index 000000000000..7ed2eaba0dc5 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/build.gradle.kts.after @@ -0,0 +1,24 @@ +plugins { + id("java") + kotlin("jvm") version "1.8.22" +} + +group = "testgroup" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} +java { +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(11) +} diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/settings.gradle.kts b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/settings.gradle.kts new file mode 100644 index 000000000000..8471722fb309 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/dontReusePluginManagementDiffVersionKts/settings.gradle.kts @@ -0,0 +1,11 @@ +pluginManagement { + plugins { + kotlin("jvm") version "1.9.0" + } +} +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" +} + +rootProject.name = "project" + diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/projectWithoutRootBuildScriptAndWithSameKotlinVersion/app1/build.gradle.after b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/projectWithoutRootBuildScriptAndWithSameKotlinVersion/app1/build.gradle.after index 34836386ac9c..5a852ebd0d0d 100644 --- a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/projectWithoutRootBuildScriptAndWithSameKotlinVersion/app1/build.gradle.after +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/projectWithoutRootBuildScriptAndWithSameKotlinVersion/app1/build.gradle.after @@ -1,6 +1,6 @@ plugins { id 'java' - id "org.jetbrains.kotlin.jvm" + id "org.jetbrains.kotlin.jvm" } group 'testgroup' diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle new file mode 100644 index 000000000000..9420f6352ae5 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java' +} + +group 'testgroup' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +java { + setTargetCompatibility(JavaVersion.VERSION_11) +} + +dependencies { +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle.after b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle.after new file mode 100644 index 000000000000..d13d3beeb483 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/build.gradle.after @@ -0,0 +1,25 @@ +plugins { + id 'java' + id 'org.jetbrains.kotlin.jvm' +} + +group 'testgroup' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +java { +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" +} + +test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(11) +} diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/settings.gradle b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/settings.gradle new file mode 100644 index 000000000000..07641b439ffa --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionGroovy/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + plugins { + id 'org.jetbrains.kotlin.jvm' + } +} +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' +} +rootProject.name = 'project' +include 'app' \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts new file mode 100644 index 000000000000..7e89bdb28977 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts @@ -0,0 +1,20 @@ +plugins { + id("java") +} + +group = "testgroup" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} +java { + setTargetCompatibility(JavaVersion.VERSION_11) +} + +dependencies { +} + +tasks.test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts.after b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts.after new file mode 100644 index 000000000000..d362c39b30e9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/build.gradle.kts.after @@ -0,0 +1,24 @@ +plugins { + id("java") + kotlin("jvm") +} + +group = "testgroup" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} +java { +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(11) +} diff --git a/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/settings.gradle.kts b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/settings.gradle.kts new file mode 100644 index 000000000000..8471722fb309 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/gradle/kotlinVersionUplift/reusePluginManagementVersionKts/settings.gradle.kts @@ -0,0 +1,11 @@ +pluginManagement { + plugins { + kotlin("jvm") version "1.9.0" + } +} +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" +} + +rootProject.name = "project" +