mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] KTIJ-39542 Handle Maven pluginManagement ordering during Kotlin config
Avoid reordering plugins across `build/plugins` and `pluginManagement` when configuring Kotlin in Maven projects. The previous logic assumed the reordered plugin would always be resolved from `build/plugins`, which caused a NoSuchElementException for root POMs that keep javac settings in `pluginManagement`. (cherry picked from commit 431b37eece386b8c85a7a04cfd2a5cc139a4c355) IJ-CR-213466 GitOrigin-RevId: 631849e34a1b0907ac680566bd925378447fae53
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d375e34d0b
commit
8c3d78652c
@@ -201,11 +201,13 @@ class PomFile private constructor(private val xmlFile: XmlFile, val domModel: Ma
|
||||
?: domModel.build.pluginManagement.plugins.plugins.firstOrNull { it.matches(groupArtifact) }
|
||||
|
||||
fun isPluginAfter(plugin: MavenDomPlugin, referencePlugin: MavenDomPlugin): Boolean {
|
||||
require(plugin.parent === referencePlugin.parent) { "Plugins should be siblings" }
|
||||
require(plugin !== referencePlugin)
|
||||
|
||||
val referenceElement = referencePlugin.xmlElement!!
|
||||
var e: PsiElement = plugin.xmlElement!!
|
||||
// `pluginManagement/plugins` and `build/plugins` can both contain the same Maven plugin.
|
||||
// In that case there is no shared sibling order to compare inside one XML container.
|
||||
if (e.parent !== referenceElement.parent) return false
|
||||
|
||||
while (e !== referenceElement) {
|
||||
val prev = e.prevSibling ?: return false
|
||||
@@ -216,13 +218,21 @@ class PomFile private constructor(private val xmlFile: XmlFile, val domModel: Ma
|
||||
}
|
||||
|
||||
private fun ensurePluginAfter(plugin: MavenDomPlugin, referencePlugin: MavenDomPlugin): MavenDomPlugin {
|
||||
// Only reorder plugins that already live in the same XML list. Moving a plugin across
|
||||
// `pluginManagement` and `build/plugins` would change the POM structure instead of order.
|
||||
if (plugin.xmlElement?.parent !== referencePlugin.xmlElement?.parent) {
|
||||
return plugin
|
||||
}
|
||||
|
||||
if (!isPluginAfter(plugin, referencePlugin)) {
|
||||
// rearrange
|
||||
val referenceElement = referencePlugin.xmlElement!!
|
||||
val newElement = referenceElement.parent.addAfter(plugin.xmlElement!!, referenceElement)
|
||||
plugin.xmlTag?.delete()
|
||||
|
||||
return domModel.build.plugins.plugins.single { it.xmlElement == newElement }
|
||||
return (domModel.build.plugins.plugins + domModel.build.pluginManagement.plugins.plugins)
|
||||
.singleOrNull { it.xmlElement == newElement }
|
||||
?: error("Failed to find plugin after reordering in ${xmlFile.name}")
|
||||
}
|
||||
|
||||
return plugin
|
||||
|
||||
+194
@@ -401,6 +401,200 @@ class KotlinSourceRootDirsMavenTest : AbstractKotlinMavenImporterTest() {
|
||||
doTest(project, module, afterFile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test root module with plugin management and processor submodule`() = runBlocking {
|
||||
val mainPom = createProjectPom(
|
||||
"""
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>sub-mod</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.15.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>$KOTLIN_VERSION</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val subModulePom = createModulePom(
|
||||
"sub-mod",
|
||||
"""
|
||||
<parent>
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>sub-mod</artifactId>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>1.6.3</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
importProjectsAsync(mainPom, subModulePom)
|
||||
assertModules("project", "sub-mod")
|
||||
|
||||
val module = project.modules.first { it.name == "project" }
|
||||
|
||||
val afterFile = """<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>sub-mod</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<kotlin.version>2.2.20</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>${'$'}{kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${'$'}{kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${'$'}{kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<jvmTarget>${'$'}{maven.compiler.target}</jvmTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.15.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>default-testCompile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>testCompile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>"""
|
||||
|
||||
val childTextBefore = runReadAction { subModulePom.toPsiFile(project)!!.text }
|
||||
|
||||
doTest(project, module, afterFile)
|
||||
|
||||
val childTextAfter = runReadAction { subModulePom.toPsiFile(project)!!.text }
|
||||
assertEquals(
|
||||
"Submodule POM should stay untouched:\n$childTextAfter",
|
||||
childTextBefore,
|
||||
childTextAfter
|
||||
)
|
||||
}
|
||||
|
||||
private fun doTest(project: Project, module: Module, afterFile: String) {
|
||||
return runInEdtAndGet {
|
||||
val moduleRootManager = ModuleRootManager.getInstance(module)
|
||||
|
||||
Reference in New Issue
Block a user