From 9488bcdda5cac4d9acf38d3a2c7c6a6425cf55f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Tue, 4 Jul 2023 14:05:13 +0200 Subject: [PATCH 1/3] Use java.specification.version when no source and target version is available --- .../maven/MavenMojoProjectParser.java | 2 +- .../maven/MavenMojoProjectParserTest.java | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java diff --git a/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java b/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java index 42f50cd6..4ad7cd3d 100644 --- a/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java +++ b/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java @@ -193,7 +193,7 @@ private SourceFile logParseErrors(SourceFile source) { public List generateProvenance(MavenProject mavenProject) { - String javaRuntimeVersion = System.getProperty("java.runtime.version"); + String javaRuntimeVersion = System.getProperty("java.specification.version"); String javaVendor = System.getProperty("java.vm.vendor"); String sourceCompatibility = null; diff --git a/src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java b/src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java new file mode 100644 index 00000000..394e6f2e --- /dev/null +++ b/src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java @@ -0,0 +1,34 @@ +package org.openrewrite.maven; + +import it.unimi.dsi.fastutil.ints.IntSets; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.logging.SystemStreamLog; +import org.apache.maven.project.MavenProject; +import org.apache.maven.rtinfo.internal.DefaultRuntimeInformation; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openrewrite.java.marker.JavaVersion; +import org.openrewrite.marker.Marker; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Fabian Krüger + */ +class MavenMojoProjectParserTest { + @Test + @DisplayName("Given No Java version information exists in Maven Then java.specification.version should be used") + void givenNoJavaVersionInformationExistsInMavenThenJavaSpecificationVersionShouldBeUsed() { + MavenMojoProjectParser sut = new MavenMojoProjectParser(new SystemStreamLog(), null, false, null, new DefaultRuntimeInformation(), false, Collections.EMPTY_LIST, Collections.EMPTY_LIST, -1, null, null, false); + List markers = sut.generateProvenance(new MavenProject()); + JavaVersion marker = markers.stream().filter(JavaVersion.class::isInstance).map(JavaVersion.class::cast).findFirst().get(); + assertThat(marker.getSourceCompatibility()).isEqualTo(System.getProperty("java.specification.version")); + assertThat(marker.getTargetCompatibility()).isEqualTo(System.getProperty("java.specification.version")); + } +} \ No newline at end of file From e4ac0ae1a26dac61ad982425ff7c8952033842d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Tue, 18 Jul 2023 13:22:26 +0200 Subject: [PATCH 2/3] WIP: Unsure how to test the private method isolated --- .../maven/MavenMojoProjectParserTest.java | 126 +++++++++++++++++- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java b/src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java index 394e6f2e..ea8e6f63 100644 --- a/src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java +++ b/src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java @@ -5,17 +5,28 @@ import org.apache.maven.plugin.logging.SystemStreamLog; import org.apache.maven.project.MavenProject; import org.apache.maven.rtinfo.internal.DefaultRuntimeInformation; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.openrewrite.ExecutionContext; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.Parser; +import org.openrewrite.SourceFile; import org.openrewrite.java.marker.JavaVersion; import org.openrewrite.marker.Marker; +import org.openrewrite.tree.ParsingEventListener; +import org.openrewrite.tree.ParsingExecutionContextView; +import org.openrewrite.xml.tree.Xml; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.io.IOException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchIllegalArgumentException; import static org.junit.jupiter.api.Assertions.*; /** @@ -31,4 +42,111 @@ void givenNoJavaVersionInformationExistsInMavenThenJavaSpecificationVersionShoul assertThat(marker.getSourceCompatibility()).isEqualTo(System.getProperty("java.specification.version")); assertThat(marker.getTargetCompatibility()).isEqualTo(System.getProperty("java.specification.version")); } + + @Test + @DisplayName("order of build files should reflect reactor build order") + void orderOfBuildFilesShouldReflectReactorBuildOrder(@TempDir Path tempDir) throws NoSuchMethodException, IOException { + MavenMojoProjectParser sut = new MavenMojoProjectParser(new SystemStreamLog(), null, false, null, new DefaultRuntimeInformation(), false, Collections.EMPTY_LIST, Collections.EMPTY_LIST, -1, null, null, false); + /*Method collectPoms = MavenMojoProjectParser.class.getDeclaredMethod("collectPoms", MavenProject.class, Set.class); + collectPoms.setAccessible(true); + Set allPoms = new LinkedHashSet<>(); + Object mavenProjects; + collectPoms.invoke(sut, mavenProjects, allPoms);*/ + String pomXml = "\n" + + "\n" + + " 4.0.0\n" + + " com.example\n" + + " multi-module-1\n" + + " 1.0.0\n" + + " pom\n" + + " \n" + + " 17\n" + + " 17\n" + + " UTF-8\n" + + " \n" + + " \n" + + " \n" + + " org.springframework.boot\n" + + " spring-boot-starter\n" + + " 3.1.1\n" + + " \n" + + " \n" + + " \n" + + " module-a\n" + + " module-b\n" + + " \n" + + ""; + + String moduleAPom = "\n" + + "\n" + + " 4.0.0\n" + + " \n" + + " com.example\n" + + " multi-module-1\n" + + " 1.0.0\n" + + " \n" + + " module-a\n" + + " \n" + + " \n" + + " com.example\n" + + " module-b\n" + + " ${project.version}\n" + + " \n" + + " \n" + + ""; + + String moduleBPom = "\n" + + "\n" + + " 4.0.0\n" + + " \n" + + " com.example\n" + + " multi-module-1\n" + + " 1.0.0\n" + + " \n" + + " module-b\n" + + ""; + + + Path rootPomFile = tempDir.resolve("pom.xml"); + Files.write(rootPomFile, pomXml.getBytes()); + + Path aPath = tempDir.resolve("module-a"); + aPath.toFile().mkdirs(); + Path aFile = aPath.resolve("pom.xml"); + Files.write(aFile, moduleAPom.getBytes()); + + Path bPath = tempDir.resolve("module-b"); + Path bFile = bPath.resolve("pom.xml"); + bPath.toFile().mkdirs(); + Files.write(bFile, moduleBPom.getBytes()); + + MavenProject rootProject = new MavenProject();// mock(MavenProject.class); + MavenProject aProject = new MavenProject(); + MavenProject bProject = new MavenProject(); + + List mavenProjects = new ArrayList<>(); + mavenProjects.add(bProject); + mavenProjects.add(rootProject); + mavenProjects.add(aProject); + Map> markers = new LinkedHashMap<>(); + ExecutionContext ctx = new InMemoryExecutionContext(Assertions::fail); + List capturedResourcePaths = new ArrayList<>(); + new ParsingExecutionContextView(ctx).setParsingListener((input, sourceFile) -> { + capturedResourcePaths.add(sourceFile.getSourcePath().toString()); + }); +// Map mavenProjectDocumentMap = sut.parseMaven(mavenProjects, markers, ctx); + MavenProject mavenProject = new MavenProject(); + mavenProject.setFile(rootPomFile.toFile()); + sut.parseMaven(mavenProject, new ArrayList<>(), ctx); + + assertThat(capturedResourcePaths.get(0)).isEqualTo("pom.xml"); + assertThat(capturedResourcePaths.get(1)).isEqualTo("module-b/pom.xml"); + assertThat(capturedResourcePaths.get(2)).isEqualTo("module-a/pom.xml"); + } } \ No newline at end of file From 83d184ea9ffe3046429f16c91aa56a9610bae832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Tue, 18 Jul 2023 14:15:19 +0200 Subject: [PATCH 3/3] Dummy code as proposal --- .../maven/MavenMojoProjectParser.java | 83 ++++++++++++------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java b/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java index 6c2eb59f..f314aa30 100644 --- a/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java +++ b/src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java @@ -385,11 +385,9 @@ public Map parseMaven(List mavenProjec MavenProject topLevelProject = mavenSession.getTopLevelProject(); logInfo(topLevelProject, "Resolving Poms..."); - Set allPoms = new LinkedHashSet<>(); - mavenProjects.forEach(p -> collectPoms(p, allPoms)); - for (MavenProject mavenProject : mavenProjects) { - mavenSession.getProjectDependencyGraph().getUpstreamProjects(mavenProject, true).forEach(p -> collectPoms(p, allPoms)); - } + List allPoms = collectLocalAndUpstreamPoms(mavenSession); + + MavenParser.Builder mavenParserBuilder = MavenParser.builder().mavenConfig(baseDir.resolve(".mvn/maven.config")); MavenSettings settings = buildSettings(); @@ -459,35 +457,64 @@ public Map parseMaven(List mavenProjec return projectMap; } - /** - * Recursively navigate the maven project to collect any poms that are local (on disk) - * - * @param project A maven project to examine for any children/parent poms. - * @param paths A list of paths to poms that have been collected so far. - */ - private void collectPoms(MavenProject project, Set paths) { - paths.add(pomPath(project)); - - // children - if (project.getCollectedProjects() != null) { - for (MavenProject child : project.getCollectedProjects()) { - Path path = pomPath(child); - if (!paths.contains(path)) { - collectPoms(child, paths); - } - } + private List collectLocalAndUpstreamPoms(MavenSession mavenSession) { + List allPoms = new ArrayList<>(); + // mavenSession.getProjects() or mavenSession.getAllProjects() ? + List mavenProjects = mavenSession.getProjects(); + mavenProjects.forEach(p -> collectProjectPoms(mavenSession, allPoms)); + collectUpstreamPoms(mavenProjects, allPoms); + return allPoms; + } + + private void collectUpstreamPoms(List mavenProjects, List allPoms) { + for (MavenProject mavenProject : mavenProjects) { + mavenSession.getProjectDependencyGraph().getUpstreamProjects(mavenProject, true).forEach(p -> collectUpstreamPoms(mavenProject, allPoms)); } + } - MavenProject parent = project.getParent(); - while (parent != null && parent.getFile() != null) { - Path path = pomPath(parent); - if (!paths.contains(path)) { - collectPoms(parent, paths); + private void collectUpstreamPoms(MavenProject mavenProject, List allPoms) { + if(mavenProject.getCollectedProjects() != null) { + for(MavenProject project : mavenProject.getCollectedProjects()) { + Path path = pomPath(project); + if (!allPoms.contains(path)) { + collectUpstreamPoms(project, allPoms); + } } - parent = parent.getParent(); } } + /** + * Collect Paths of all projects that belong to the current Maven reactor build. + * + * @param session The current Maven session + * @param paths A list of paths to poms that have been collected so far. + */ + private void collectProjectPoms(MavenSession session, List paths) { + List collect = session.getProjects().stream().map(p -> p.getFile().toPath()).collect(toList()); + paths.addAll(collect); +// +// paths.add(pomPath(session.)); +// +// // children +// if (session.getProjects() != null) { +// for (MavenProject child : /*project.getCollectedProjects()*/ session.getProjects()) { +// Path path = pomPath(child); +// if (!paths.contains(path)) { +// collectPoms(session, paths); +// } +// } +// } +// +// MavenProject parent = session.getCurrentProject().getParent(); +// while (parent != null && parent.getFile() != null) { +// Path path = pomPath(parent); +// if (!paths.contains(path)) { +// collectPoms(parent, paths); +// } +// parent = parent.getParent(); +// } + } + private static Path pomPath(MavenProject mavenProject) { Path pomPath = mavenProject.getFile().toPath(); // org.codehaus.mojo:flatten-maven-plugin produces a synthetic pom unsuitable for our purposes, use the regular pom instead