You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2023/04/12 10:26:54 UTC

[maven] branch maven-3.9.x updated: [MNG-7750] Fix unwanted interpolation in plugins from profiles. (#1075)

This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch maven-3.9.x
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/maven-3.9.x by this push:
     new 0f1847057 [MNG-7750] Fix unwanted interpolation in plugins from profiles. (#1075)
0f1847057 is described below

commit 0f18470576d1eb0649aa93c739b8dd39c9368716
Author: Niels Basjes <gi...@basjes.nl>
AuthorDate: Wed Apr 12 12:26:47 2023 +0200

    [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
---
 .../apache/maven/project/PomConstructionTest.java  | 196 +++++++++++++++++++++
 .../plugin-interpolation-build/pom.xml             | 123 +++++++++++++
 .../plugin-interpolation-reporting/pom.xml         | 123 +++++++++++++
 .../model/profile/DefaultProfileInjector.java      |   8 +-
 4 files changed, 446 insertions(+), 4 deletions(-)

diff --git a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java
index e3c9f59f4..28d747c10 100644
--- a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java
+++ b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java
@@ -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
diff --git a/maven-core/src/test/resources-project-builder/plugin-interpolation-build/pom.xml b/maven-core/src/test/resources-project-builder/plugin-interpolation-build/pom.xml
new file mode 100644
index 000000000..56718154a
--- /dev/null
+++ b/maven-core/src/test/resources-project-builder/plugin-interpolation-build/pom.xml
@@ -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>
diff --git a/maven-core/src/test/resources-project-builder/plugin-interpolation-reporting/pom.xml b/maven-core/src/test/resources-project-builder/plugin-interpolation-reporting/pom.xml
new file mode 100644
index 000000000..aeb6f7de2
--- /dev/null
+++ b/maven-core/src/test/resources-project-builder/plugin-interpolation-reporting/pom.xml
@@ -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>
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java b/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java
index f34d69e36..3949ed8b4 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java
@@ -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());
                     }
                 }