Skip to content

Commit 306db11

Browse files
rzo1slachiewicz
authored andcommitted
Add regression test for filtering with overlapping <resource> entries
When a directory is covered by two <resource> entries — one with filtering=true and a narrow <include>, the other with filtering=false and <include>**</include> — the placeholder in the file selected by the first entry is no longer replaced. This was introduced between maven-filtering 3.3.1 and 3.3.2 and surfaced downstream as apache/maven-resources-plugin#471. The new test calls MavenResourcesFiltering directly (no plugin invoker), so the failure can be reproduced and bisected within this repository. It also asserts that files matched only by the unfiltered <resource> entry still keep their literal placeholders, so a fix cannot trivially "filter everything".
1 parent 6c668ca commit 306db11

3 files changed

Lines changed: 153 additions & 0 deletions

File tree

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.shared.filtering;
20+
21+
import javax.inject.Inject;
22+
23+
import java.io.File;
24+
import java.nio.charset.StandardCharsets;
25+
import java.nio.file.Files;
26+
import java.util.Arrays;
27+
import java.util.Collections;
28+
import java.util.List;
29+
import java.util.Properties;
30+
31+
import org.apache.commons.io.FileUtils;
32+
import org.apache.maven.model.Resource;
33+
import org.codehaus.plexus.testing.PlexusTest;
34+
import org.junit.jupiter.api.BeforeEach;
35+
import org.junit.jupiter.api.Test;
36+
37+
import static org.codehaus.plexus.testing.PlexusExtension.getBasedir;
38+
import static org.junit.jupiter.api.Assertions.assertFalse;
39+
import static org.junit.jupiter.api.Assertions.assertTrue;
40+
41+
/**
42+
* Reproduces the regression first reported against
43+
* <a href="https://github.com/apache/maven-resources-plugin/issues/471">
44+
* maven-resources-plugin issue #471</a>.
45+
*
46+
* <p>When a single source directory is covered by two {@link Resource} entries — one with
47+
* {@code filtering=true} and a narrow {@code <include>}, the other with {@code filtering=false}
48+
* and a broad {@code <include>**</include>} — the file selected by the first entry must still be
49+
* filtered. From {@code maven-filtering 3.3.2} onwards (pulled in by
50+
* {@code maven-resources-plugin 3.4.0}), the placeholder is left as the literal {@code ${...}}
51+
* text instead of being replaced.</p>
52+
*
53+
* <p>The {@code static/keep-as-is.txt} file, only matched by the second (unfiltered) entry, is
54+
* expected to keep its placeholder verbatim — the test asserts both halves so a future fix
55+
* cannot trivially "always filter everything".</p>
56+
*/
57+
@PlexusTest
58+
class OverlappingResourcesFilteringTest {
59+
60+
private final File outputDirectory = new File(getBasedir(), "target/OverlappingResourcesFilteringTest");
61+
private final File baseDir = new File(getBasedir());
62+
private final StubMavenProject mavenProject = new StubMavenProject(baseDir);
63+
64+
@Inject
65+
private MavenResourcesFiltering mavenResourcesFiltering;
66+
67+
@BeforeEach
68+
void setUp() throws Exception {
69+
if (outputDirectory.exists()) {
70+
FileUtils.deleteDirectory(outputDirectory);
71+
}
72+
outputDirectory.mkdirs();
73+
74+
mavenProject.setVersion("1.0");
75+
mavenProject.setGroupId("org.apache");
76+
mavenProject.setName("MRP-471 repro");
77+
}
78+
79+
@Test
80+
void overlappingResourceEntriesShouldStillFilter() throws Exception {
81+
Properties projectProperties = new Properties();
82+
projectProperties.put("repro.value", "REPLACED_BY_FILTERING");
83+
mavenProject.setProperties(projectProperties);
84+
85+
String unitFilesDir = getBasedir() + "/src/test/units-files/MRP-471";
86+
87+
// Mirrors the failing POM configuration:
88+
// <resource>
89+
// <filtering>true</filtering>
90+
// <directory>src/main/resources</directory>
91+
// <includes><include>config/filtered.xml</include></includes>
92+
// </resource>
93+
// <resource>
94+
// <filtering>false</filtering>
95+
// <directory>src/main/resources</directory>
96+
// <includes><include>**</include></includes>
97+
// </resource>
98+
Resource filtered = new Resource();
99+
filtered.setDirectory(unitFilesDir);
100+
filtered.setFiltering(true);
101+
filtered.addInclude("config/filtered.xml");
102+
103+
Resource unfiltered = new Resource();
104+
unfiltered.setDirectory(unitFilesDir);
105+
unfiltered.setFiltering(false);
106+
unfiltered.addInclude("**");
107+
108+
List<Resource> resources = Arrays.asList(filtered, unfiltered);
109+
110+
MavenResourcesExecution execution = new MavenResourcesExecution(
111+
resources,
112+
outputDirectory,
113+
mavenProject,
114+
"UTF-8",
115+
Collections.emptyList(),
116+
Collections.emptyList(),
117+
new StubMavenSession());
118+
execution.setUseDefaultFilterWrappers(true);
119+
120+
mavenResourcesFiltering.filterResources(execution);
121+
122+
File filteredOut = new File(outputDirectory, "config/filtered.xml");
123+
File unfilteredOut = new File(outputDirectory, "static/keep-as-is.txt");
124+
assertTrue(filteredOut.isFile(), "expected " + filteredOut + " to be copied");
125+
assertTrue(unfilteredOut.isFile(), "expected " + unfilteredOut + " to be copied");
126+
127+
String filteredContent = new String(Files.readAllBytes(filteredOut.toPath()), StandardCharsets.UTF_8);
128+
String unfilteredContent = new String(Files.readAllBytes(unfilteredOut.toPath()), StandardCharsets.UTF_8);
129+
130+
// The placeholder targeted by the filtered <resource> entry must be replaced.
131+
// Regression on maven-filtering >= 3.3.2: the literal ${repro.value} is left in place.
132+
assertTrue(
133+
filteredContent.contains("REPLACED_BY_FILTERING"),
134+
"config/filtered.xml should have ${repro.value} replaced; got:\n" + filteredContent);
135+
assertFalse(
136+
filteredContent.contains("${repro.value}"),
137+
"config/filtered.xml still contains the literal placeholder — see "
138+
+ "https://github.com/apache/maven-resources-plugin/issues/471\n"
139+
+ filteredContent);
140+
141+
// The second (unfiltered) entry must leave files matched only by it untouched —
142+
// this guards against a fix that just turns filtering on for everything.
143+
assertTrue(
144+
unfilteredContent.contains("${repro.value}"),
145+
"static/keep-as-is.txt is matched by filtering=false and must keep the literal "
146+
+ "placeholder; got:\n" + unfilteredContent);
147+
}
148+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<config>
3+
<property name="value">${repro.value}</property>
4+
</config>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Not filtered. Placeholder must stay verbatim: ${repro.value}

0 commit comments

Comments
 (0)