From 5c2e671a06721fe07cf414a9377a63652d512be0 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Sun, 24 Sep 2023 21:44:27 +0200 Subject: [PATCH] [MNG-7895] Support ${project.basedir} in file profile activation --- api/maven-api-model/src/main/mdo/maven.mdo | 2 +- ...ProfileActivationFilePathInterpolator.java | 6 +- .../activation/FileProfileActivator.java | 5 +- .../validation/DefaultModelValidator.java | 73 ++++++++----------- .../validation/DefaultModelValidatorTest.java | 24 ++++++ ...tivation-file-with-allowed-expressions.xml | 64 ++++++++++++++++ ...tivation-file-with-project-expressions.xml | 48 ++++++++++++ 7 files changed, 169 insertions(+), 53 deletions(-) create mode 100644 maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-allowed-expressions.xml create mode 100644 maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-project-expressions.xml diff --git a/api/maven-api-model/src/main/mdo/maven.mdo b/api/maven-api-model/src/main/mdo/maven.mdo index b7b37b484f..2c24e748e0 100644 --- a/api/maven-api-model/src/main/mdo/maven.mdo +++ b/api/maven-api-model/src/main/mdo/maven.mdo @@ -3007,7 +3007,7 @@ is the location of a file that needs to exist, and if it doesn't, the profile will be activated. On the other hand, {@code exists} will test for the existence of the file and if it is there, the profile will be activated.
- Variable interpolation for these file specifications is limited to {@code ${basedir}}, + Variable interpolation for these file specifications is limited to {@code ${project.basedir}}, system properties and user properties.]]> diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java index 7c420a3e75..1ab4e4734c 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java @@ -69,11 +69,7 @@ public class ProfileActivationFilePathInterpolator { interpolator.addValueSource(new AbstractValueSource(false) { @Override public Object getValue(String expression) { - /* - * We intentionally only support ${basedir} and not ${project.basedir} as the latter form - * would suggest that other project.* expressions can be used which is beyond the design. - */ - if ("basedir".equals(expression)) { + if ("basedir".equals(expression) || "project.basedir".equals(expression)) { return basedir.getAbsolutePath(); } return null; diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java index 0ce909b05e..f7c7dc9cf0 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java @@ -37,11 +37,8 @@ import org.codehaus.plexus.interpolation.InterpolationException; /** * Determines profile activation based on the existence/absence of some file. - * File name interpolation support is limited to ${basedir} (since Maven 3, - * see MNG-2363), + * File name interpolation support is limited to ${project.basedir} * system properties and user properties. - * ${project.basedir} is intentionally not supported as this form would suggest that other - * ${project.*} expressions can be used, which is however beyond the design. * * @see ActivationFile * @see org.apache.maven.model.validation.DefaultModelValidator#validateRawModel diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java index 83e22deb0f..98aa018719 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java @@ -68,6 +68,7 @@ import org.apache.maven.model.v4.MavenModelVersion; public class DefaultModelValidator implements ModelValidator { private static final Pattern EXPRESSION_NAME_PATTERN = Pattern.compile("\\$\\{(.+?)}"); + private static final Pattern EXPRESSION_PROJECT_NAME_PATTERN = Pattern.compile("\\$\\{(project.+?)}"); private static final String ILLEGAL_FS_CHARS = "\\/:\"<>|?*"; @@ -210,8 +211,7 @@ public class DefaultModelValidator implements ModelValidator { profile); } - validate30RawProfileActivation( - problems, profile.getActivation(), profile.getId(), prefix, "activation", request); + validate30RawProfileActivation(problems, profile.getActivation(), prefix); validate20RawDependencies( problems, profile.getDependencies(), prefix, "dependencies.dependency.", request); @@ -283,54 +283,41 @@ public class DefaultModelValidator implements ModelValidator { } } - private void validate30RawProfileActivation( - ModelProblemCollector problems, - Activation activation, - String sourceHint, - String prefix, - String fieldName, - ModelBuildingRequest request) { - if (activation == null) { + private void validate30RawProfileActivation(ModelProblemCollector problems, Activation activation, String prefix) { + if (activation == null || activation.getFile() == null) { return; } ActivationFile file = activation.getFile(); - if (file != null) { - String path; - boolean missing; + String path; + String location; - if (file.getExists() != null && !file.getExists().isEmpty()) { - path = file.getExists(); - missing = false; - } else if (file.getMissing() != null && !file.getMissing().isEmpty()) { - path = file.getMissing(); - missing = true; - } else { - return; - } + if (file.getExists() != null && !file.getExists().isEmpty()) { + path = file.getExists(); + location = "exists"; + } else if (file.getMissing() != null && !file.getMissing().isEmpty()) { + path = file.getMissing(); + location = "missing"; + } else { + return; + } - if (path.contains("${project.basedir}")) { - addViolation( - problems, - Severity.WARNING, - Version.V30, - prefix + fieldName + (missing ? ".file.missing" : ".file.exists"), - null, - "Failed to interpolate file location " + path + " for profile " + sourceHint - + ": ${project.basedir} expression not supported during profile activation, " - + "use ${basedir} instead", - file.getLocation(missing ? "missing" : "exists")); - } else if (hasProjectExpression(path)) { - addViolation( - problems, - Severity.WARNING, - Version.V30, - prefix + fieldName + (missing ? ".file.missing" : ".file.exists"), - null, - "Failed to interpolate file location " + path + " for profile " + sourceHint - + ": ${project.*} expressions are not supported during profile activation", - file.getLocation(missing ? "missing" : "exists")); + if (hasProjectExpression(path)) { + Matcher matcher = EXPRESSION_PROJECT_NAME_PATTERN.matcher(path); + while (matcher.find()) { + String propertyName = matcher.group(0); + if (!"${project.basedir}".equals(propertyName)) { + addViolation( + problems, + Severity.WARNING, + Version.V30, + prefix + "activation.file." + location, + null, + "Failed to interpolate file location " + path + ": " + propertyName + + " expressions are not supported during profile activation.", + file.getLocation(location)); + } } } } diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java index 79973d49cc..1148be9b70 100644 --- a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java +++ b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java @@ -814,4 +814,28 @@ class DefaultModelValidatorTest { SimpleProblemCollector result = validateRaw("raw-model/repository-with-basedir-expression.xml"); assertViolations(result, 0, 0, 0); } + + @Test + void profileActivationWithAllowedExpression() throws Exception { + SimpleProblemCollector result = validateRaw("raw-model/profile-activation-file-with-allowed-expressions.xml"); + assertViolations(result, 0, 0, 0); + } + + @Test + void profileActivationWithProjectExpression() throws Exception { + SimpleProblemCollector result = validateRaw("raw-model/profile-activation-file-with-project-expressions.xml"); + assertViolations(result, 0, 0, 2); + + assertEquals( + "'profiles.profile[exists-project-version].activation.file.exists' " + + "Failed to interpolate file location ${project.version}/test.txt: " + + "${project.version} expressions are not supported during profile activation.", + result.getWarnings().get(0)); + + assertEquals( + "'profiles.profile[missing-project-version].activation.file.missing' " + + "Failed to interpolate file location ${project.version}/test.txt: " + + "${project.version} expressions are not supported during profile activation.", + result.getWarnings().get(1)); + } } diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-allowed-expressions.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-allowed-expressions.xml new file mode 100644 index 0000000000..a4beb6238f --- /dev/null +++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-allowed-expressions.xml @@ -0,0 +1,64 @@ + + + + 4.0.0 + aid + gid + 0.1 + pom + + + + exists-basedir + + + ${basedir}/test.txt + + + + + missing-basedir + + + ${basedir}/test.txt + + + + + + exists-project-basedir + + + ${project.basedir}/test.txt + + + + + missing-project-basedir + + + ${project.basedir}/test.txt + + + + + + diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-project-expressions.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-project-expressions.xml new file mode 100644 index 0000000000..65953c3bb9 --- /dev/null +++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-project-expressions.xml @@ -0,0 +1,48 @@ + + + + 4.0.0 + aid + gid + 0.1 + pom + + + + + exists-project-version + + + ${project.version}/test.txt + + + + + missing-project-version + + + ${project.version}/test.txt + + + + + +