Skip to content

Commit 8470ab7

Browse files
gnodetclaude
andcommitted
Upgrade extra-enforcer-rules in mvnup plugin dependency handling
extra-enforcer-rules versions before 1.4 use DependencyGraphBuilder .buildDependencyGraph(MavenProject, ArtifactFilter) which was removed in Maven 4. The mvnup plugin upgrade strategy now also checks and upgrades dependencies declared inside plugin configurations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5868027 commit 8470ab7

2 files changed

Lines changed: 147 additions & 0 deletions

File tree

impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.List;
2929
import java.util.Map;
3030
import java.util.Set;
31+
import java.util.stream.Collectors;
3132

3233
import org.apache.maven.api.RemoteRepository;
3334
import org.apache.maven.api.Session;
@@ -100,6 +101,12 @@ public class PluginUpgradeStrategy extends AbstractUpgradeStrategy {
100101
"3.0.0",
101102
MAVEN_4_COMPATIBILITY_REASON));
102103

104+
private static final List<PluginUpgrade> PLUGIN_DEPENDENCY_UPGRADES = List.of(new PluginUpgrade(
105+
"org.codehaus.mojo",
106+
"extra-enforcer-rules",
107+
"1.4",
108+
"Versions before 1.4 use a removed DependencyGraphBuilder API incompatible with Maven 4"));
109+
103110
private Session session;
104111

105112
@Inject
@@ -281,6 +288,8 @@ private boolean upgradePluginsInSection(
281288
}
282289
}
283290
}
291+
292+
hasUpgrades |= upgradePluginDependencies(pluginElement, namespace, pomDocument, sectionName, context);
284293
}
285294

286295
return hasUpgrades;
@@ -373,6 +382,57 @@ private boolean upgradePropertyVersion(
373382
return false;
374383
}
375384

