diff --git a/pom.xml b/pom.xml index 0de3e5b3..3688f4ab 100644 --- a/pom.xml +++ b/pom.xml @@ -264,6 +264,11 @@ under the License. junit-jupiter-api test + + org.junit.jupiter + junit-jupiter-params + test + org.mockito mockito-core @@ -377,6 +382,10 @@ under the License. + + org.eclipse.sisu + sisu-maven-plugin + diff --git a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java index 09987f4b..92f4583a 100644 --- a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java +++ b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java @@ -410,6 +410,10 @@ public abstract class AbstractInvokerMojo extends AbstractMojo { /** * The MAVEN_OPTS environment variable to use when invoking Maven. This value can be overridden for * individual integration tests by using {@link #invokerPropertiesFile}. + *
+ * Since the version 3.7.0 using an alternate syntax for mavenOpts, @{...} + * allows late replacement of properties when the plugin is executed, + * so properties that have been modified by other plugins will be picked up correctly. * * @since 1.2 */ @@ -739,6 +743,9 @@ public abstract class AbstractInvokerMojo extends AbstractMojo { @Component private ToolchainManagerPrivate toolchainManagerPrivate; + @Component + private InterpolatorUtils interpolatorUtils; + /** * Invokes Maven on the configured test projects. * @@ -2363,7 +2370,7 @@ private InvokerProperties getInvokerProperties(final File projectDirectory, Prop invokerProperties.setDefaultGoals(goals); invokerProperties.setDefaultProfiles(profiles); invokerProperties.setDefaultMavenExecutable(mavenExecutable); - invokerProperties.setDefaultMavenOpts(mavenOpts); + invokerProperties.setDefaultMavenOpts(interpolatorUtils.interpolateAtPattern(mavenOpts)); invokerProperties.setDefaultTimeoutInSeconds(timeoutInSeconds); invokerProperties.setDefaultEnvironmentVariables(environmentVariables); invokerProperties.setDefaultUpdateSnapshots(updateSnapshots); diff --git a/src/main/java/org/apache/maven/plugins/invoker/InterpolatorUtils.java b/src/main/java/org/apache/maven/plugins/invoker/InterpolatorUtils.java new file mode 100644 index 00000000..a4804b9b --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/invoker/InterpolatorUtils.java @@ -0,0 +1,62 @@ +/* + * 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. + */ +package org.apache.maven.plugins.invoker; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.interpolation.InterpolationException; +import org.codehaus.plexus.interpolation.Interpolator; +import org.codehaus.plexus.interpolation.MapBasedValueSource; +import org.codehaus.plexus.interpolation.RegexBasedInterpolator; + +/** + * Helper component for interpolating values. + */ +@Named +class InterpolatorUtils { + + private final Interpolator atInterpolator; + + /** + * A default constructor. + * + * @param mavenProject a MavenProject + */ + @Inject + InterpolatorUtils(MavenProject mavenProject) { + atInterpolator = new RegexBasedInterpolator("[@\\$]\\{(.+?)", "}"); + atInterpolator.addValueSource(new MapBasedValueSource(mavenProject.getProperties())); + } + + public String interpolateAtPattern(String value) throws MojoExecutionException { + + if (value == null || !(value.contains("@{") || value.contains("${"))) { + return value; + } + + try { + return atInterpolator.interpolate(value); + } catch (InterpolationException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } +} diff --git a/src/test/java/org/apache/maven/plugins/invoker/InterpolatorUtilsTest.java b/src/test/java/org/apache/maven/plugins/invoker/InterpolatorUtilsTest.java new file mode 100644 index 00000000..ceab70aa --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/invoker/InterpolatorUtilsTest.java @@ -0,0 +1,71 @@ +/* + * 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. + */ +package org.apache.maven.plugins.invoker; + +import java.util.Properties; +import java.util.stream.Stream; + +import org.apache.maven.project.MavenProject; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class InterpolatorUtilsTest { + + @Mock + private MavenProject mavenProject; + + static Stream testAtInterpolate() { + return Stream.of( + Arguments.of(null, null), + Arguments.of("test", "test"), + Arguments.of("test@test", "test@test"), + Arguments.of("test$test", "test$test"), + Arguments.of("@{test}", "testInProps"), + Arguments.of("${test}", "testInProps"), + Arguments.of("test @{test} test", "test testInProps test"), + Arguments.of("test ${test} test", "test testInProps test"), + Arguments.of("@{test} @{test}", "testInProps testInProps"), + Arguments.of("${test} ${test}", "testInProps testInProps"), + Arguments.of("@{test} ${test}", "testInProps testInProps")); + } + + @ParameterizedTest + @MethodSource + void testAtInterpolate(String input, String expected) throws Exception { + // given + Properties properties = new Properties(); + properties.put("test", "testInProps"); + when(mavenProject.getProperties()).thenReturn(properties); + InterpolatorUtils interpolatorUtils = new InterpolatorUtils(mavenProject); + + // when + String output = interpolatorUtils.interpolateAtPattern(input); + + // then + assertThat(output).isEqualTo(expected); + } +} diff --git a/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java b/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java index d57a5876..fd603222 100644 --- a/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/invoker/InvokerMojoTest.java @@ -49,11 +49,13 @@ private MavenProject getMavenProject() { @Test void testSingleInvokerTest() throws Exception { // given + MavenProject mavenProject = getMavenProject(); InvokerMojo invokerMojo = new InvokerMojo(); String dirPath = getBasedir() + "/src/test/resources/unit"; setVariableValueToObject(invokerMojo, "projectsDirectory", new File(dirPath)); setVariableValueToObject(invokerMojo, "invokerPropertiesFile", "invoker.properties"); - setVariableValueToObject(invokerMojo, "project", getMavenProject()); + setVariableValueToObject(invokerMojo, "project", mavenProject); + setVariableValueToObject(invokerMojo, "interpolatorUtils", new InterpolatorUtils(mavenProject)); setVariableValueToObject(invokerMojo, "invokerTest", "*dummy*"); setVariableValueToObject(invokerMojo, "settings", new Settings()); @@ -67,11 +69,13 @@ void testSingleInvokerTest() throws Exception { @Test void testMultiInvokerTest() throws Exception { // given + MavenProject mavenProject = getMavenProject(); InvokerMojo invokerMojo = new InvokerMojo(); String dirPath = getBasedir() + "/src/test/resources/unit"; setVariableValueToObject(invokerMojo, "projectsDirectory", new File(dirPath)); setVariableValueToObject(invokerMojo, "invokerPropertiesFile", "invoker.properties"); - setVariableValueToObject(invokerMojo, "project", getMavenProject()); + setVariableValueToObject(invokerMojo, "project", mavenProject); + setVariableValueToObject(invokerMojo, "interpolatorUtils", new InterpolatorUtils(mavenProject)); setVariableValueToObject(invokerMojo, "invokerTest", "*dummy*,*terpolatio*"); setVariableValueToObject(invokerMojo, "settings", new Settings()); @@ -85,11 +89,13 @@ void testMultiInvokerTest() throws Exception { @Test void testFullPatternInvokerTest() throws Exception { // given + MavenProject mavenProject = getMavenProject(); InvokerMojo invokerMojo = new InvokerMojo(); String dirPath = getBasedir() + "/src/test/resources/unit"; setVariableValueToObject(invokerMojo, "projectsDirectory", new File(dirPath)); setVariableValueToObject(invokerMojo, "invokerPropertiesFile", "invoker.properties"); - setVariableValueToObject(invokerMojo, "project", getMavenProject()); + setVariableValueToObject(invokerMojo, "project", mavenProject); + setVariableValueToObject(invokerMojo, "interpolatorUtils", new InterpolatorUtils(mavenProject)); setVariableValueToObject(invokerMojo, "invokerTest", "*"); setVariableValueToObject(invokerMojo, "settings", new Settings()); @@ -106,11 +112,13 @@ void testFullPatternInvokerTest() throws Exception { @Test void testSetupInProjectList() throws Exception { // given + MavenProject mavenProject = getMavenProject(); InvokerMojo invokerMojo = new InvokerMojo(); String dirPath = getBasedir() + "/src/test/resources/unit"; setVariableValueToObject(invokerMojo, "projectsDirectory", new File(dirPath)); setVariableValueToObject(invokerMojo, "invokerPropertiesFile", "invoker.properties"); - setVariableValueToObject(invokerMojo, "project", getMavenProject()); + setVariableValueToObject(invokerMojo, "project", mavenProject); + setVariableValueToObject(invokerMojo, "interpolatorUtils", new InterpolatorUtils(mavenProject)); setVariableValueToObject(invokerMojo, "settings", new Settings()); setVariableValueToObject(invokerMojo, "setupIncludes", Collections.singletonList("dum*/pom.xml")); @@ -134,11 +142,13 @@ void testSetupInProjectList() throws Exception { @Test void testSetupProjectIsFiltered() throws Exception { // given + MavenProject mavenProject = getMavenProject(); InvokerMojo invokerMojo = new InvokerMojo(); String dirPath = getBasedir() + "/src/test/resources/unit"; setVariableValueToObject(invokerMojo, "projectsDirectory", new File(dirPath)); setVariableValueToObject(invokerMojo, "invokerPropertiesFile", "invoker.properties"); - setVariableValueToObject(invokerMojo, "project", getMavenProject()); + setVariableValueToObject(invokerMojo, "project", mavenProject); + setVariableValueToObject(invokerMojo, "interpolatorUtils", new InterpolatorUtils(mavenProject)); setVariableValueToObject(invokerMojo, "settings", new Settings()); setVariableValueToObject(invokerMojo, "setupIncludes", Collections.singletonList("dum*/pom.xml")); setVariableValueToObject(invokerMojo, "invokerTest", "*project-dir*");