Skip to content

Commit ee739b5

Browse files
authored
fix: fix Maven source and test source directory resolving (#3562)
1 parent c99a186 commit ee739b5

File tree

5 files changed

+139
-8
lines changed

5 files changed

+139
-8
lines changed

src/main/java/spoon/support/compiler/SpoonPom.java

+77-8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.io.FileReader;
3636
import java.io.IOException;
3737
import java.io.InputStreamReader;
38+
import java.nio.file.Path;
3839
import java.nio.file.Paths;
3940
import java.util.ArrayList;
4041
import java.util.Collections;
@@ -165,9 +166,20 @@ public List<File> getSourceDirectories() {
165166
sourcePath = build.getSourceDirectory();
166167
}
167168
if (sourcePath == null) {
168-
sourcePath = Paths.get("src/main/java").toString();
169+
sourcePath = getSourceDirectoryFromParent(getParentPom());
170+
if (sourcePath == null) {
171+
sourcePath = Paths.get("src/main/java").toString();
172+
}
173+
}
174+
sourcePath = extractVariable(sourcePath);
175+
Path path = Paths.get(sourcePath);
176+
177+
String absoluteSourcePath;
178+
if (path.isAbsolute()) {
179+
absoluteSourcePath = path.toString();
180+
} else {
181+
absoluteSourcePath = Paths.get(directory.getAbsolutePath(), sourcePath).toString();
169182
}
170-
String absoluteSourcePath = Paths.get(directory.getAbsolutePath(), sourcePath).toString();
171183
File source = new File(absoluteSourcePath);
172184
if (source.exists()) {
173185
output.add(source);
@@ -182,6 +194,28 @@ public List<File> getSourceDirectories() {
182194
return output;
183195
}
184196

197+
/**
198+
* Climbs the pom.xml hierarchy until a model is found in which
199+
* a source directory is declared.
200+
* @return the uninterpolated source directory declared in the nearest ancestor
201+
*/
202+
private String getSourceDirectoryFromParent(SpoonPom parent) {
203+
if (parent == null) {
204+
return null;
205+
}
206+
String sourcePath = null;
207+
Build build = parent.model.getBuild();
208+
if (build != null) {
209+
sourcePath = build.getSourceDirectory();
210+
if (sourcePath == null && parent.getParentPom() != null) {
211+
return getSourceDirectoryFromParent(parent.getParentPom());
212+
}
213+
} else if (parent.getParentPom() != null) {
214+
return getSourceDirectoryFromParent(parent.getParentPom());
215+
}
216+
return sourcePath;
217+
}
218+
185219
/**
186220
* Get the list of test directories of the project
187221
* @return the list of test directories
@@ -195,9 +229,20 @@ public List<File> getTestDirectories() {
195229
sourcePath = build.getTestSourceDirectory();
196230
}
197231
if (sourcePath == null) {
198-
sourcePath = Paths.get("src/test/java").toString();
232+
sourcePath = getTestSourceDirectoryFromParent(getParentPom());
233+
if (sourcePath == null) {
234+
sourcePath = Paths.get("src/test/java").toString();
235+
}
236+
}
237+
sourcePath = extractVariable(sourcePath);
238+
Path path = Paths.get(sourcePath);
239+
240+
String absoluteSourcePath;
241+
if (path.isAbsolute()) {
242+
absoluteSourcePath = path.toString();
243+
} else {
244+
absoluteSourcePath = Paths.get(directory.getAbsolutePath(), sourcePath).toString();
199245
}
200-
String absoluteSourcePath = Paths.get(directory.getAbsolutePath(), sourcePath).toString();
201246
File source = new File(absoluteSourcePath);
202247
if (source.exists()) {
203248
output.add(source);
@@ -212,6 +257,28 @@ public List<File> getTestDirectories() {
212257
return output;
213258
}
214259

260+
/**
261+
* Climbs the pom.xml hierarchy until a model is found in which
262+
* a test source directory is declared.
263+
* @return the uninterpolated test source directory declared in the nearest ancestor
264+
*/
265+
private String getTestSourceDirectoryFromParent(SpoonPom parent) {
266+
if (parent == null) {
267+
return null;
268+
}
269+
String sourcePath = null;
270+
Build build = parent.model.getBuild();
271+
if (build != null) {
272+
sourcePath = build.getTestSourceDirectory();
273+
if (sourcePath == null && parent.getParentPom() != null) {
274+
return getTestSourceDirectoryFromParent(parent.getParentPom());
275+
}
276+
} else if (parent.getParentPom() != null) {
277+
return getTestSourceDirectoryFromParent(parent.getParentPom());
278+
}
279+
return sourcePath;
280+
}
281+
215282
/**
216283
* Get the list of classpath files generated by maven
217284
* @return the list of classpath files
@@ -247,29 +314,31 @@ private String extractVariable(String value) {
247314
}
248315

249316
/**
250-
* Get the value of a property
317+
* Get the value of a property. Reference: https://maven.apache.org/ref/3.6.3/maven-model-builder/#Model_Interpolation
251318
* @param key the key of the property
252319
* @return the property value if key exists or null
253320
*/
254321
private String getProperty(String key) {
255-
if ("project.version".equals(key) || "pom.version".equals(key)) {
322+
if ("project.version".equals(key) || "pom.version".equals(key) || "version".equals(key)) {
256323
if (model.getVersion() != null) {
257324
return model.getVersion();
258325
} else if (model.getParent() != null) {
259326
return model.getParent().getVersion();
260327
}
261-
} else if ("project.groupId".equals(key) || "pom.groupId".equals(key)) {
328+
} else if ("project.groupId".equals(key) || "pom.groupId".equals(key) || "groupId".equals(key)) {
262329
if (model.getGroupId() != null) {
263330
return model.getGroupId();
264331
} else if (model.getParent() != null) {
265332
return model.getParent().getGroupId();
266333
}
267-
} else if ("project.artifactId".equals(key) || "pom.artifactId".equals(key)) {
334+
} else if ("project.artifactId".equals(key) || "pom.artifactId".equals(key) || "artifactId".equals(key)) {
268335
if (model.getArtifactId() != null) {
269336
return model.getArtifactId();
270337
} else if (model.getParent() != null) {
271338
return model.getParent().getArtifactId();
272339
}
340+
} else if ("project.basedir".equals(key) || "pom.basedir".equals(key) || "basedir".equals(key)) {
341+
return pomFile.getParent();
273342
}
274343
String value = extractVariable(model.getProperties().getProperty(key));
275344
if (value == null) {

src/test/java/spoon/support/compiler/SpoonPomTest.java

+17
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.io.IOException;
99
import java.util.List;
1010
import java.util.regex.Pattern;
11+
import java.nio.file.Paths;
1112

1213
import static org.junit.Assert.*;
1314

@@ -51,4 +52,20 @@ public void checkProfilesModules(String path, String[] expected, Pattern profile
5152
assertEquals(expected[i], modules.get(i).getName());
5253
}
5354
}
55+
56+
public void getSourceDirectory() throws IOException, XmlPullParserException {
57+
checkSourceDirectory(
58+
"src/test/resources/maven-launcher/hierarchy",
59+
Paths.get("src/test/resources/maven-launcher/hierarchy/child/src").toAbsolutePath().toString()
60+
);
61+
}
62+
63+
public void checkSourceDirectory(String path, String expected) throws IOException, XmlPullParserException {
64+
SpoonPom pomModel = new SpoonPom(path, null, MavenLauncher.SOURCE_TYPE.APP_SOURCE, new StandardEnvironment());
65+
66+
SpoonPom childModel = pomModel.getModules().get(0);
67+
//contract: source directory is derived from parent pom.xml if not declared in the current
68+
// (childModel) SpoonPom
69+
assertEquals(expected, childModel.getSourceDirectories().get(0).getAbsolutePath());
70+
}
5471
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>sample.text</groupId>
7+
<artifactId>parent</artifactId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
<relativePath>..</relativePath>
10+
</parent>
11+
<groupId>sample.text</groupId>
12+
<artifactId>child</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
15+
<packaging>jar</packaging>
16+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package maven-launcher.hierarchy.child.src;
2+
3+
public class Test {
4+
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>sample.text</groupId>
7+
<artifactId>project</artifactId>
8+
<version>2.2.2.RELEASE</version>
9+
<relativePath/>
10+
</parent>
11+
<groupId>sample.text</groupId>
12+
<artifactId>parent</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
15+
<packaging>pom</packaging>
16+
17+
<modules>
18+
<module>child</module>
19+
</modules>
20+
21+
<build>
22+
<sourceDirectory>${project.basedir}/src</sourceDirectory>
23+
</build>
24+
</project>

0 commit comments

Comments
 (0)