This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/maven-4.0.x by this push:
new 0a792e8a8a Use maven-api Version for mvnup plugin version comparison
(#12073)
0a792e8a8a is described below
commit 0a792e8a8a7860c65376aedc3dcf40caa5b23cf9
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue May 19 16:28:13 2026 +0200
Use maven-api Version for mvnup plugin version comparison (#12073)
Replace hand-rolled version comparison with Session.parseVersion() which
correctly handles milestone/pre-release qualifiers. The previous
implementation stripped qualifiers (e.g., 3.0.0-M1 → 3.0.0) causing
pre-release versions to be incorrectly considered sufficient.
This fixes 19 projects (flink-connectors, sling) using enforcer
3.0.0-M1 that mvnup failed to upgrade to 3.0.0.
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
---
.../invoker/mvnup/goals/PluginUpgradeStrategy.java | 28 +--------------
.../mvnup/goals/PluginUpgradeStrategyTest.java | 40 ++++++++++++++++++++++
2 files changed, 41 insertions(+), 27 deletions(-)
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java
index 66f3b91d61..0dcb39883c 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java
@@ -378,33 +378,7 @@ private boolean isVersionBelow(String currentVersion,
String minVersion) {
if (currentVersion == null || minVersion == null) {
return false;
}
-
- // Remove any qualifiers like -SNAPSHOT, -alpha, etc. for comparison
- String cleanCurrent = currentVersion.split("-")[0];
- String cleanMin = minVersion.split("-")[0];
-
- try {
- String[] currentParts = cleanCurrent.split("\\.");
- String[] minParts = cleanMin.split("\\.");
-
- int maxLength = Math.max(currentParts.length, minParts.length);
-
- for (int i = 0; i < maxLength; i++) {
- int currentPart = i < currentParts.length ?
Integer.parseInt(currentParts[i]) : 0;
- int minPart = i < minParts.length ?
Integer.parseInt(minParts[i]) : 0;
-
- if (currentPart < minPart) {
- return true;
- } else if (currentPart > minPart) {
- return false;
- }
- }
-
- return false; // Versions are equal
- } catch (NumberFormatException e) {
- // Fallback to string comparison if parsing fails
- return currentVersion.compareTo(minVersion) < 0;
- }
+ return
getSession().parseVersion(currentVersion).compareTo(getSession().parseVersion(minVersion))
< 0;
}
/**
diff --git
a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java
b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java
index 7366d8c7e1..2ba4de0c2b 100644
---
a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java
+++
b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java
@@ -187,6 +187,46 @@ void shouldNotModifyPluginWhenVersionAlreadySufficient()
throws Exception {
// POM might still be marked as modified due to other plugin
management additions
}
+ @Test
+ @DisplayName("should upgrade milestone version below release minimum")
+ void shouldUpgradeMilestoneVersionBelowRelease() throws Exception {
+ String pomXml = """
+ <?xml version="1.0" encoding="UTF-8"?>
+ <project xmlns="http://maven.apache.org/POM/4.0.0">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>test</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0.0</version>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>3.0.0-M1</version>
+ </plugin>
+ </plugins>
+ </build>
+ </project>
+ """;
+
+ Document document = saxBuilder.build(new StringReader(pomXml));
+ Map<Path, Document> pomMap = Map.of(Paths.get("pom.xml"),
document);
+
+ UpgradeContext context = createMockContext();
+ UpgradeResult result = strategy.apply(context, pomMap);
+
+ assertTrue(result.success(), "Plugin upgrade should succeed");
+ assertTrue(result.modifiedCount() > 0, "Should have upgraded
3.0.0-M1 to 3.0.0");
+
+ Element root = document.getRootElement();
+ Namespace namespace = root.getNamespace();
+ Element build = root.getChild("build", namespace);
+ Element plugins = build.getChild("plugins", namespace);
+ Element plugin = plugins.getChild("plugin", namespace);
+ String version = plugin.getChildText("version", namespace);
+ assertEquals("3.0.0", version, "3.0.0-M1 should be upgraded to
3.0.0");
+ }
+
@Test
@DisplayName("should upgrade plugin in pluginManagement")
void shouldUpgradePluginInPluginManagement() throws Exception {