You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/05/19 12:58:47 UTC
(maven) 01/01: [maven-4.0.x] Fix mvnup to replace deprecated ${basedir} in repository URLs (#12105)
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch backport/maven-4.0.x/pr-12105
in repository https://gitbox.apache.org/repos/asf/maven.git
commit dc30cbfef5074757ef2ab3d69c517aa2b9e3adec
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Tue May 19 14:51:21 2026 +0200
[maven-4.0.x] Fix mvnup to replace deprecated ${basedir} in repository URLs (#12105)
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
.../mvnup/goals/CompatibilityFixStrategy.java | 12 +-
.../mvnup/goals/CompatibilityFixStrategyTest.java | 197 +++++++++++++++++++++
2 files changed, 204 insertions(+), 5 deletions(-)
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java
index 69e09e0a0d..ff572d49b4 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java
@@ -497,12 +497,14 @@ private boolean fixRepositoryExpressions(Element repositoriesElement, Namespace
Element urlElement = repository.getChild("url", namespace);
if (urlElement != null) {
String url = urlElement.getTextTrim();
- if (url.contains("${")) {
- // Allow repository URL interpolation; do not disable.
- // Keep a gentle warning to help users notice unresolved placeholders at build time.
+ String fixedUrl =
+ url.replace("${basedir}", "${project.basedir}").replace("${pom.basedir}", "${project.basedir}");
+ if (!fixedUrl.equals(url)) {
+ urlElement.setText(fixedUrl);
String repositoryId = getChildText(repository, "id", namespace);
- context.info("Detected interpolated expression in " + elementType + " URL (id: " + repositoryId
- + "): " + url);
+ context.detail("Fixed: replaced deprecated expression in " + elementType + " URL (id: "
+ + repositoryId + "): " + url + " → " + fixedUrl);
+ fixed = true;
}
}
}
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java
index 0a26906012..12bbf60f89 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java
@@ -287,6 +287,203 @@ void shouldRemoveDuplicatePluginsInPluginManagement() throws Exception {
}
}
+ @Nested
+ @DisplayName("Repository Expression Fixes")
+ class RepositoryExpressionFixesTests {
+
+ @Test
+ @DisplayName("should replace ${basedir} with ${project.basedir} in repository URLs")
+ void shouldReplaceBasedirInRepositoryUrls() 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>
+ <repositories>
+ <repository>
+ <id>local-repo</id>
+ <url>file://${basedir}/internal-repository</url>
+ </repository>
+ </repositories>
+ </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(), "Compatibility fix should succeed");
+ assertTrue(result.modifiedCount() > 0, "Should have fixed basedir expression");
+
+ Element root = document.getRootElement();
+ Element repositories = root.getChild("repositories", root.getNamespace());
+ Element repository = repositories.getChild("repository", root.getNamespace());
+ Element url = repository.getChild("url", root.getNamespace());
+ assertEquals(
+ "file://${project.basedir}/internal-repository",
+ url.getTextTrim(),
+ "Should have replaced ${basedir} with ${project.basedir}");
+ }
+
+ @Test
+ @DisplayName("should replace ${pom.basedir} with ${project.basedir} in repository URLs")
+ void shouldReplacePomBasedirInRepositoryUrls() 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>
+ <repositories>
+ <repository>
+ <id>local-repo</id>
+ <url>file://${pom.basedir}/lib</url>
+ </repository>
+ </repositories>
+ </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(), "Compatibility fix should succeed");
+ assertTrue(result.modifiedCount() > 0, "Should have fixed pom.basedir expression");
+
+ Element root = document.getRootElement();
+ Element repositories = root.getChild("repositories", root.getNamespace());
+ Element repository = repositories.getChild("repository", root.getNamespace());
+ Element url = repository.getChild("url", root.getNamespace());
+ assertEquals(
+ "file://${project.basedir}/lib",
+ url.getTextTrim(),
+ "Should have replaced ${pom.basedir} with ${project.basedir}");
+ }
+
+ @Test
+ @DisplayName("should replace ${basedir} in pluginRepository URLs")
+ void shouldReplaceBasedirInPluginRepositoryUrls() 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>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>local-plugins</id>
+ <url>file://${basedir}/plugin-repo</url>
+ </pluginRepository>
+ </pluginRepositories>
+ </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(), "Compatibility fix should succeed");
+ assertTrue(result.modifiedCount() > 0, "Should have fixed basedir in pluginRepository");
+
+ Element root = document.getRootElement();
+ Element pluginRepositories = root.getChild("pluginRepositories", root.getNamespace());
+ Element pluginRepository = pluginRepositories.getChild("pluginRepository", root.getNamespace());
+ Element url = pluginRepository.getChild("url", root.getNamespace());
+ assertEquals(
+ "file://${project.basedir}/plugin-repo",
+ url.getTextTrim(),
+ "Should have replaced ${basedir} with ${project.basedir}");
+ }
+
+ @Test
+ @DisplayName("should replace ${basedir} in profile repository URLs")
+ void shouldReplaceBasedirInProfileRepositoryUrls() 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>
+ <profiles>
+ <profile>
+ <id>local</id>
+ <repositories>
+ <repository>
+ <id>local-repo</id>
+ <url>file://${basedir}/repo</url>
+ </repository>
+ </repositories>
+ </profile>
+ </profiles>
+ </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(), "Compatibility fix should succeed");
+ assertTrue(result.modifiedCount() > 0, "Should have fixed basedir in profile repository");
+
+ Element root = document.getRootElement();
+ Element profiles = root.getChild("profiles", root.getNamespace());
+ Element profile = profiles.getChild("profile", root.getNamespace());
+ Element repositories = profile.getChild("repositories", root.getNamespace());
+ Element repository = repositories.getChild("repository", root.getNamespace());
+ Element url = repository.getChild("url", root.getNamespace());
+ assertEquals(
+ "file://${project.basedir}/repo",
+ url.getTextTrim(),
+ "Should have replaced ${basedir} with ${project.basedir}");
+ }
+
+ @Test
+ @DisplayName("should not modify repository URLs without deprecated expressions")
+ void shouldNotModifyUrlsWithoutDeprecatedExpressions() 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>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <url>https://repo.maven.apache.org/maven2</url>
+ </repository>
+ <repository>
+ <id>local-repo</id>
+ <url>file://${project.basedir}/repo</url>
+ </repository>
+ </repositories>
+ </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(), "Compatibility fix should succeed");
+ assertEquals(0, result.modifiedCount(), "Should not have modified any POMs");
+ }
+ }
+
@Nested
@DisplayName("Strategy Description")
class StrategyDescriptionTests {