Skip to content

Commit 7d10442

Browse files
committed
Cleanup and verify parameters in BuildFileParser
1 parent 924e344 commit 7d10442

File tree

2 files changed

+168
-53
lines changed

2 files changed

+168
-53
lines changed

sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/BuildFileParser.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,31 @@ class BuildFileParser {
5353
private final ParserSettings parserSettings;
5454

5555
/**
56-
* See {@link org.openrewrite.maven.MavenMojoProjectParser#parseMaven(List, Map, ExecutionContext)}
56+
* Parse a list of Maven Pom files to a Map of {@code Path} and their parsed {@Xml.Document}s.
57+
* The {@link Xml.Document}s are marked with {@link org.openrewrite.maven.tree.MavenResolutionResult} and the provided provenance markers.
58+
* Reimplements {@link org.openrewrite.maven.MavenMojoProjectParser#parseMaven(List, Map, ExecutionContext)}.
59+
* The provided list of pom files must be sorted beforehand. See {@link MavenBuildFileGraph#build(Path, List)}.
60+
*
61+
* @param baseDir the {@link Path} to the root of the scanned project
62+
* @param buildFileResources the list of resources for relevant pom files.
63+
* @param executionContext the ExecutionContext to use
64+
* @param provenanceMarkers the map of markers to be added
65+
* @param
5766
*/
58-
public Map<Path, Xml.Document> parseBuildFiles(Path baseDir, List<Resource> buildFileResources, ExecutionContext executionContext, boolean skipMavenParsing, Map<Path, List<Marker>> provenanceMarkers) {
67+
public Map<Path, Xml.Document> parseBuildFiles(
68+
Path baseDir,
69+
List<Resource> buildFileResources,
70+
ExecutionContext executionContext,
71+
boolean skipMavenParsing,
72+
Map<Path, List<Marker>> provenanceMarkers
73+
) {
5974
Assert.notNull(baseDir, "Base directory must be provided but was null.");
6075
Assert.notEmpty(buildFileResources, "No build files provided.");
76+
List<Resource> nonPomFiles = retrieveNonPomFiles(buildFileResources);
77+
Assert.isTrue(nonPomFiles.isEmpty(), "Provided resources which are not Maven build files: '%s'".formatted(nonPomFiles.stream().map(r -> ResourceUtil.getPath(r).toAbsolutePath()).toList()));
78+
List<Resource> resourcesWithoutProvenanceMarker = findResourcesWithoutProvenanceMarker(baseDir, buildFileResources, provenanceMarkers);
79+
Assert.isTrue(resourcesWithoutProvenanceMarker.isEmpty(), "No provenance marker provided for these pom files %s".formatted(resourcesWithoutProvenanceMarker.stream().map(r -> ResourceUtil.getPath(r).toAbsolutePath()).toList()));
80+
6181
if(skipMavenParsing) {
6282
return Map.of();
6383
}
@@ -113,6 +133,16 @@ public Map<Path, Xml.Document> parseBuildFiles(Path baseDir, List<Resource> bui
113133
return result;
114134
}
115135

136+
private List<Resource> findResourcesWithoutProvenanceMarker(Path baseDir, List<Resource> buildFileResources, Map<Path, List<Marker>> provenanceMarkers) {
137+
return buildFileResources.stream()
138+
.filter(r -> !provenanceMarkers.containsKey(baseDir.resolve(ResourceUtil.getPath(r)).normalize()))
139+
.toList();
140+
}
141+
142+
private static List<Resource> retrieveNonPomFiles(List<Resource> buildFileResources) {
143+
return buildFileResources.stream().filter(r -> !"pom.xml".equals(ResourceUtil.getPath(r).getFileName().toString())).toList();
144+
}
145+
116146
private SourceFile markPomFile(SourceFile pp, List<Marker> markers) {
117147
for (Marker marker : markers) {
118148
pp = pp.withMarkers(pp.getMarkers().addIfAbsent(marker));
@@ -191,11 +221,11 @@ public List<Resource> filterAndSortBuildFiles(List<Resource> resources) {
191221
.sorted((r1, r2) -> {
192222

193223
Path r1Path = ResourceUtil.getPath(r1);
194-
ArrayList<String> r1PathParts = new ArrayList<String>();
224+
ArrayList<String> r1PathParts = new ArrayList<>();
195225
r1Path.iterator().forEachRemaining(it -> r1PathParts.add(it.toString()));
196226

197227
Path r2Path = ResourceUtil.getPath(r2);
198-
ArrayList<String> r2PathParts = new ArrayList<String>();
228+
ArrayList<String> r2PathParts = new ArrayList<>();
199229
r2Path.iterator().forEachRemaining(it -> r2PathParts.add(it.toString()));
200230
return Integer.compare(r1PathParts.size(), r2PathParts.size());
201231
})

sbm-support-rewrite/src/test/java/org/springframework/sbm/parsers/BuildFileParserTest.java

Lines changed: 134 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
package org.springframework.sbm.parsers;
1717

1818
import org.intellij.lang.annotations.Language;
19+
import org.junit.jupiter.api.DisplayName;
1920
import org.junit.jupiter.api.Nested;
2021
import org.junit.jupiter.api.Test;
2122
import org.openrewrite.ExecutionContext;
2223
import org.openrewrite.InMemoryExecutionContext;
24+
import org.openrewrite.java.marker.JavaProject;
2325
import org.openrewrite.marker.Marker;
26+
import org.openrewrite.maven.MavenExecutionContextView;
27+
import org.openrewrite.maven.tree.*;
2428
import org.openrewrite.xml.tree.Xml;
2529
import org.springframework.core.io.Resource;
2630
import org.springframework.sbm.test.util.DummyResource;
@@ -30,8 +34,10 @@
3034
import java.util.HashMap;
3135
import java.util.List;
3236
import java.util.Map;
37+
import java.util.UUID;
3338

3439
import static org.assertj.core.api.Assertions.assertThat;
40+
import static org.junit.jupiter.api.Assertions.assertThrows;
3541

3642
/**
3743
* @author Fabian Krüger
@@ -44,63 +50,63 @@ public class GivenSimpleMavenMultiModuleProject {
4450
@Language("xml")
4551
private static final String POM_1 =
4652
"""
47-
<?xml version="1.0" encoding="UTF-8"?>
48-
<project xmlns="http://maven.apache.org/POM/4.0.0"
49-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
50-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
51-
<modelVersion>4.0.0</modelVersion>
52-
53-
<groupId>com.example</groupId>
54-
<artifactId>parent-module</artifactId>
55-
<version>1.0</version>
56-
<modules>
57-
<module>module1</module>
58-
</modules>
59-
</project>
60-
""";
53+
<?xml version="1.0" encoding="UTF-8"?>
54+
<project xmlns="http://maven.apache.org/POM/4.0.0"
55+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
56+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
57+
<modelVersion>4.0.0</modelVersion>
58+
59+
<groupId>com.example</groupId>
60+
<artifactId>parent</artifactId>
61+
<version>1.0</version>
62+
<modules>
63+
<module>module1</module>
64+
</modules>
65+
</project>
66+
""";
6167

6268
@Language("xml")
6369
private static final String POM_2 =
6470
"""
65-
<?xml version="1.0" encoding="UTF-8"?>
66-
<project xmlns="http://maven.apache.org/POM/4.0.0"
67-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
68-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
69-
<modelVersion>4.0.0</modelVersion>
70-
<parent>
71-
<groupId>com.example</groupId>
72-
<artifactId>parent</artifactId>
73-
<version>1.0</version>
74-
</parent>
75-
<artifactId>module1</artifactId>
76-
<modules>
77-
<module>submodule</module>
78-
</modules>
79-
</project>
80-
""";
71+
<?xml version="1.0" encoding="UTF-8"?>
72+
<project xmlns="http://maven.apache.org/POM/4.0.0"
73+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
74+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
75+
<modelVersion>4.0.0</modelVersion>
76+
<parent>
77+
<groupId>com.example</groupId>
78+
<artifactId>parent</artifactId>
79+
<version>1.0</version>
80+
</parent>
81+
<artifactId>module1</artifactId>
82+
<modules>
83+
<module>submodule</module>
84+
</modules>
85+
</project>
86+
""";
8187

8288
@Language("xml")
8389
private static final String POM_3 =
8490
"""
85-
<project xmlns="http://maven.apache.org/POM/4.0.0"
86-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
87-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
88-
<modelVersion>4.0.0</modelVersion>
89-
<parent>
90-
<groupId>com.example</groupId>
91-
<artifactId>module1</artifactId>
92-
<version>1.0</version>
93-
</parent>
94-
<artifactId>submodule</artifactId>
95-
</project>
96-
""";
97-
98-
private BuildFileParser sut = new BuildFileParser(new ParserSettings());
91+
<project xmlns="http://maven.apache.org/POM/4.0.0"
92+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
93+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
94+
<modelVersion>4.0.0</modelVersion>
95+
<parent>
96+
<groupId>com.example</groupId>
97+
<artifactId>module1</artifactId>
98+
<version>1.0</version>
99+
</parent>
100+
<artifactId>submodule</artifactId>
101+
</project>
102+
""";
103+
104+
private final BuildFileParser sut = new BuildFileParser(new ParserSettings());
99105

100106
@Test
101107
void filterAndSortBuildFiles_shouldReturnSortedListOfFilteredBuildFiles() {
102108

103-
// the poms have no order
109+
// the provided resources have no order and contain non-pom files
104110
List<Resource> resources = List.of(
105111
new DummyResource("src/test/resources/dummy/pom.xml", ""), // filtered
106112
new DummyResource("module1/submodule/pom.xml", POM_3), // pos. 3
@@ -128,12 +134,25 @@ void filterAndSortBuildFiles_shouldReturnSortedListOfFilteredBuildFiles() {
128134
@Test
129135
void parseBuildFiles_shouldReturnSortedListOfParsedBuildFiles() {
130136
Path baseDir = Path.of(".").toAbsolutePath().normalize();
137+
String module1SubmoduleSourcePath = "module1/submodule/pom.xml";
138+
String parentSourcePath = "pom.xml";
139+
String module1SourcePath = "module1/pom.xml";
131140
List<Resource> filteredAndSortedBuildFiles = List.of(
132-
new DummyResource(baseDir, "module1/submodule/pom.xml", POM_3),
133-
new DummyResource(baseDir, "pom.xml", POM_1),
134-
new DummyResource(baseDir, "module1/pom.xml", POM_2)
141+
new DummyResource(baseDir, module1SubmoduleSourcePath, POM_3),
142+
new DummyResource(baseDir, parentSourcePath, POM_1),
143+
new DummyResource(baseDir, module1SourcePath, POM_2)
135144
);
136-
Map<Path, List<Marker>> provenanceMarkers = new HashMap<>();
145+
146+
// provenance markers
147+
Path module1SubmodulePomPath = baseDir.resolve(module1SubmoduleSourcePath);
148+
Path parentPomPath = baseDir.resolve(parentSourcePath);
149+
Path module1PomXml = baseDir.resolve(module1SourcePath);
150+
Map<Path, List<Marker>> provenanceMarkers = Map.of(
151+
module1SubmodulePomPath, List.of(new JavaProject(UUID.randomUUID(), module1SubmoduleSourcePath, null)),
152+
parentPomPath, List.of(new JavaProject(UUID.randomUUID(), parentSourcePath, null)),
153+
module1PomXml, List.of(new JavaProject(UUID.randomUUID(), module1SourcePath, null))
154+
);
155+
137156
ExecutionContext executionContext = new InMemoryExecutionContext(t -> t.printStackTrace());
138157
boolean skipMavenParsing = false;
139158
Map<Path, Xml.Document> parsedBuildFiles = sut.parseBuildFiles(
@@ -142,7 +161,73 @@ void parseBuildFiles_shouldReturnSortedListOfParsedBuildFiles() {
142161
executionContext,
143162
skipMavenParsing,
144163
provenanceMarkers);
164+
165+
assertThat(parsedBuildFiles).hasSize(3);
166+
assertThat(parsedBuildFiles.get(module1SubmodulePomPath).getMarkers().findFirst(JavaProject.class).get().getProjectName()).isEqualTo(module1SubmoduleSourcePath);
167+
assertThat(parsedBuildFiles.get(parentPomPath).getMarkers().findFirst(JavaProject.class).get().getProjectName()).isEqualTo(parentSourcePath);
168+
assertThat(parsedBuildFiles.get(module1PomXml).getMarkers().findFirst(JavaProject.class).get().getProjectName()).isEqualTo(module1SourcePath);
169+
}
170+
171+
@Test
172+
@DisplayName("parse without baseDir should throw exception")
173+
void parseWithoutBaseDirShouldThrowException() {
174+
String message = assertThrows(
175+
IllegalArgumentException.class,
176+
() -> sut.parseBuildFiles(null, List.of(), new InMemoryExecutionContext(), false, Map.of())
177+
)
178+
.getMessage();
179+
assertThat(message).isEqualTo("Base directory must be provided but was null.");
180+
}
181+
182+
@Test
183+
@DisplayName("parse with empty resources should throw exception")
184+
void parseWithEmptyResourcesShouldThrowException() {
185+
String message = assertThrows(
186+
IllegalArgumentException.class,
187+
() -> sut.parseBuildFiles(Path.of("."), List.of(), new InMemoryExecutionContext(), false, Map.of())
188+
)
189+
.getMessage();
190+
assertThat(message).isEqualTo("No build files provided.");
145191
}
192+
193+
@Test
194+
@DisplayName("parse with non-pom resources provided should throw exception")
195+
void parseWithNonPomResourcesProvidedShouldThrowException() {
196+
Path baseDir = Path.of(".").toAbsolutePath().normalize();
197+
Resource nonPomResource = new DummyResource(baseDir, "src/main/java/SomeClass.java", "public class SomeClass {}");
198+
List<Resource> nonPomResource1 = List.of(nonPomResource);
199+
String message = assertThrows(
200+
IllegalArgumentException.class,
201+
() -> sut.parseBuildFiles(baseDir, nonPomResource1, new InMemoryExecutionContext(), false, Map.of())
202+
)
203+
.getMessage();
204+
assertThat(message).isEqualTo("Provided resources which are not Maven build files: '["+ baseDir +"/src/main/java/SomeClass.java]'");
205+
}
206+
207+
@Test
208+
@DisplayName("parse with incomplete provenance markers should throw exception")
209+
void parseWithIncompleteProvenanceMarkersShouldThrowException() {
210+
Path baseDir = Path.of(".").toAbsolutePath().normalize();
211+
212+
Path pom1Path = baseDir.resolve("pom.xml");
213+
Resource pom1 = new DummyResource(pom1Path, "");
214+
Path pom2Path = baseDir.resolve("module1/pom.xml");
215+
Resource pom2 = new DummyResource(pom2Path, "");
216+
List<Resource> poms = List.of(pom1, pom2);
217+
218+
Map<Path, List<Marker>> provenanceMarkers = Map.of(
219+
pom1Path, List.of(new JavaProject(UUID.randomUUID(), "pom.xml", null))
220+
// no marker for module1/pom.xml
221+
);
222+
223+
String message = assertThrows(
224+
IllegalArgumentException.class,
225+
() -> sut.parseBuildFiles(baseDir, poms, new InMemoryExecutionContext(), false, provenanceMarkers)
226+
)
227+
.getMessage();
228+
assertThat(message).isEqualTo("No provenance marker provided for these pom files ["+Path.of(".").toAbsolutePath().normalize().resolve("module1/pom.xml]"));
229+
}
230+
146231
}
147232

148233
}

0 commit comments

Comments
 (0)