[MNG-7750] Fix unwanted interpolation in plugins from profiles. (#1075)

This is ONLY the reproduction of the problem I found.

If you disable the activeProfile (in buildPom and remove the assert) then all checks pass.

If you enable this profile (provided code) then in several places the ${project.basedir} has been interpolated and shows the path of the build and the assertions fail the build.

---

https://issues.apache.org/jira/browse/MNG-7750
This commit is contained in:
Niels Basjes 2023-04-12 12:26:47 +02:00 committed by GitHub
parent 36a4e9ff64
commit 0f18470576
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 446 additions and 4 deletions

View File

@ -26,8 +26,12 @@ import java.util.Map;
import java.util.Properties;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.Profile;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.project.harness.PomTestWrapper;
import org.apache.maven.repository.RepositorySystem;
@ -38,6 +42,7 @@ import org.codehaus.plexus.PlexusTestCase;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.repository.LocalRepository;
import org.junit.Assert;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.lessThan;
@ -133,6 +138,197 @@ public class PomConstructionTest extends PlexusTestCase {
assertEquals("PASSED", pom.getValue("properties[1]/property"));
}
/*MNG-7750*/
private void checkBuildPluginWithArtifactId(
List<Plugin> plugins, String artifactId, String expectedId, String expectedConfig) {
Plugin plugin = plugins.stream()
.filter(p -> p.getArtifactId().equals(artifactId))
.findFirst()
.orElse(null);
assertNotNull("Unable to find plugin with artifactId: " + artifactId, plugin);
List<PluginExecution> pluginExecutions = plugin.getExecutions();
assertEquals("Wrong number of plugin executions for \"" + artifactId + "\"", 1, pluginExecutions.size());
assertEquals(
"Wrong id for \"" + artifactId + "\"",
expectedId,
pluginExecutions.get(0).getId());
String config = pluginExecutions.get(0).getConfiguration().toString();
assertTrue(
"Wrong config for \"" + artifactId + "\": (" + config + ") does not contain :" + expectedConfig,
config.contains(expectedConfig));
}
public void testBuildPluginInterpolation() throws Exception {
PomTestWrapper pom = buildPom("plugin-interpolation-build", "activeProfile");
Model originalModel = pom.getMavenProject().getOriginalModel();
// =============================================
assertEquals("||${project.basedir}||", originalModel.getProperties().get("prop-outside"));
List<Plugin> outsidePlugins = originalModel.getBuild().getPlugins();
Assert.assertEquals(1, outsidePlugins.size());
checkBuildPluginWithArtifactId(
outsidePlugins,
"plugin-all-profiles",
"Outside ||${project.basedir}||",
"<plugin-all-profiles-out>Outside ||${project.basedir}||</plugin-all-profiles-out>");
// =============================================
Profile activeProfile = originalModel.getProfiles().stream()
.filter(profile -> profile.getId().equals("activeProfile"))
.findFirst()
.orElse(null);
assertNotNull("Unable to find the activeProfile", activeProfile);
assertTrue(
"The activeProfile should be active in the maven project",
pom.getMavenProject().getActiveProfiles().contains(activeProfile));
assertEquals("||${project.basedir}||", activeProfile.getProperties().get("prop-active"));
List<Plugin> activeProfilePlugins = activeProfile.getBuild().getPlugins();
assertEquals("Number of active profile plugins", 2, activeProfilePlugins.size());
checkBuildPluginWithArtifactId(
activeProfilePlugins,
"plugin-all-profiles",
"Active all ||${project.basedir}||",
"<plugin-all-profiles-in>Active all ||${project.basedir}||</plugin-all-profiles-in>");
checkBuildPluginWithArtifactId(
activeProfilePlugins,
"only-active-profile",
"Active only ||${project.basedir}||",
"<plugin-in-active-profile-only>Active only ||${project.basedir}||</plugin-in-active-profile-only>");
// =============================================
Profile inactiveProfile = originalModel.getProfiles().stream()
.filter(profile -> profile.getId().equals("inactiveProfile"))
.findFirst()
.orElse(null);
assertNotNull("Unable to find the inactiveProfile", inactiveProfile);
assertFalse(
"The inactiveProfile should NOT be active in the maven project",
pom.getMavenProject().getActiveProfiles().contains(inactiveProfile));
assertEquals("||${project.basedir}||", inactiveProfile.getProperties().get("prop-inactive"));
List<Plugin> inactiveProfilePlugins = inactiveProfile.getBuild().getPlugins();
assertEquals("Number of active profile plugins", 2, inactiveProfilePlugins.size());
checkBuildPluginWithArtifactId(
inactiveProfilePlugins,
"plugin-all-profiles",
"Inactive all ||${project.basedir}||",
"<plugin-all-profiles-ina>Inactive all ||${project.basedir}||</plugin-all-profiles-ina>");
checkBuildPluginWithArtifactId(
inactiveProfilePlugins,
"only-inactive-profile",
"Inactive only ||${project.basedir}||",
"<plugin-in-inactive-only>Inactive only ||${project.basedir}||</plugin-in-inactive-only>");
}
private void checkReportPluginWithArtifactId(
List<ReportPlugin> plugins, String artifactId, String expectedId, String expectedConfig) {
ReportPlugin plugin = plugins.stream()
.filter(p -> p.getArtifactId().equals(artifactId))
.findFirst()
.orElse(null);
assertNotNull("Unable to find plugin with artifactId: " + artifactId, plugin);
List<ReportSet> pluginReportSets = plugin.getReportSets();
assertEquals("Wrong number of plugin reportSets for \"" + artifactId + "\"", 1, pluginReportSets.size());
assertEquals(
"Wrong id for \"" + artifactId + "\"",
expectedId,
pluginReportSets.get(0).getId());
String config = pluginReportSets.get(0).getConfiguration().toString();
assertTrue(
"Wrong config for \"" + artifactId + "\": (" + config + ") does not contain :" + expectedConfig,
config.contains(expectedConfig));
}
public void testReportingPluginInterpolation() throws Exception {
PomTestWrapper pom = buildPom("plugin-interpolation-reporting", "activeProfile");
Model originalModel = pom.getMavenProject().getOriginalModel();
// =============================================
assertEquals("||${project.basedir}||", originalModel.getProperties().get("prop-outside"));
List<ReportPlugin> outsidePlugins = originalModel.getReporting().getPlugins();
Assert.assertEquals(1, outsidePlugins.size());
checkReportPluginWithArtifactId(
outsidePlugins,
"plugin-all-profiles",
"Outside ||${project.basedir}||",
"<plugin-all-profiles-out>Outside ||${project.basedir}||</plugin-all-profiles-out>");
// =============================================
Profile activeProfile = originalModel.getProfiles().stream()
.filter(profile -> profile.getId().equals("activeProfile"))
.findFirst()
.orElse(null);
assertNotNull("Unable to find the activeProfile", activeProfile);
assertTrue(
"The activeProfile should be active in the maven project",
pom.getMavenProject().getActiveProfiles().contains(activeProfile));
assertEquals("||${project.basedir}||", activeProfile.getProperties().get("prop-active"));
List<ReportPlugin> activeProfilePlugins = activeProfile.getReporting().getPlugins();
assertEquals("Number of active profile plugins", 2, activeProfilePlugins.size());
checkReportPluginWithArtifactId(
activeProfilePlugins,
"plugin-all-profiles",
"Active all ||${project.basedir}||",
"<plugin-all-profiles-in>Active all ||${project.basedir}||</plugin-all-profiles-in>");
checkReportPluginWithArtifactId(
activeProfilePlugins,
"only-active-profile",
"Active only ||${project.basedir}||",
"<plugin-in-active-profile-only>Active only ||${project.basedir}||</plugin-in-active-profile-only>");
// =============================================
Profile inactiveProfile = originalModel.getProfiles().stream()
.filter(profile -> profile.getId().equals("inactiveProfile"))
.findFirst()
.orElse(null);
assertNotNull("Unable to find the inactiveProfile", inactiveProfile);
assertFalse(
"The inactiveProfile should NOT be active in the maven project",
pom.getMavenProject().getActiveProfiles().contains(inactiveProfile));
assertEquals("||${project.basedir}||", inactiveProfile.getProperties().get("prop-inactive"));
List<ReportPlugin> inactiveProfilePlugins =
inactiveProfile.getReporting().getPlugins();
assertEquals("Number of active profile plugins", 2, inactiveProfilePlugins.size());
checkReportPluginWithArtifactId(
inactiveProfilePlugins,
"plugin-all-profiles",
"Inactive all ||${project.basedir}||",
"<plugin-all-profiles-ina>Inactive all ||${project.basedir}||</plugin-all-profiles-ina>");
checkReportPluginWithArtifactId(
inactiveProfilePlugins,
"only-inactive-profile",
"Inactive only ||${project.basedir}||",
"<plugin-in-inactive-only>Inactive only ||${project.basedir}||</plugin-in-inactive-only>");
}
// Some better conventions for the test poms needs to be created and each of these tests
// that represent a verification of a specification item needs to be a couple lines at most.
// The expressions help a lot, but we need a clean to pick up a directory of POMs, automatically load

View File

@ -0,0 +1,123 @@
<?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.0.0</modelVersion>
<groupId>org.apache.maven.its.build.plugins</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<name>MNG-7750</name>
<description>
Test build plugin and execution interpolation.
</description>
<properties>
<prop-outside>||${project.basedir}||</prop-outside>
</properties>
<build>
<plugins>
<plugin>
<artifactId>plugin-all-profiles</artifactId>
<executions>
<execution>
<id>Outside ||${project.basedir}||</id>
<configuration>
<plugin-all-profiles-out>Outside ||${project.basedir}||</plugin-all-profiles-out>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>activeProfile</id>
<properties>
<prop-active>||${project.basedir}||</prop-active>
</properties>
<build>
<plugins>
<plugin>
<artifactId>plugin-all-profiles</artifactId>
<executions>
<execution>
<id>Active all ||${project.basedir}||</id>
<configuration>
<plugin-all-profiles-in>Active all ||${project.basedir}||</plugin-all-profiles-in>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>only-active-profile</artifactId>
<executions>
<execution>
<id>Active only ||${project.basedir}||</id>
<configuration>
<plugin-in-active-profile-only>Active only ||${project.basedir}||</plugin-in-active-profile-only>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>inactiveProfile</id>
<properties>
<prop-inactive>||${project.basedir}||</prop-inactive>
</properties>
<build>
<plugins>
<plugin>
<artifactId>plugin-all-profiles</artifactId>
<executions>
<execution>
<id>Inactive all ||${project.basedir}||</id>
<configuration>
<plugin-all-profiles-ina>Inactive all ||${project.basedir}||</plugin-all-profiles-ina>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>only-inactive-profile</artifactId>
<executions>
<execution>
<id>Inactive only ||${project.basedir}||</id>
<configuration>
<plugin-in-inactive-only>Inactive only ||${project.basedir}||</plugin-in-inactive-only>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,123 @@
<?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.0.0</modelVersion>
<groupId>org.apache.maven.its.reporting.plugins</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<name>MNG-7750</name>
<description>
Test reporting plugin and reportSet interpolation.
</description>
<properties>
<prop-outside>||${project.basedir}||</prop-outside>
</properties>
<reporting>
<plugins>
<plugin>
<artifactId>plugin-all-profiles</artifactId>
<reportSets>
<reportSet>
<id>Outside ||${project.basedir}||</id>
<configuration>
<plugin-all-profiles-out>Outside ||${project.basedir}||</plugin-all-profiles-out>
</configuration>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>activeProfile</id>
<properties>
<prop-active>||${project.basedir}||</prop-active>
</properties>
<reporting>
<plugins>
<plugin>
<artifactId>plugin-all-profiles</artifactId>
<reportSets>
<reportSet>
<id>Active all ||${project.basedir}||</id>
<configuration>
<plugin-all-profiles-in>Active all ||${project.basedir}||</plugin-all-profiles-in>
</configuration>
</reportSet>
</reportSets>
</plugin>
<plugin>
<artifactId>only-active-profile</artifactId>
<reportSets>
<reportSet>
<id>Active only ||${project.basedir}||</id>
<configuration>
<plugin-in-active-profile-only>Active only ||${project.basedir}||</plugin-in-active-profile-only>
</configuration>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</profile>
<profile>
<id>inactiveProfile</id>
<properties>
<prop-inactive>||${project.basedir}||</prop-inactive>
</properties>
<reporting>
<plugins>
<plugin>
<artifactId>plugin-all-profiles</artifactId>
<reportSets>
<reportSet>
<id>Inactive all ||${project.basedir}||</id>
<configuration>
<plugin-all-profiles-ina>Inactive all ||${project.basedir}||</plugin-all-profiles-ina>
</configuration>
</reportSet>
</reportSets>
</plugin>
<plugin>
<artifactId>only-inactive-profile</artifactId>
<reportSets>
<reportSet>
<id>Inactive only ||${project.basedir}||</id>
<configuration>
<plugin-in-inactive-only>Inactive only ||${project.basedir}||</plugin-in-inactive-only>
</configuration>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</profile>
</profiles>
</project>

View File

@ -108,7 +108,7 @@ public class DefaultProfileInjector implements ProfileInjector {
pending = new ArrayList<>();
}
} else {
pending.add(element);
pending.add(element.clone());
}
}
@ -145,7 +145,7 @@ public class DefaultProfileInjector implements ProfileInjector {
if (existing != null) {
mergePluginExecution(existing, element, sourceDominant, context);
} else {
merged.put(key, element);
merged.put(key, element.clone());
}
}
@ -170,7 +170,7 @@ public class DefaultProfileInjector implements ProfileInjector {
Object key = getReportPluginKey(element);
ReportPlugin existing = merged.get(key);
if (existing == null) {
merged.put(key, element);
merged.put(key, element.clone());
} else {
mergeReportPlugin(existing, element, sourceDominant, context);
}
@ -199,7 +199,7 @@ public class DefaultProfileInjector implements ProfileInjector {
if (existing != null) {
mergeReportSet(existing, element, sourceDominant, context);
} else {
merged.put(key, element);
merged.put(key, element.clone());
}
}