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 a140418c4d Fix repository ID interpolation in Maven 4 (#11224) (#11241) a140418c4d is described below commit a140418c4dc6b31e036881d7d65f150710afabad Author: Guillaume Nodet <gno...@gmail.com> AuthorDate: Thu Oct 9 19:43:19 2025 +0200 Fix repository ID interpolation in Maven 4 (#11224) (#11241) Repository IDs were not being interpolated while URLs were, causing issues when using expressions like repository.id in repository configurations. This commit adds ID interpolation alongside URL interpolation and includes validation for uninterpolated expressions in repository IDs. Fixes #11076 (cherry picked from commit c81df9d482e7b2643bbfa2a88d1a9c1ddefac8b4) --- .../maven/impl/model/DefaultModelBuilder.java | 1 + .../maven/impl/model/DefaultModelValidator.java | 19 ++++++-- .../impl/model/DefaultModelValidatorTest.java | 18 ++++++++ .../repository-with-uninterpolated-id.xml | 51 ++++++++++++++++++++++ 4 files changed, 86 insertions(+), 3 deletions(-) diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java index 249980d6df..dfd124cc3e 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java @@ -1668,6 +1668,7 @@ private Repository interpolateRepository(Repository repository, UnaryOperator<St ? null : repository .with() + .id(interpolator.interpolate(repository.getId(), callback)) .url(interpolator.interpolate(repository.getUrl(), callback)) .build(); } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java index 18be13c560..d087dcee83 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java @@ -1495,8 +1495,21 @@ private void validateRawRepository( if (repository == null) { return; } - validateStringNotEmpty( - prefix, prefix2, "id", problems, Severity.ERROR, Version.V20, repository.getId(), null, repository); + if (validateStringNotEmpty( + prefix, prefix2, "id", problems, Severity.ERROR, Version.V20, repository.getId(), null, repository)) { + // Check for uninterpolated expressions in ID - these should have been interpolated by now + Matcher matcher = EXPRESSION_NAME_PATTERN.matcher(repository.getId()); + if (matcher.find()) { + addViolation( + problems, + Severity.ERROR, + Version.V40, + prefix + prefix2 + "[" + repository.getId() + "].id", + null, + "contains an uninterpolated expression.", + repository); + } + } if (!allowEmptyUrl && validateStringNotEmpty( @@ -1509,7 +1522,7 @@ && validateStringNotEmpty( repository.getUrl(), null, repository)) { - // Check for uninterpolated expressions - these should have been interpolated by now + // Check for uninterpolated expressions in URL - these should have been interpolated by now Matcher matcher = EXPRESSION_NAME_PATTERN.matcher(repository.getUrl()); if (matcher.find()) { addViolation( diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java index 9948814d4e..d7fe81c2ca 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelValidatorTest.java @@ -874,6 +874,24 @@ void repositoryWithUnsupportedExpression() throws Exception { assertViolations(result, 0, 1, 0); } + @Test + void repositoryWithUninterpolatedId() throws Exception { + SimpleProblemCollector result = validateRaw("raw-model/repository-with-uninterpolated-id.xml"); + // Uninterpolated expressions in repository IDs should cause validation errors + assertViolations(result, 0, 3, 0); + + // Check that all three repository ID validation errors are present + assertTrue(result.getErrors().stream() + .anyMatch(error -> error.contains("repositories.repository.[${repository.id}].id") + && error.contains("contains an uninterpolated expression"))); + assertTrue(result.getErrors().stream() + .anyMatch(error -> error.contains("pluginRepositories.pluginRepository.[${plugin.repository.id}].id") + && error.contains("contains an uninterpolated expression"))); + assertTrue(result.getErrors().stream() + .anyMatch(error -> error.contains("distributionManagement.repository.[${staging.repository.id}].id") + && error.contains("contains an uninterpolated expression"))); + } + @Test void profileActivationWithAllowedExpression() throws Exception { SimpleProblemCollector result = validateRaw( diff --git a/impl/maven-impl/src/test/resources/poms/validation/raw-model/repository-with-uninterpolated-id.xml b/impl/maven-impl/src/test/resources/poms/validation/raw-model/repository-with-uninterpolated-id.xml new file mode 100644 index 0000000000..df4c752b87 --- /dev/null +++ b/impl/maven-impl/src/test/resources/poms/validation/raw-model/repository-with-uninterpolated-id.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<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.1.0</modelVersion> + + <groupId>org.apache.maven.validation</groupId> + <artifactId>project</artifactId> + <version>1.0.0-SNAPSHOT</version> + + <repositories> + <repository> + <id>${repository.id}</id> + <url>https://nexus.acme.com</url> + </repository> + </repositories> + + <pluginRepositories> + <pluginRepository> + <id>${plugin.repository.id}</id> + <url>https://nexus.acme.com</url> + </pluginRepository> + </pluginRepositories> + + <distributionManagement> + <repository> + <id>${staging.repository.id}</id> + <url>https://staging.nexus.acme.com</url> + </repository> + </distributionManagement> + +</project>