385+
/**
386+
* Upgrades plugin dependencies (e.g., extra-enforcer-rules inside maven-enforcer-plugin).
387+
*/
388+
private boolean upgradePluginDependencies(
389+
Element pluginElement,
390+
Namespace namespace,
391+
Document pomDocument,
392+
String sectionName,
393+
UpgradeContext context) {
394+
Element dependenciesElement = pluginElement.getChild("dependencies", namespace);
395+
if (dependenciesElement == null) {
396+
return false;
397+
}
398+
399+
Map<String, PluginUpgradeInfo> depUpgrades = getPluginDependencyUpgradesMap();
400+
boolean hasUpgrades = false;
401+
402+
List<Element> depElements = dependenciesElement.getChildren("dependency", namespace);
403+
for (Element depElement : depElements) {
404+
String groupId = getChildText(depElement, GROUP_ID, namespace);
405+
String artifactId = getChildText(depElement, ARTIFACT_ID, namespace);
406+
407+
if (groupId != null && artifactId != null) {
408+
String depKey = groupId + ":" + artifactId;
409+
PluginUpgradeInfo upgrade = depUpgrades.get(depKey);
410+
411+
if (upgrade != null) {
412+
if (upgradePluginVersion(
413+
depElement,
414+
namespace,
415+
upgrade,
416+
pomDocument,
417+
sectionName + "/plugin/dependencies",
418+
context)) {
419+
hasUpgrades = true;
420+
}
421+
}
422+
}
423+
}
424+
425+
return hasUpgrades;
426+
}
427+
428+
private Map<String, PluginUpgradeInfo> getPluginDependencyUpgradesMap() {
429+
return PLUGIN_DEPENDENCY_UPGRADES.stream()
430+
.collect(Collectors.toMap(
431+
upgrade -> upgrade.groupId() + ":" + upgrade.artifactId(),
432+
upgrade ->
433+
new PluginUpgradeInfo(upgrade.groupId(), upgrade.artifactId(), upgrade.minVersion())));
434+
}
435+
376436
/**
377437
* Simple version comparison to check if current version is below minimum version.
378438
* This is a basic implementation that works for most Maven plugin versions.

impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,93 @@ void shouldNotUpgradeWhenPropertyNotFound() throws Exception {
428428
}
429429
}
430430

431+
@Nested
432+
@DisplayName("Plugin Dependency Upgrades")
433+
class PluginDependencyUpgradeTests {
434+
435+
@Test
436+
@DisplayName("should upgrade extra-enforcer-rules dependency when below minimum")
437+
void shouldUpgradeExtraEnforcerRulesDependency() throws Exception {
438+
String pomXml = """
439+
<?xml version="1.0" encoding="UTF-8"?>
440+
<project xmlns="http://maven.apache.org/POM/4.0.0">
441+
<modelVersion>4.0.0</modelVersion>
442+
<groupId>test</groupId>
443+
<artifactId>test</artifactId>
444+
<version>1.0.0</version>
445+
<build>
446+
<plugins>
447+
<plugin>
448+
<groupId>org.apache.maven.plugins</groupId>
449+
<artifactId>maven-enforcer-plugin</artifactId>
450+
<version>3.5.0</version>
451+
<dependencies>
452+
<dependency>
453+
<groupId>org.codehaus.mojo</groupId>
454+
<artifactId>extra-enforcer-rules</artifactId>
455+
<version>1.0-beta-4</version>
456+
</dependency>
457+
</dependencies>
458+
</plugin>
459+
</plugins>
460+
</build>
461+
</project>
462+
""";
463+
464+
Document document = saxBuilder.build(new StringReader(pomXml));
465+
Map<Path, Document> pomMap = Map.of(Paths.get("pom.xml"), document);
466+
467+
UpgradeContext context = createMockContext();
468+
UpgradeResult result = strategy.doApply(context, pomMap);
469+
470+
assertTrue(result.success(), "Plugin dependency upgrade should succeed");
471+
assertTrue(result.modifiedCount() > 0, "Should have upgraded extra-enforcer-rules");
472+
473+
String xml = new XMLOutputter().outputString(document);
474+
assertTrue(xml.contains("<version>1.4</version>"), "extra-enforcer-rules should be upgraded to 1.4");
475+
assertFalse(xml.contains("1.0-beta-4"), "Old version should be gone");
476+
}
477+
478+
@Test
479+
@DisplayName("should not upgrade extra-enforcer-rules when version is already sufficient")
480+
void shouldNotUpgradeExtraEnforcerRulesWhenSufficient() throws Exception {
481+
String pomXml = """
482+
<?xml version="1.0" encoding="UTF-8"?>
483+
<project xmlns="http://maven.apache.org/POM/4.0.0">
484+
<modelVersion>4.0.0</modelVersion>
485+
<groupId>test</groupId>
486+
<artifactId>test</artifactId>
487+
<version>1.0.0</version>
488+
<build>
489+
<plugins>
490+
<plugin>
491+
<groupId>org.apache.maven.plugins</groupId>
492+
<artifactId>maven-enforcer-plugin</artifactId>
493+
<version>3.5.0</version>
494+
<dependencies>
495+
<dependency>
496+
<groupId>org.codehaus.mojo</groupId>
497+
<artifactId>extra-enforcer-rules</artifactId>
498+
<version>1.8.0</version>
499+
</dependency>
500+
</dependencies>
501+
</plugin>
502+
</plugins>
503+
</build>
504+
</project>
505+
""";
506+
507+
Document document = saxBuilder.build(new StringReader(pomXml));
508+
Map<Path, Document> pomMap = Map.of(Paths.get("pom.xml"), document);
509+
510+
UpgradeContext context = createMockContext();
511+
strategy.doApply(context, pomMap);
512+
513+
String xml = new XMLOutputter().outputString(document);
514+
assertTrue(xml.contains("1.8.0"), "Version 1.8.0 should be preserved");
515+
}
516+
}
517+
431518
@Nested
432519
@DisplayName("Plugin Management")
433520
class PluginManagementTests {

0 commit comments

Comments
 (0)