Fix Windows build

* Fix paths for all OS

* Tweak build file

* Provide correct class to logger

* Download dependencies before comparing parse reults

When local Maven repo is empty the Markers added by the RewriteMavenProjectParser (comparing) and the RewriteProjectParser (under test) differ.
This is because one downloads the dependencies and the next takes them form local Maven and the URIs for dependencies then differ.
By builing the projects with Maven first the dependencies will be available in local Maven repo and taken from there by both parsers.

* Add logging

* fix formatting

* Ignore test when using Windows
This commit is contained in:
Fabian Krüger
2023-12-21 09:13:31 +00:00
committed by GitHub
parent d0b8c7fe68
commit 8fc77a20bc
24 changed files with 603 additions and 402 deletions

View File

@@ -3,8 +3,6 @@ name: CI
on:
workflow_dispatch:
push:
branches:
- main
paths-ignore:
- '.github/**'
@@ -27,14 +25,28 @@ jobs:
java: 17
name: CI Build ${{ matrix.nickname }}
steps:
- name: Set git config for long paths
if: runner.os == 'Windows'
run: |
git config --system core.longpaths true
- uses: actions/checkout@v4
- uses: jvalkeal/setup-maven@v1
with:
maven-version: 3.6.3
- uses: actions/setup-java@v4
with:
distribution: liberica
java-version: ${{ matrix.java }}
- name: Build
- name: Setup docker (missing on MacOS)
if: runner.os == 'macos'
run: |
brew install docker
colima start
# For testcontainers to find the Colima socket
# https://github.com/abiosoft/colima/blob/main/docs/FAQ.md#cannot-connect-to-the-docker-daemon-at-unixvarrundockersock-is-the-docker-daemon-running
sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
- name: Verify formatting
run: mvn -B -Pfunctional-tests spring-javaformat:validate
- name: Build (Windows, no functional tests)
if: runner.os == 'Windows'
run: ./mvnw -B clean verify
- name: Build (Non Windows)
if: runner.os != 'Windows'
run: ./mvnw -B -Pfunctional-tests clean verify

View File

@@ -30,6 +30,7 @@ ____
compile 'org.springframework.rewrite:spring-rewrite-commons-launcher:{projectVersion}'
----
=== Implement a Recipe Launcher
[source,java]

View File

@@ -102,16 +102,17 @@ public class PrivateArtifactRepositoryTest {
public static final String DEPENDENCY_CLASS_FQNAME = "com.example.dependency.DependencyClass";
private static final String NEW_USER_HOME = Path.of(".")
.resolve(TESTCODE_DIR + "/user.home")
.toAbsolutePath()
.normalize()
.toString();
.resolve(TESTCODE_DIR + "/user.home")
.toAbsolutePath()
.normalize()
.toString();
private static final File LOCAL_MAVEN_REPOSITORY = Path.of(NEW_USER_HOME + "/.m2/repository").toFile();
private static final Path DEPENDENCY_PATH_IN_LOCAL_MAVEN_REPO = Path
.of(NEW_USER_HOME + "/.m2/repository/com/example/dependency/dependency-project")
.toAbsolutePath()
.normalize();
.of(NEW_USER_HOME + "/.m2/repository/com/example/dependency/dependency-project")
.toAbsolutePath()
.normalize();
// File path was too long under Windows when Maven repository was under TESTCODE_DIR +
// "/reposilite-data"
@@ -356,6 +357,7 @@ public class PrivateArtifactRepositoryTest {
throw new RuntimeException("Could not create target dir");
}
}
}
}

View File

@@ -25,6 +25,7 @@ import org.openrewrite.maven.utilities.MavenArtifactDownloader;
import org.openrewrite.xml.tree.Xml;
import org.springframework.core.io.Resource;
import org.springframework.rewrite.parsers.maven.MavenRuntimeInformation;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.rewrite.utils.ResourceUtil;
import java.io.File;
@@ -88,15 +89,26 @@ public class MavenProject {
return pomFile;
}
/**
* @return absolute Path of Module
*/
public Path getModulePath() {
return projectRoot.resolve(getModuleDir());
}
/**
* @return Path for Module relative to {@code baseDir}.
*/
public Path getModuleDir() {
if (getBasedir() == null) {
return null;
}
else if (projectRoot.relativize(ResourceUtil.getPath(pomFile)).toString().equals("pom.xml")) {
else if ("pom.xml"
.equals(LinuxWindowsPathUnifier.relativize(projectRoot, ResourceUtil.getPath(pomFile)).toString())) {
return Path.of("");
}
else {
return projectRoot.relativize(ResourceUtil.getPath(pomFile)).getParent();
return LinuxWindowsPathUnifier.relativize(projectRoot, ResourceUtil.getPath(pomFile)).getParent();
}
}
@@ -218,7 +230,11 @@ public class MavenProject {
@NotNull
private static Predicate<Resource> whenIn(Path sourceDirectory) {
return r -> ResourceUtil.getPath(r).toString().startsWith(sourceDirectory.toString());
return r -> {
String resourcePath = LinuxWindowsPathUnifier.unifiedPathString(r);
String sourceDirectoryPath = LinuxWindowsPathUnifier.unifiedPathString(sourceDirectory);
return resourcePath.startsWith(sourceDirectoryPath);
};
}
public List<Resource> getJavaSourcesInTarget() {
@@ -230,11 +246,12 @@ public class MavenProject {
}
public List<Resource> getMainJavaSources() {
return listJavaSources(resources, getProjectRoot().resolve(getModuleDir()).resolve("src/main/java"));
Path sourceDir = getProjectRoot().resolve(getModuleDir()).resolve("src/main/java");
return listJavaSources(resources, sourceDir);
}
public Path getModulePath() {
return projectRoot.resolve(getModuleDir());
public List<Resource> getTestJavaSources() {
return listJavaSources(resources, getProjectRoot().resolve(getModuleDir()).resolve("src/test/java"));
}
public ProjectId getProjectId() {

View File

@@ -31,6 +31,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -57,9 +58,8 @@ public class ProjectScanner {
if (!baseDir.toFile().exists()) {
throw new IllegalArgumentException("Provided path does not exist: " + baseDir);
}
Path absoluteRootPath = baseDir.toAbsolutePath();
String unifiedPath = new LinuxWindowsPathUnifier().unifyPath(absoluteRootPath.toString() + "/**");
String pattern = "file:" + unifiedPath;
Path absoluteRootPath = baseDir;
String pattern = "file:" + absoluteRootPath.toString() + "/**";
try {
Resource[] resources = ResourcePatternUtils.getResourcePatternResolver(resourceLoader)
.getResources(pattern);
@@ -72,7 +72,7 @@ public class ProjectScanner {
int numIgnored = resources.length - numResulting;
LOGGER.debug("Scan returns %s resources, %d resources were ignored.".formatted(numResulting, numIgnored));
LOGGER.trace("Resources resulting from scan: %s".formatted(resultingResources.stream()
.map(r -> absoluteRootPath.relativize(ResourceUtil.getPath(r)).toString())
.map(getResourceStringFunction(absoluteRootPath))
.collect(Collectors.joining(", "))));
return resultingResources;
@@ -82,6 +82,11 @@ public class ProjectScanner {
}
}
@NotNull
private static Function<Resource, String> getResourceStringFunction(Path absoluteRootPath) {
return r -> LinuxWindowsPathUnifier.relativize(absoluteRootPath, ResourceUtil.getPath(r)).toString();
}
@NotNull
private List<Resource> filterIgnoredResources(Path baseDir, Resource[] resources) {
Set<String> effectivePathMatcherPatterns = new HashSet<>();

View File

@@ -35,6 +35,8 @@ import org.springframework.rewrite.parsers.maven.MavenProjectAnalyzer;
import org.springframework.rewrite.parsers.maven.ProvenanceMarkerFactory;
import org.springframework.rewrite.recipes.RewriteRecipeDiscovery;
import org.springframework.rewrite.scopes.ScanScope;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.util.StringUtils;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -120,7 +122,7 @@ public class RewriteProjectParser {
}
/**
* Parse given {@link Resource}s in {@code baseDir} to OpenRewrite AST representation.
* Parse given {@link Resource}s in {@code baseDir} to OpenRewrite LST.
*/
public RewriteProjectParsingResult parse(Path givenBaseDir, List<Resource> resources) {
scanScope.clear(beanFactory);
@@ -175,8 +177,8 @@ public class RewriteProjectParser {
if (!givenBaseDir.isAbsolute()) {
givenBaseDir = givenBaseDir.toAbsolutePath().normalize();
}
final Path baseDir = givenBaseDir;
return baseDir;
String cleanedPath = StringUtils.cleanPath(givenBaseDir.toString());
return Path.of(cleanedPath);
}
}

View File

@@ -90,7 +90,6 @@ public class RewriteResourceParser {
}
public Stream<SourceFile> parse(Path searchDir, List<Resource> resources, Set<Path> alreadyParsed) {
// TODO: 945 remove/clean this up
List<Resource> resourcesLeft = resources.stream()
.filter(r -> alreadyParsed.stream()
.noneMatch(path -> ResourceUtil.getPath(r).toString().startsWith(path.toString())))

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.rewrite.parsers.maven;
import org.jetbrains.annotations.NotNull;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Parser;
import org.openrewrite.SourceFile;
@@ -24,6 +25,7 @@ import org.openrewrite.xml.tree.Xml;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.rewrite.utils.ResourceUtil;
import org.springframework.util.Assert;
@@ -101,10 +103,15 @@ public class BuildFileParser {
private List<Resource> findResourcesWithoutProvenanceMarker(Path baseDir, List<Resource> buildFileResources,
Map<Path, List<Marker>> provenanceMarkers) {
return buildFileResources.stream()
.filter(r -> !provenanceMarkers.containsKey(baseDir.resolve(ResourceUtil.getPath(r)).normalize()))
.filter(r -> !provenanceMarkers.containsKey(ResourceUtil.getPath(r)))
.toList();
}
@NotNull
private static Path getUnifiedPath(Path baseDir, Resource r) {
return LinuxWindowsPathUnifier.unifiedPath(baseDir.resolve(ResourceUtil.getPath(r)));
}
private static List<Resource> retrieveNonPomFiles(List<Resource> buildFileResources) {
return buildFileResources.stream()
.filter(r -> !"pom.xml".equals(ResourceUtil.getPath(r).getFileName().toString()))
@@ -167,7 +174,7 @@ public class BuildFileParser {
private static boolean filterTestResources(Resource r) {
String path = ResourceUtil.getPath(r).toString();
boolean underTest = path.contains("src/test");
boolean underTest = path.contains(Path.of("src/test").toString());
if (underTest) {
LOGGER.info("Ignore build file '%s' having 'src/test' in its path indicating it's a build file for tests."
.formatted(path));

View File

@@ -36,6 +36,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.rewrite.parsers.*;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.rewrite.utils.ResourceUtil;
import java.io.InputStream;
@@ -58,333 +59,344 @@ import static org.openrewrite.Tree.randomId;
*/
public class MavenModuleParser {
private static final Logger LOGGER = LoggerFactory.getLogger(MavenProvenanceMarkerFactory.class);
private static final Logger LOGGER = LoggerFactory.getLogger(MavenModuleParser.class);
private final SpringRewriteProperties springRewriteProperties;
private final SpringRewriteProperties springRewriteProperties;
public MavenModuleParser(SpringRewriteProperties springRewriteProperties) {
this.springRewriteProperties = springRewriteProperties;
}
public MavenModuleParser(SpringRewriteProperties springRewriteProperties) {
this.springRewriteProperties = springRewriteProperties;
}
public List<SourceFile> parseModuleSourceFiles(List<Resource> resources, MavenProject currentProject,
Xml.Document moduleBuildFile, List<Marker> provenanceMarkers, List<NamedStyles> styles,
ExecutionContext executionContext, Path baseDir) {
public List<SourceFile> parseModuleSourceFiles(List<Resource> resources, MavenProject currentProject,
Xml.Document moduleBuildFile, List<Marker> provenanceMarkers, List<NamedStyles> styles,
ExecutionContext executionContext, Path baseDir) {
List<SourceFile> sourceFiles = new ArrayList<>();
// 146:149: get source encoding from maven
// TDOD:
// String s =
// moduleBuildFile.getMarkers().findFirst(MavenResolutionResult.class).get().getPom().getProperties().get("project.build.sourceEncoding");
// if (mavenSourceEncoding != null) {
// ParsingExecutionContextView.view(ctx).setCharset(Charset.forName(mavenSourceEncoding.toString()));
// }
Object mavenSourceEncoding = currentProject.getProjectEncoding();
if (mavenSourceEncoding != null) {
ParsingExecutionContextView.view(executionContext)
.setCharset(Charset.forName(mavenSourceEncoding.toString()));
}
List<SourceFile> sourceFiles = new ArrayList<>();
// 146:149: get source encoding from maven
// TDOD:
// String s =
// moduleBuildFile.getMarkers().findFirst(MavenResolutionResult.class).get().getPom().getProperties().get("project.build.sourceEncoding");
// if (mavenSourceEncoding != null) {
// ParsingExecutionContextView.view(ctx).setCharset(Charset.forName(mavenSourceEncoding.toString()));
// }
Object mavenSourceEncoding = currentProject.getProjectEncoding();
if (mavenSourceEncoding != null) {
ParsingExecutionContextView.view(executionContext)
.setCharset(Charset.forName(mavenSourceEncoding.toString()));
}
JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder = JavaParser.fromJavaVersion()
.styles(styles)
.logCompilationWarningsAndErrors(false);
JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder = JavaParser.fromJavaVersion()
.styles(styles)
.logCompilationWarningsAndErrors(false);
Path buildFilePath = currentProject.getBasedir().resolve(moduleBuildFile.getSourcePath());
LOGGER.info("Parsing module " + buildFilePath);
// these paths will be ignored by ResourceParser
Set<Path> skipResourceScanDirs = pathsToOtherMavenProjects(currentProject, buildFilePath);
RewriteResourceParser rp = new RewriteResourceParser(baseDir, springRewriteProperties.getIgnoredPathPatterns(),
springRewriteProperties.getPlainTextMasks(), springRewriteProperties.getSizeThresholdMb(),
skipResourceScanDirs, javaParserBuilder.clone(), executionContext);
Path buildFilePath = currentProject.getBasedir().resolve(moduleBuildFile.getSourcePath());
LOGGER.info("Parsing module " + buildFilePath);
// these paths will be ignored by ResourceParser
Set<Path> skipResourceScanDirs = pathsToOtherMavenProjects(currentProject, buildFilePath);
RewriteResourceParser rp = new RewriteResourceParser(baseDir, springRewriteProperties.getIgnoredPathPatterns(),
springRewriteProperties.getPlainTextMasks(), springRewriteProperties.getSizeThresholdMb(),
skipResourceScanDirs, javaParserBuilder.clone(), executionContext);
Set<Path> alreadyParsed = new HashSet<>();
Path moduleBuildFilePath = baseDir.resolve(moduleBuildFile.getSourcePath());
alreadyParsed.add(moduleBuildFilePath);
alreadyParsed.addAll(skipResourceScanDirs);
SourceSetParsingResult mainSourcesParsingResult = parseMainSources(baseDir, currentProject, moduleBuildFile,
resources, javaParserBuilder.clone(), rp, provenanceMarkers, alreadyParsed, executionContext);
SourceSetParsingResult testSourcesParsingResult = parseTestSources(baseDir, currentProject, moduleBuildFile,
javaParserBuilder.clone(), rp, provenanceMarkers, alreadyParsed, executionContext, resources,
mainSourcesParsingResult.classpath());
// Collect the dirs of modules parsed in previous steps
Set<Path> alreadyParsed = new HashSet<>();
Path moduleBuildFilePath = baseDir.resolve(moduleBuildFile.getSourcePath());
alreadyParsed.add(moduleBuildFilePath);
alreadyParsed.addAll(skipResourceScanDirs);
// parse other project resources
Stream<SourceFile> parsedResourceFiles = rp.parse(moduleBuildFilePath.getParent(), resources, alreadyParsed)
// FIXME: handle generated sources
.map(addProvenance(baseDir, provenanceMarkers, null));
SourceSetParsingResult mainSourcesParsingResult = processMainSources(baseDir, resources, moduleBuildFile,
javaParserBuilder, rp, provenanceMarkers, alreadyParsed, executionContext, currentProject);
List<SourceFile> mainAndTestSources = mergeAndFilterExcluded(baseDir,
springRewriteProperties.getIgnoredPathPatterns(), mainSourcesParsingResult.sourceFiles(),
testSourcesParsingResult.sourceFiles());
List<SourceFile> resourceFilesList = parsedResourceFiles.toList();
sourceFiles.addAll(mainAndTestSources);
sourceFiles.addAll(resourceFilesList);
SourceSetParsingResult testSourcesParsingResult = processTestSources(baseDir, moduleBuildFile,
javaParserBuilder, rp, provenanceMarkers, alreadyParsed, executionContext, currentProject, resources,
mainSourcesParsingResult.classpath());
// Collect the dirs of modules parsed in previous steps
return sourceFiles;
}
// parse other project resources
Stream<SourceFile> parsedResourceFiles = rp.parse(moduleBuildFilePath.getParent(), resources, alreadyParsed)
// FIXME: handle generated sources
.map(addProvenance(baseDir, provenanceMarkers, null));
List<SourceFile> mainAndTestSources = mergeAndFilterExcluded(baseDir,
springRewriteProperties.getIgnoredPathPatterns(), mainSourcesParsingResult.sourceFiles(),
testSourcesParsingResult.sourceFiles());
List<SourceFile> resourceFilesList = parsedResourceFiles.toList();
sourceFiles.addAll(mainAndTestSources);
sourceFiles.addAll(resourceFilesList);
/**
* Add {@link Marker}s to {@link SourceFile}.
*/
public <T extends SourceFile> UnaryOperator<T> addProvenance(Path baseDir, List<Marker> provenance,
@Nullable Collection<Path> generatedSources) {
return s -> {
Markers markers = s.getMarkers();
for (Marker marker : provenance) {
markers = markers.addIfAbsent(marker);
}
if (generatedSources != null && generatedSources.contains(baseDir.resolve(s.getSourcePath()))) {
markers = markers.addIfAbsent(new Generated(randomId()));
}
return s.withMarkers(markers);
};
}
return sourceFiles;
}
private List<SourceFile> mergeAndFilterExcluded(Path baseDir, Set<String> exclusions, List<SourceFile> mainSources,
List<SourceFile> testSources) {
List<PathMatcher> pathMatchers = exclusions.stream()
.map(pattern -> baseDir.getFileSystem().getPathMatcher("glob:" + pattern))
.toList();
if (pathMatchers.isEmpty()) {
return Stream.concat(mainSources.stream(), testSources.stream()).toList();
}
return new ArrayList<>(Stream.concat(mainSources.stream(), testSources.stream())
.filter(s -> isNotExcluded(baseDir, pathMatchers, s))
.toList());
}
/**
* Add {@link Marker}s to {@link SourceFile}.
*/
public <T extends SourceFile> UnaryOperator<T> addProvenance(Path baseDir, List<Marker> provenance,
@Nullable Collection<Path> generatedSources) {
return s -> {
Markers markers = s.getMarkers();
for (Marker marker : provenance) {
markers = markers.addIfAbsent(marker);
}
if (generatedSources != null && generatedSources.contains(baseDir.resolve(s.getSourcePath()))) {
markers = markers.addIfAbsent(new Generated(randomId()));
}
return s.withMarkers(markers);
};
}
private static boolean isNotExcluded(Path baseDir, List<PathMatcher> exclusions, SourceFile s) {
return exclusions.stream()
.noneMatch(pm -> pm.matches(baseDir.resolve(s.getSourcePath()).toAbsolutePath().normalize()));
}
private List<SourceFile> mergeAndFilterExcluded(Path baseDir, Set<String> exclusions, List<SourceFile> mainSources,
List<SourceFile> testSources) {
List<PathMatcher> pathMatchers = exclusions.stream()
.map(pattern -> baseDir.getFileSystem().getPathMatcher("glob:" + pattern))
.toList();
if (pathMatchers.isEmpty()) {
return Stream.concat(mainSources.stream(), testSources.stream()).toList();
}
return new ArrayList<>(Stream.concat(mainSources.stream(), testSources.stream())
.filter(s -> isNotExcluded(baseDir, pathMatchers, s))
.toList());
}
private SourceSetParsingResult parseTestSources(Path baseDir, MavenProject mavenProject,
Xml.Document moduleBuildFile, JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder,
RewriteResourceParser rp, List<Marker> provenanceMarkers, Set<Path> alreadyParsed,
ExecutionContext executionContext, List<Resource> resources, List<JavaType.FullyQualified> classpath) {
return processTestSources(baseDir, moduleBuildFile, javaParserBuilder, rp,
provenanceMarkers, alreadyParsed, executionContext, mavenProject, resources, classpath);
}
private static boolean isNotExcluded(Path baseDir, List<PathMatcher> exclusions, SourceFile s) {
return exclusions.stream()
.noneMatch(pm -> pm.matches(baseDir.resolve(s.getSourcePath()).toAbsolutePath().normalize()));
}
/**
*
*/
private SourceSetParsingResult parseMainSources(Path baseDir, MavenProject mavenProject,
Xml.Document moduleBuildFile, List<Resource> resources,
JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder, RewriteResourceParser rp,
List<Marker> provenanceMarkers, Set<Path> alreadyParsed, ExecutionContext executionContext) {
private Set<Path> pathsToOtherMavenProjects(MavenProject mavenProject, Path moduleBuildFile) {
return mavenProject.getCollectedProjects()
.stream()
.filter(p -> !p.getFile().toPath().toString().equals(moduleBuildFile.toString()))
.map(p -> p.getFile().toPath().getParent())
.collect(Collectors.toSet());
}
return processMainSources(baseDir, resources, moduleBuildFile,
javaParserBuilder, rp, provenanceMarkers, alreadyParsed, executionContext, mavenProject);
}
/**
* Parse Java sources and resources under {@code src/main} of current module.
*/
public SourceSetParsingResult processMainSources(Path baseDir, List<Resource> resources,
Xml.Document moduleBuildFile, JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder,
RewriteResourceParser rp, List<Marker> provenanceMarkers, Set<Path> alreadyParsed,
ExecutionContext executionContext, MavenProject currentProject) {
LOGGER.info("Processing main sources in module '%s'".formatted(currentProject.getProjectId()));
// FIXME: 945
// Some annotation processors output generated sources to the /target directory.
// These are added for parsing but
// should be filtered out of the final SourceFile list.
private Set<Path> pathsToOtherMavenProjects(MavenProject mavenProject, Path moduleBuildFile) {
return mavenProject.getCollectedProjects()
.stream()
.filter(p -> !p.getFile().toPath().toString().equals(moduleBuildFile.toString()))
.map(p -> p.getFile().toPath().getParent())
.collect(Collectors.toSet());
}
List<Resource> mainJavaSources = new ArrayList<>();
List<Resource> javaSourcesInTarget = currentProject.getJavaSourcesInTarget(); // listJavaSources(resources,
// currentProject.getBasedir().resolve(currentProject.getBuildDirectory()));
List<Resource> javaSourcesInMain = currentProject.getMainJavaSources(); // listJavaSources(resources,
// currentProject.getBasedir().resolve(currentProject.getSourceDirectory()));
mainJavaSources.addAll(javaSourcesInTarget);
mainJavaSources.addAll(javaSourcesInMain);
LOGGER.info("[%s] Parsing main source files".formatted(currentProject));
/**
* Parse Java sources and resources under {@code src/main} of current module.
*/
public SourceSetParsingResult processMainSources(Path baseDir, List<Resource> resources,
Xml.Document moduleBuildFile, JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder,
RewriteResourceParser rp, List<Marker> provenanceMarkers, Set<Path> alreadyParsed,
ExecutionContext executionContext, MavenProject currentProject) {
LOGGER.info("Processing main sources in module '%s'".formatted(currentProject.getProjectId()));
// FIXME: 945
// Some annotation processors output generated sources to the /target directory.
// These are added for parsing but
// should be filtered out of the final SourceFile list.
// FIXME 945 classpath
// - Resolve dependencies to non-reactor projects from Maven repository
// - Resolve dependencies to reactor projects by providing the sources
// javaParserBuilder.classpath(byte[])
List<Resource> mainJavaSources = new ArrayList<>();
List<Resource> javaSourcesInTarget = currentProject.getJavaSourcesInTarget(); // listJavaSources(resources,
// currentProject.getBasedir().resolve(currentProject.getBuildDirectory()));
List<Resource> javaSourcesInMain = currentProject.getMainJavaSources(); // listJavaSources(resources,
// currentProject.getBasedir().resolve(currentProject.getSourceDirectory()));
mainJavaSources.addAll(javaSourcesInTarget);
mainJavaSources.addAll(javaSourcesInMain);
// we're processing a module here. The classpath of the module consists of all
// declared dependencies and their transitive dependencies too.
// For dependencies to projects that belong to the current rector...
// They'd either need to be built with Maven before to guarantee that the jars are
// installed to local Maven repo.
// Or, the classpath must be created from the sources of the project.
LOGGER.info("[%s] Parsing source files".formatted(currentProject));
List<Path> dependencies = currentProject.getCompileClasspathElements();
// FIXME 945 classpath
// - Resolve dependencies to non-reactor projects from Maven repository
// - Resolve dependencies to reactor projects by providing the sources
// javaParserBuilder.classpath(byte[])
javaParserBuilder.classpath(dependencies);
// we're processing a module here. The classpath of the module consists of all
// declared dependencies and their transitive dependencies too.
// For dependencies to projects that belong to the current rector...
// They'd either need to be built with Maven before to guarantee that the jars are
// installed to local Maven repo.
// Or, the classpath must be created from the sources of the project.
LOGGER.info("Dependencies on main classpath: %s".formatted(dependencies));
List<Path> dependencies = currentProject.getCompileClasspathElements();
JavaTypeCache typeCache = new JavaTypeCache();
javaParserBuilder.typeCache(typeCache);
javaParserBuilder.classpath(dependencies);
Iterable<Parser.Input> inputs = mainJavaSources.stream().map(r -> {
FileAttributes fileAttributes = null;
Path path = ResourceUtil.getPath(r);
boolean isSynthetic = Files.exists(path);
Supplier<InputStream> inputStreamSupplier = () -> ResourceUtil.getInputStream(r);
Parser.Input input = new Parser.Input(path, fileAttributes, inputStreamSupplier, isSynthetic);
return input;
}).toList();
JavaTypeCache typeCache = new JavaTypeCache();
javaParserBuilder.typeCache(typeCache);
LOGGER.info("Parsing main Java sources.");
Iterable<Parser.Input> inputs = mainJavaSources.stream().map(r -> {
FileAttributes fileAttributes = null;
Path path = ResourceUtil.getPath(r);
boolean isSynthetic = Files.exists(path);
Supplier<InputStream> inputStreamSupplier = () -> ResourceUtil.getInputStream(r);
Parser.Input input = new Parser.Input(path, fileAttributes, inputStreamSupplier, isSynthetic);
return input;
}).toList();
Set<JavaType.FullyQualified> localClassesCp = new HashSet<>();
JavaSourceSet javaSourceSet = sourceSet("main", dependencies, typeCache);
List<? extends SourceFile> cus = javaParserBuilder.build()
.parseInputs(inputs, baseDir, executionContext)
.peek(s -> {
((J.CompilationUnit) s).getClasses()
.stream()
.map(J.ClassDeclaration::getType)
.forEach(localClassesCp::add);
Set<JavaType.FullyQualified> localClassesCp = new HashSet<>();
JavaSourceSet javaSourceSet = sourceSet("main", dependencies, typeCache);
List<? extends SourceFile> cus = javaParserBuilder.build()
.parseInputs(inputs, baseDir, executionContext)
.peek(s -> {
((J.CompilationUnit) s).getClasses()
.stream()
.map(J.ClassDeclaration::getType)
.forEach(localClassesCp::add);
alreadyParsed.add(baseDir.resolve(s.getSourcePath()));
})
.toList();
alreadyParsed.add(baseDir.resolve(s.getSourcePath()));
})
.toList();
LOGGER.info("Parsed %d main Java source files.".formatted(cus.size()));
// TODO: This is a hack:
// Parsed java sources are not themselves on the classpath (here).
// The actual parsing happens when the stream is terminated (toList),
// therefore the toList() must be called before the parsed compilation units can
// be added to the classpath
List<Marker> mainProjectProvenance = new ArrayList<>(provenanceMarkers);
javaSourceSet = appendToClasspath(localClassesCp, javaSourceSet);
mainProjectProvenance.add(javaSourceSet);
// TODO: This is a hack:
// Parsed java sources are not themselves on the classpath (here).
// The actual parsing happens when the stream is terminated (toList),
// therefore the toList() must be called before the parsed compilation units can
// be added to the classpath
List<Marker> mainProjectProvenance = new ArrayList<>(provenanceMarkers);
javaSourceSet = appendToClasspath(localClassesCp, javaSourceSet);
mainProjectProvenance.add(javaSourceSet);
List<Path> parsedJavaPaths = javaSourcesInTarget.stream().map(ResourceUtil::getPath).toList();
Stream<SourceFile> parsedJava = cus.stream()
.map(addProvenance(baseDir, mainProjectProvenance, parsedJavaPaths));
LOGGER.debug(
"[%s] Scanned %d java source files in main scope.".formatted(currentProject, mainJavaSources.size()));
List<Path> parsedJavaPaths = javaSourcesInTarget.stream().map(ResourceUtil::getPath).toList();
Stream<SourceFile> parsedMainJava = cus.stream()
.map(addProvenance(baseDir, mainProjectProvenance, parsedJavaPaths));
LOGGER.debug(
"[%s] Scanned %d java source files in main scope.".formatted(currentProject, mainJavaSources.size()));
// Filter out any generated source files from the returned list, as we do not want
// to apply the recipe to the
// generated files.
Path buildDirectory = Paths.get(currentProject.getBuildDirectory());
List<SourceFile> sourceFiles = parsedJava.filter(s -> !s.getSourcePath().startsWith(buildDirectory))
.collect(Collectors.toCollection(ArrayList::new));
// Filter out any generated source files from the returned list, as we do not want
// to apply the recipe to the
// generated files.
Path buildDirectory = LinuxWindowsPathUnifier.unifiedPath(Paths.get(currentProject.getBuildDirectory()));
List<SourceFile> filteredMainJava = filterOutResourcesInDir(parsedMainJava, buildDirectory);
int sourcesParsedBefore = alreadyParsed.size();
alreadyParsed.addAll(parsedJavaPaths);
List<SourceFile> parsedResourceFiles = rp
.parse(currentProject.getModulePath().resolve("src/main/resources"), resources, alreadyParsed)
.map(addProvenance(baseDir, mainProjectProvenance, null))
.toList();
int sourcesParsedBefore = alreadyParsed.size();
alreadyParsed.addAll(parsedJavaPaths);
LOGGER.debug("[%s] Scanned %d resource files in main scope.".formatted(currentProject,
(alreadyParsed.size() - sourcesParsedBefore)));
// Any resources parsed from "main/resources" should also have the main source set
// added to them.
sourceFiles.addAll(parsedResourceFiles);
return new SourceSetParsingResult(sourceFiles, javaSourceSet.getClasspath());
}
List<Resource> resourcesLeft = resources.stream()
.filter(r -> alreadyParsed.stream().noneMatch(path -> LinuxWindowsPathUnifier.pathStartsWith(r, path)))
.toList();
/**
* Add entries that don't exist in the classpath of {@code javaSourceSet} from
* {@code appendingClasspath}.
*/
@NotNull
private static JavaSourceSet appendToClasspath(Set<JavaType.FullyQualified> appendingClasspath,
JavaSourceSet javaSourceSet) {
List<JavaType.FullyQualified> curCp = javaSourceSet.getClasspath();
appendingClasspath.forEach(f -> {
if (!curCp.contains(f)) {
curCp.add(f);
}
});
javaSourceSet = javaSourceSet.withClasspath(new ArrayList<>(curCp));
return javaSourceSet;
}
LOGGER.info("Parsing main resources");
List<SourceFile> parsedResourceFiles = rp
.parseSourceFiles(currentProject.getModulePath().resolve("src/main/resources"), resourcesLeft,
alreadyParsed, executionContext)
.map(addProvenance(baseDir, mainProjectProvenance, null))
.toList();
@NotNull
private static JavaSourceSet sourceSet(String name, List<Path> dependencies, JavaTypeCache typeCache) {
return JavaSourceSet.build(name, dependencies, typeCache, false);
}
LOGGER.info("Parsed %d main resources".formatted(parsedResourceFiles.size()));
/**
* Parse Java sources and resource files under {@code src/test}.
*/
public SourceSetParsingResult processTestSources(Path baseDir, Xml.Document moduleBuildFile,
JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder, RewriteResourceParser rp,
List<Marker> provenanceMarkers, Set<Path> alreadyParsed, ExecutionContext executionContext,
MavenProject currentProject, List<Resource> resources, List<JavaType.FullyQualified> classpath) {
LOGGER.info("Processing test sources in module '%s'".formatted(currentProject.getProjectId()));
// TODO: Remove
// List<SourceFile> parsedResourceFiles = rp
// .parse(currentProject.getModulePath().resolve("src/main/resources"), resources,
// alreadyParsed)
// .map(addProvenance(baseDir, mainProjectProvenance, null))
// .toList();
List<Path> testDependencies = currentProject.getTestClasspathElements();
LOGGER.debug("[%s] Scanned %d resource files in main scope.".formatted(currentProject,
(alreadyParsed.size() - sourcesParsedBefore)));
// Any resources parsed from "main/resources" should also have the main source set
// added to them.
filteredMainJava.addAll(parsedResourceFiles);
return new SourceSetParsingResult(filteredMainJava, javaSourceSet.getClasspath());
}
javaParserBuilder.classpath(testDependencies);
JavaTypeCache typeCache = new JavaTypeCache();
javaParserBuilder.typeCache(typeCache);
@NotNull
private static ArrayList<SourceFile> filterOutResourcesInDir(Stream<SourceFile> parsedJava, Path buildDirectory) {
return parsedJava.filter(s -> !s.getSourcePath().startsWith(buildDirectory))
.collect(Collectors.toCollection(ArrayList::new));
}
List<Resource> testJavaSources = listJavaSources(resources,
currentProject.getBasedir().resolve(currentProject.getTestSourceDirectory()));
alreadyParsed.addAll(testJavaSources.stream().map(ResourceUtil::getPath).toList());
/**
* Add entries that don't exist in the classpath of {@code javaSourceSet} from
* {@code appendingClasspath}.
*/
@NotNull
private static JavaSourceSet appendToClasspath(Set<JavaType.FullyQualified> appendingClasspath,
JavaSourceSet javaSourceSet) {
List<JavaType.FullyQualified> curCp = javaSourceSet.getClasspath();
appendingClasspath.forEach(f -> {
if (!curCp.contains(f)) {
curCp.add(f);
}
});
javaSourceSet = javaSourceSet.withClasspath(new ArrayList<>(curCp));
return javaSourceSet;
}
Iterable<Parser.Input> inputs = testJavaSources.stream()
.map(r -> new Parser.Input(ResourceUtil.getPath(r), () -> ResourceUtil.getInputStream(r)))
.toList();
@NotNull
private static JavaSourceSet sourceSet(String name, List<Path> dependencies, JavaTypeCache typeCache) {
return JavaSourceSet.build(name, dependencies, typeCache, false);
}
final List<JavaType.FullyQualified> localClassesCp = new ArrayList<>();
List<? extends SourceFile> cus = javaParserBuilder.build()
.parseInputs(inputs, baseDir, executionContext)
.peek(s -> {
((J.CompilationUnit) s).getClasses()
.stream()
.map(J.ClassDeclaration::getType)
.forEach(localClassesCp::add);
alreadyParsed.add(baseDir.resolve(s.getSourcePath()));
})
.toList();
/**
* Parse Java sources and resource files under {@code src/test}.
*/
public SourceSetParsingResult processTestSources(Path baseDir, Xml.Document moduleBuildFile,
JavaParser.Builder<? extends JavaParser, ?> javaParserBuilder, RewriteResourceParser rp,
List<Marker> provenanceMarkers, Set<Path> alreadyParsed, ExecutionContext executionContext,
MavenProject currentProject, List<Resource> resources, List<JavaType.FullyQualified> classpath) {
LOGGER.info("Processing test sources in module '%s'".formatted(currentProject.getProjectId()));
List<Marker> markers = new ArrayList<>(provenanceMarkers);
List<Path> testDependencies = currentProject.getTestClasspathElements();
JavaSourceSet javaSourceSet = sourceSet("test", testDependencies, typeCache);
Set<JavaType.FullyQualified> curClasspath = Stream.concat(classpath.stream(), localClassesCp.stream())
.collect(Collectors.toSet());
javaSourceSet = appendToClasspath(curClasspath, javaSourceSet);
markers.add(javaSourceSet);
Stream<SourceFile> parsedJava = cus.stream().map(addProvenance(baseDir, markers, null));
javaParserBuilder.classpath(testDependencies);
JavaTypeCache typeCache = new JavaTypeCache();
javaParserBuilder.typeCache(typeCache);
LOGGER.debug(
"[%s] Scanned %d java source files in test scope.".formatted(currentProject, testJavaSources.size()));
Stream<SourceFile> sourceFiles = parsedJava;
List<Resource> testJavaSources = currentProject.getTestJavaSources();
// listJavaSources(resources,
// currentProject.getBasedir().resolve(currentProject.getTestSourceDirectory()));
// alreadyParsed.addAll(testJavaSources.stream().map(ResourceUtil::getPath).toList());
// Any resources parsed from "test/resources" should also have the test source set
// added to them.
int sourcesParsedBefore = alreadyParsed.size();
Stream<SourceFile> parsedResourceFiles = rp
.parse(currentProject.getBasedir().resolve("src/test/resources"), resources, alreadyParsed)
.map(addProvenance(baseDir, markers, null));
LOGGER.debug("[%s] Scanned %d resource files in test scope.".formatted(currentProject,
(alreadyParsed.size() - sourcesParsedBefore)));
sourceFiles = Stream.concat(sourceFiles, parsedResourceFiles);
List<SourceFile> result = sourceFiles.toList();
return new SourceSetParsingResult(result, javaSourceSet.getClasspath());
}
Iterable<Parser.Input> inputs = testJavaSources.stream()
.map(r -> new Parser.Input(ResourceUtil.getPath(r), () -> ResourceUtil.getInputStream(r)))
.toList();
// FIXME: 945 take Java sources from resources
private static List<Resource> listJavaSources(List<Resource> resources, Path sourceDirectory) {
return resources.stream().filter(whenIn(sourceDirectory)).filter(whenFileNameEndsWithJava()).toList();
}
final List<JavaType.FullyQualified> localClassesCp = new ArrayList<>();
List<? extends SourceFile> cus = javaParserBuilder.build()
.parseInputs(inputs, baseDir, executionContext)
.peek(s -> {
((J.CompilationUnit) s).getClasses()
.stream()
.map(J.ClassDeclaration::getType)
.forEach(localClassesCp::add);
alreadyParsed.add(baseDir.resolve(s.getSourcePath()));
})
.toList();
@NotNull
private static Predicate<Resource> whenFileNameEndsWithJava() {
return p -> ResourceUtil.getPath(p).getFileName().toString().endsWith(".java");
}
List<Marker> markers = new ArrayList<>(provenanceMarkers);
@NotNull
private static Predicate<Resource> whenIn(Path sourceDirectory) {
return r -> ResourceUtil.getPath(r).toString().startsWith(sourceDirectory.toString());
}
JavaSourceSet javaSourceSet = sourceSet("test", testDependencies, typeCache);
Set<JavaType.FullyQualified> curClasspath = Stream.concat(classpath.stream(), localClassesCp.stream())
.collect(Collectors.toSet());
javaSourceSet = appendToClasspath(curClasspath, javaSourceSet);
markers.add(javaSourceSet);
Stream<SourceFile> parsedJava = cus.stream().map(addProvenance(baseDir, markers, null));
LOGGER.debug(
"[%s] Scanned %d java source files in test scope.".formatted(currentProject, testJavaSources.size()));
Stream<SourceFile> sourceFiles = parsedJava;
// Any resources parsed from "test/resources" should also have the test source set
// added to them.
int sourcesParsedBefore = alreadyParsed.size();
Stream<SourceFile> parsedResourceFiles = rp
.parse(currentProject.getBasedir().resolve("src/test/resources"), resources, alreadyParsed)
.map(addProvenance(baseDir, markers, null));
LOGGER.debug("[%s] Scanned %d resource files in test scope.".formatted(currentProject,
(alreadyParsed.size() - sourcesParsedBefore)));
sourceFiles = Stream.concat(sourceFiles, parsedResourceFiles);
List<SourceFile> result = sourceFiles.toList();
return new SourceSetParsingResult(result, javaSourceSet.getClasspath());
}
// FIXME: 945 take Java sources from resources
private static List<Resource> listJavaSources(List<Resource> resources, Path sourceDirectory) {
return resources.stream()
.filter(whenIn(LinuxWindowsPathUnifier.unifiedPath(sourceDirectory)))
.filter(whenFileNameEndsWithJava())
.toList();
}
@NotNull
private static Predicate<Resource> whenFileNameEndsWithJava() {
return p -> ResourceUtil.getPath(p).getFileName().toString().endsWith(".java");
}
@NotNull
private static Predicate<Resource> whenIn(Path sourceDirectory) {
return r -> ResourceUtil.getPath(r).toString().startsWith(sourceDirectory.toString());
}
}

View File

@@ -18,16 +18,19 @@ package org.springframework.rewrite.parsers.maven;
import org.apache.maven.model.*;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.jetbrains.annotations.NotNull;
import org.openrewrite.maven.utilities.MavenArtifactDownloader;
import org.springframework.core.io.Resource;
import org.springframework.rewrite.parsers.MavenProject;
import org.springframework.rewrite.parsers.ParserContext;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.rewrite.utils.ResourceUtil;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -60,7 +63,7 @@ public class MavenProjectAnalyzer {
}
Resource rootPom = allPomFiles.stream()
.filter(r -> ResourceUtil.getPath(r).toString().equals(baseDir.resolve(POM_XML).normalize().toString()))
.filter(r -> LinuxWindowsPathUnifier.pathEquals(r, baseDir.resolve(POM_XML)))
.findFirst()
.orElseThrow(
() -> new IllegalArgumentException("The provided resources do not contain a root 'pom.xml' file."));
@@ -78,12 +81,14 @@ public class MavenProjectAnalyzer {
private List<MavenProject> map(Path baseDir, List<Resource> resources, List<Model> sortedModels) {
List<MavenProject> mavenProjects = new ArrayList<>();
sortedModels.stream().filter(Objects::nonNull).forEach(m -> {
String projectDir = baseDir.resolve(m.getProjectDirectory().toString()).normalize().toString();
String projectDir = LinuxWindowsPathUnifier
.unifiedPathString(baseDir.resolve(m.getProjectDirectory().toPath()).normalize());
List<Resource> filteredResources = resources.stream()
.filter(r -> ResourceUtil.getPath(r).toString().startsWith(projectDir))
.filter(r -> LinuxWindowsPathUnifier.unifiedPathString(r).startsWith(projectDir))
.toList();
mavenProjects
.add(new MavenProject(baseDir, m.getResource(), m, rewriteMavenArtifactDownloader, filteredResources));
MavenProject mavenProject = new MavenProject(baseDir, m.getResource(), m, rewriteMavenArtifactDownloader,
filteredResources);
mavenProjects.add(mavenProject);
});
// set all non parent poms as collected projects for root parent pom
List<MavenProject> collected = new ArrayList<>(mavenProjects);
@@ -108,15 +113,8 @@ public class MavenProjectAnalyzer {
String modulePathSegment = path == null ? moduleName : path + "/" + moduleName;
allPomFiles.stream().filter(resource -> {
String modulePath = baseDir.resolve(modulePathSegment)
.resolve(POM_XML)
.toAbsolutePath()
.normalize()
.toString();
String resourcePath = ResourceUtil.getPath(resource).toAbsolutePath().normalize().toString();
return resourcePath.equals(modulePath);
})
allPomFiles.stream()
.filter(getResourcePredicate(baseDir, modulePathSegment))
.map(Model::new)
.forEach(m -> recursivelyFindReactorModules(baseDir, modulePathSegment, reactorModels, allPomFiles, m)
.stream());
@@ -124,6 +122,16 @@ public class MavenProjectAnalyzer {
return reactorModels;
}
@NotNull
private static Predicate<Resource> getResourcePredicate(Path baseDir, String modulePathSegment) {
return resource -> {
Path pomPath = baseDir.resolve(modulePathSegment).resolve(POM_XML).toAbsolutePath().normalize();
String modulePath = LinuxWindowsPathUnifier.unifiedPathString(pomPath);
Path resourcePath = ResourceUtil.getPath(resource).toAbsolutePath().normalize();
return LinuxWindowsPathUnifier.pathEquals(resourcePath, modulePath);
};
}
public List<Model> sortModels(List<Model> reactorModels) {
List<Model> sortedModels = new ArrayList<>();
Map<String, Model> gaToModelMap = reactorModels.stream().collect(Collectors.toMap(m -> {

View File

@@ -22,6 +22,7 @@ import org.openrewrite.maven.MavenSettings;
import org.openrewrite.maven.internal.RawRepositories;
import org.openrewrite.maven.tree.MavenRepository;
import org.springframework.rewrite.scopes.ProjectMetadata;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.stereotype.Component;
import java.nio.file.Files;
@@ -50,9 +51,10 @@ public class MavenSettingsInitializer {
}
public void initializeMavenSettings() {
Path userHome = Path.of(System.getProperty("user.home"));
Path userHome = Path.of(System.getProperty("user.home")).toAbsolutePath().normalize();
String m2RepoPath = userHome.resolve(".m2/repository").toAbsolutePath().normalize() + "/";
String repo = "file://" + m2RepoPath;
String unifiedM2RepoPath = LinuxWindowsPathUnifier.unifiedPathString(m2RepoPath);
String repo = "file://" + unifiedM2RepoPath;
Path mavenSettingsFile = userHome.resolve(".m2/settings.xml");
Path mavenSecuritySettingsFile = userHome.resolve(".m2/settings-security.xml");
@@ -62,7 +64,7 @@ public class MavenSettingsInitializer {
MavenSettings.@Nullable ActiveProfiles activeProfiles = new MavenSettings.ActiveProfiles(List.of("default"));
MavenSettings.@Nullable Mirrors mirrors = new MavenSettings.Mirrors();
MavenSettings.Servers servers = new MavenSettings.Servers();
MavenSettings mavenSettings = new MavenSettings(m2RepoPath, mavenRepository, profiles, activeProfiles, mirrors,
MavenSettings mavenSettings = new MavenSettings(repo, mavenRepository, profiles, activeProfiles, mirrors,
servers);
// TODO: Add support for global Maven settings (${maven.home}/conf/settings.xml).

View File

@@ -18,6 +18,7 @@ package org.springframework.rewrite.parsers.maven;
import org.openrewrite.marker.Marker;
import org.springframework.core.io.Resource;
import org.springframework.rewrite.parsers.ParserContext;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.rewrite.utils.ResourceUtil;
import java.nio.file.Path;

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.rewrite.utils;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import java.nio.file.Path;
@@ -26,11 +27,26 @@ import java.nio.file.Path;
*/
public class LinuxWindowsPathUnifier {
public String unifyPath(Path path) {
return unifyPath(path.toString());
public static Path relativize(Path subpath, Path path) {
LinuxWindowsPathUnifier linuxWindowsPathUnifier = new LinuxWindowsPathUnifier();
String unifiedAbsoluteRootPath = linuxWindowsPathUnifier.unifiedPathString(subpath);
String pathUnified = linuxWindowsPathUnifier.unifiedPathString(path);
return Path.of(unifiedAbsoluteRootPath).relativize(Path.of(pathUnified));
}
public String unifyPath(String path) {
public static String unifiedPathString(Path path) {
return unifiedPathString(path.toString());
}
public static Path unifiedPath(Path path) {
return Path.of(unifiedPathString(path));
}
public static String unifiedPathString(Resource r) {
return unifiedPathString(ResourceUtil.getPath(r));
}
public static String unifiedPathString(String path) {
path = StringUtils.cleanPath(path);
if (isWindows()) {
path = transformToLinuxPath(path);
@@ -38,12 +54,32 @@ public class LinuxWindowsPathUnifier {
return path;
}
boolean isWindows() {
public static Path unifiedPath(String path) {
return Path.of(unifiedPathString(path));
}
static boolean isWindows() {
return System.getProperty("os.name").contains("Windows");
}
private String transformToLinuxPath(String path) {
private static String transformToLinuxPath(String path) {
return path.replaceAll("^[\\w]+:\\/?", "/");
}
public static boolean pathEquals(Resource r, Path path) {
return unifiedPathString(ResourceUtil.getPath(r)).equals(unifiedPathString(path.normalize()));
}
public static boolean pathEquals(Path basedir, String parentPomPath) {
return unifiedPathString(basedir).equals(parentPomPath);
}
public static boolean pathEquals(Path path1, Path path2) {
return unifiedPathString(path1).equals(unifiedPathString(path2));
}
public static boolean pathStartsWith(Resource r, Path path) {
return ResourceUtil.getPath(r).toString().startsWith(unifiedPathString(path));
}
}

View File

@@ -48,7 +48,7 @@ public class OsAgnosticPathMatcher implements PathMatcher {
}
private String unifyPath(String path) {
return pathUnifier.unifyPath(path);
return pathUnifier.unifiedPathString(path);
}
@Override

View File

@@ -31,6 +31,7 @@ import org.springframework.rewrite.parsers.RewriteProjectParser;
import org.springframework.rewrite.parsers.RewriteProjectParsingResult;
import org.springframework.rewrite.test.util.DummyResource;
import org.springframework.rewrite.test.util.TestProjectHelper;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import java.nio.file.Path;
import java.util.List;
@@ -100,7 +101,7 @@ public class CalculateClasspathTest {
}
""";
Path baseDir = tmpDir.resolve("/example-1").toAbsolutePath().normalize();
Path baseDir = LinuxWindowsPathUnifier.unifiedPath(tmpDir.resolve("/example-1").toAbsolutePath().normalize());
List<Resource> resources = List.of(new DummyResource(baseDir.resolve("pom.xml"), pom),
new DummyResource(baseDir.resolve("src/main/java/com/example/MainClass.java"), mainClass),
new DummyResource(baseDir.resolve("src/test/java/com/example/TestClass.java"), testClass));
@@ -109,13 +110,16 @@ public class CalculateClasspathTest {
// verify types in use
SourceFile mainSourceFile = parsingResult.sourceFiles().get(1);
assertThat(mainSourceFile).isInstanceOf(J.CompilationUnit.class);
J.CompilationUnit mainCu = (J.CompilationUnit) mainSourceFile;
// Having Min annotation resolved proves type resolution is working for main
// resources
assertThat(mainCu.getTypesInUse().getTypesInUse().stream().map(t -> t.toString()))
.containsExactlyInAnyOrder("int", "String", "javax.validation.constraints.Min");
SourceFile testSourceFile = parsingResult.sourceFiles().get(2);
assertThat(testSourceFile).isInstanceOf(J.CompilationUnit.class);
J.CompilationUnit testCu = (J.CompilationUnit) testSourceFile;
// Having Test annotation resolved proves type resolution is working for test
// resources

View File

@@ -154,10 +154,20 @@ class BuildFileParserTest {
Path module1SubmodulePomPath = baseDir.resolve(module1SubmoduleSourcePath);
Path parentPomPath = baseDir.resolve(parentSourcePath);
Path module1PomXml = baseDir.resolve(module1SourcePath);
Map<Path, List<Marker>> provenanceMarkers = Map.of(parentPomPath,
List.of(new JavaProject(UUID.randomUUID(), "parent", null)), module1PomXml,
List.of(new JavaProject(UUID.randomUUID(), "module1", null)), module1SubmodulePomPath,
List.of(new JavaProject(UUID.randomUUID(), "module1/submodule", null)));
// @formatter:off
Map<Path, List<Marker>> provenanceMarkers = Map.of(
parentPomPath, List.of(
new JavaProject(UUID.randomUUID(), "parent", null)
),
module1PomXml, List.of(
new JavaProject(UUID.randomUUID(), "module1", null)
),
module1SubmodulePomPath, List.of(
new JavaProject(UUID.randomUUID(), "module1/submodule", null)
)
);
// @formatter:on
ExecutionContext executionContext = new InMemoryExecutionContext(t -> t.printStackTrace());
boolean skipMavenParsing = false;
@@ -196,14 +206,14 @@ class BuildFileParserTest {
@DisplayName("parse with non-pom resources provided should throw exception")
void parseWithNonPomResourcesProvidedShouldThrowException() {
Path baseDir = Path.of(".").toAbsolutePath().normalize();
Resource nonPomResource = new DummyResource(baseDir, "src/main/java/SomeClass.java",
"public class SomeClass {}");
Path someClassPath = baseDir.resolve("src/main/java/SomeClass.java");
Resource nonPomResource = new DummyResource(baseDir, someClassPath.toString(), "public class SomeClass {}");
List<Resource> nonPomResource1 = List.of(nonPomResource);
String message = assertThrows(IllegalArgumentException.class, () -> sut.parseBuildFiles(baseDir,
nonPomResource1, List.of(), new InMemoryExecutionContext(), false, Map.of()))
.getMessage();
assertThat(message).isEqualTo("Provided resources which are not Maven build files: '[" + baseDir
+ "/src/main/java/SomeClass.java]'");
assertThat(message)
.isEqualTo("Provided resources which are not Maven build files: '[" + someClassPath + "]'");
}
@Test
@@ -213,20 +223,25 @@ class BuildFileParserTest {
Path pom1Path = baseDir.resolve("pom.xml");
Resource pom1 = new DummyResource(pom1Path, "");
Path pom2Path = baseDir.resolve("module1/pom.xml");
Resource pom2 = new DummyResource(pom2Path, "");
List<Resource> poms = List.of(pom1, pom2);
Map<Path, List<Marker>> provenanceMarkers = Map.of(pom1Path,
List.of(new JavaProject(UUID.randomUUID(), "pom.xml", null))
// no marker for module1/pom.xml
// @formatter:off
Map<Path, List<Marker>> provenanceMarkers = Map.of(
pom1Path, List.of(new JavaProject(UUID.randomUUID(), "pom.xml", null))
// no marker for module1/pom.xml
);
String message = assertThrows(IllegalArgumentException.class, () -> sut.parseBuildFiles(baseDir, poms,
List.of(), new InMemoryExecutionContext(), false, provenanceMarkers))
String message = assertThrows(
IllegalArgumentException.class,
() -> sut.parseBuildFiles(baseDir, poms, List.of(), new InMemoryExecutionContext(), false, provenanceMarkers)
)
.getMessage();
assertThat(message).isEqualTo("No provenance marker provided for these pom files ["
+ Path.of(".").toAbsolutePath().normalize().resolve("module1/pom.xml]"));
// @formatter:on
assertThat(message).isEqualTo("No provenance marker provided for these pom files [" + pom2Path + "]");
}
}

View File

@@ -26,6 +26,7 @@ import org.springframework.core.io.Resource;
import org.springframework.rewrite.parsers.events.FinishedParsingResourceEvent;
import org.springframework.rewrite.parsers.events.StartedParsingProjectEvent;
import org.springframework.rewrite.parsers.events.SuccessfullyParsedProjectEvent;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -53,7 +54,7 @@ public class ParserEventPublicationIntegrationTest {
@Autowired
ExecutionContext executionContext;
private static List<FinishedParsingResourceEvent> capturedEvents = new ArrayList<>();
private static List<String> capturedEvents = new ArrayList<>();
private static StartedParsingProjectEvent startedParsingEvent;
@@ -69,19 +70,19 @@ public class ParserEventPublicationIntegrationTest {
RewriteProjectParsingResult parsingResult = sut.parse(baseDir, resources);
assertThat(parsingResult.sourceFiles()).hasSize(5);
assertThat(parsingResult.sourceFiles().stream().map(s -> s.getSourcePath().toString()).toList())
.containsExactly("pom.xml", "module-b/pom.xml", "module-a/pom.xml",
assertThat(parsingResult.sourceFiles()
.stream()
.map(s -> LinuxWindowsPathUnifier.unifiedPathString(s.getSourcePath()))
.toList()).containsExactly("pom.xml", "module-b/pom.xml", "module-a/pom.xml",
"module-b/src/test/resources/application.yaml", "module-a/src/main/java/com/acme/SomeClass.java");
assertThat(capturedEvents).hasSize(5);
assertThat(capturedEvents.get(0).sourceFile().getSourcePath().toString()).isEqualTo("pom.xml");
assertThat(capturedEvents.get(1).sourceFile().getSourcePath().toString()).isEqualTo("module-b/pom.xml");
assertThat(capturedEvents.get(2).sourceFile().getSourcePath().toString()).isEqualTo("module-a/pom.xml");
assertThat(capturedEvents.get(3).sourceFile().getSourcePath().toString())
.isEqualTo("module-b/src/test/resources/application.yaml");
assertThat(capturedEvents.get(4).sourceFile().getSourcePath().toString())
.isEqualTo("module-a/src/main/java/com/acme/SomeClass.java");
assertThat(capturedEvents.get(0)).isEqualTo("pom.xml");
assertThat(capturedEvents.get(1)).isEqualTo("module-b/pom.xml");
assertThat(capturedEvents.get(2)).isEqualTo("module-a/pom.xml");
assertThat(capturedEvents.get(3)).isEqualTo("module-b/src/test/resources/application.yaml");
assertThat(capturedEvents.get(4)).isEqualTo("module-a/src/main/java/com/acme/SomeClass.java");
// ResourceParser not firing events
// TODO: reactivate after
// https://github.com/openrewrite/rewrite-maven-plugin/issues/622
@@ -99,7 +100,8 @@ public class ParserEventPublicationIntegrationTest {
@EventListener(FinishedParsingResourceEvent.class)
public void onEvent(FinishedParsingResourceEvent event) {
capturedEvents.add(event);
String unifiedPathString = LinuxWindowsPathUnifier.unifiedPathString(event.sourceFile().getSourcePath());
capturedEvents.add(unifiedPathString);
}
@EventListener(StartedParsingProjectEvent.class)

View File

@@ -17,6 +17,9 @@ package org.springframework.rewrite.parsers;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junitpioneer.jupiter.Issue;
import org.openrewrite.java.tree.J;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -33,6 +36,8 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Fabian Krüger
*/
@DisabledOnOs(value = OS.WINDOWS, disabledReason = "The repository URIs of dependencies differ.")
@Issue("https://github.com/spring-projects/spring-rewrite-commons/issues/12")
@SpringBootTest(classes = { SbmSupportRewriteConfiguration.class, SbmTestConfiguration.class })
public class RewriteProjectParserIntegrationTest {

View File

@@ -20,6 +20,8 @@ import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.io.TempDir;
import org.junitpioneer.jupiter.Issue;
import org.openrewrite.ExecutionContext;
@@ -55,6 +57,8 @@ import static org.assertj.core.api.AssertionsForClassTypes.fail;
*
* @author Fabian Krüger
*/
@DisabledOnOs(value = OS.WINDOWS, disabledReason = "The repository URIs of dependencies differ.")
@Issue("https://github.com/spring-projects/spring-rewrite-commons/issues/12")
class RewriteProjectParserParityTest {
@Test
@@ -163,14 +167,14 @@ class RewriteProjectParserParityTest {
.verifyParity((comparingParsingResult, testedParsingResult) -> {
assertThat(
comparingParsingResult.sourceFiles().stream().map(sf -> sf.getSourcePath().toString()).toList())
.contains("checkstyle/rules.xml");
.contains(Path.of("checkstyle/rules.xml").toString());
assertThat(
comparingParsingResult.sourceFiles().stream().map(sf -> sf.getSourcePath().toString()).toList())
.contains("checkstyle/suppressions.xml");
.contains(Path.of("checkstyle/suppressions.xml").toString());
assertThat(testedParsingResult.sourceFiles().stream().map(sf -> sf.getSourcePath().toString()).toList())
.contains("checkstyle/rules.xml");
.contains(Path.of("checkstyle/rules.xml").toString());
assertThat(testedParsingResult.sourceFiles().stream().map(sf -> sf.getSourcePath().toString()).toList())
.contains("checkstyle/suppressions.xml");
.contains(Path.of("checkstyle/suppressions.xml").toString());
});
}

View File

@@ -21,6 +21,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.File;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
class SpringRewritePropertiesTest {
@@ -42,7 +45,7 @@ class SpringRewritePropertiesTest {
@DisplayName("spring.rewrite.pomCacheDirectory")
void defaultPomCacheDirectory() {
assertThat(springRewriteProperties.getPomCacheDirectory())
.isEqualTo(System.getProperty("user.home") + "/.rewrite-cache");
.isEqualTo(Path.of(System.getProperty("user.home")).resolve(".rewrite-cache").toString());
}
@Test

View File

@@ -60,7 +60,7 @@ public class MavenMojoProjectParserFactory {
Collection<String> plainTextMasks, int sizeThresholdMb, boolean runPerSubmodule,
PlexusContainer plexusContainer, MavenSession session) {
try {
Log logger = new Slf4jToMavenLoggerAdapter(LOGGER);
Log logger = new Slf4jToMavenLoggerAdapter(LoggerFactory.getLogger(MavenMojoProjectParser.class));
RuntimeInformation runtimeInformation = plexusContainer.lookup(RuntimeInformation.class);
SettingsDecrypter decrypter = plexusContainer.lookup(SettingsDecrypter.class);

View File

@@ -28,6 +28,7 @@ import org.openrewrite.maven.utilities.MavenArtifactDownloader;
import org.springframework.core.io.Resource;
import org.springframework.rewrite.parsers.MavenProject;
import org.springframework.rewrite.test.util.DummyResource;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import org.springframework.rewrite.utils.ResourceUtil;
import java.io.IOException;
@@ -240,7 +241,7 @@ class MavenProjectAnalyzerTest {
*/
@Test
@DisplayName("reactorBuild")
void reactorBuild() {
void getSortedProjectsWithMultiModule() {
@Language("xml")
String parentPom = """
<?xml version="1.0" encoding="UTF-8"?>
@@ -272,18 +273,45 @@ class MavenProjectAnalyzerTest {
</project>
""";
List<Resource> resources = List.of(new DummyResource(Path.of("pom.xml"), parentPom),
new DummyResource(Path.of("example/pom.xml"), modulePom));
String javaSource = """
package com.example;
public class MainSource {
List<MavenProject> sortedProjects = sut.getSortedProjects(Path.of(".").toAbsolutePath(), resources);
}
""";
Path baseDir = Path.of(".").toAbsolutePath().normalize();
Path exampleModuleDir = baseDir.resolve("example");
// @formatter:off
List<Resource> resources = List.of(
new DummyResource(baseDir.resolve("pom.xml"), parentPom),
new DummyResource(exampleModuleDir.resolve("pom.xml"), modulePom),
new DummyResource(exampleModuleDir.resolve("src/main/java/com/acme/MainSource.java"), javaSource),
new DummyResource(exampleModuleDir.resolve("src/test/java/com/acme/MainSourceTest.java"), javaSource)
);
// @formatter:on
List<MavenProject> sortedProjects = sut.getSortedProjects(baseDir, resources);
assertThat(sortedProjects).hasSize(2);
String parentPomPath = Path.of(".").toAbsolutePath().normalize().toString();
assertThat(sortedProjects.get(0).getBasedir().toString()).isEqualTo(parentPomPath);
MavenProject parentProject = sortedProjects.get(0);
MavenProject exampleProject = sortedProjects.get(1);
assertThat(LinuxWindowsPathUnifier.pathEquals(baseDir.normalize(), parentProject.getBasedir())).isTrue();
assertThat(LinuxWindowsPathUnifier.pathEquals(exampleProject.getBasedir(),
Path.of(".").resolve("example").toAbsolutePath().normalize()));
assertThat(exampleProject.getMainJavaSources()).hasSize(1);
assertThat(LinuxWindowsPathUnifier
.unifiedPathString(ResourceUtil.getPath(exampleProject.getMainJavaSources().get(0)))
.endsWith("src/main/java/com/acme/MainSource.java"));
assertThat(exampleProject.getTestJavaSources()).hasSize(1);
assertThat(LinuxWindowsPathUnifier
.unifiedPathString(ResourceUtil.getPath(exampleProject.getMainJavaSources().get(0)))
.endsWith("src/test/java/com/acme/MainSourceTest.java"));
String modulePomPath = Path.of(".").resolve("example").toAbsolutePath().normalize().toString();
assertThat(sortedProjects.get(1).getBasedir().toString()).isEqualTo(modulePomPath);
}
/**
@@ -345,10 +373,10 @@ class MavenProjectAnalyzerTest {
assertThat(sortedProjects).hasSize(2);
String parentPomPath = Path.of(".").toAbsolutePath().normalize().toString();
assertThat(sortedProjects.get(0).getBasedir().toString()).isEqualTo(parentPomPath);
assertThat(LinuxWindowsPathUnifier.pathEquals(sortedProjects.get(0).getBasedir(), parentPomPath));
String modulePomPath = Path.of(".").resolve("example").toAbsolutePath().normalize().toString();
assertThat(sortedProjects.get(1).getBasedir().toString()).isEqualTo(modulePomPath);
assertThat(LinuxWindowsPathUnifier.pathEquals(sortedProjects.get(1).getBasedir(), modulePomPath));
}
/**
@@ -416,11 +444,12 @@ class MavenProjectAnalyzerTest {
assertThat(sortedProjects).hasSize(2);
String parentPomPath = Path.of(".").toAbsolutePath().normalize().toString();
assertThat(sortedProjects.get(0).getBasedir().toString()).isEqualTo(parentPomPath);
String parentPomPath = LinuxWindowsPathUnifier.unifiedPathString(Path.of(".").toAbsolutePath().normalize());
assertThat(LinuxWindowsPathUnifier.pathEquals(sortedProjects.get(0).getBasedir(), parentPomPath)).isTrue();
String modulePomPath = Path.of(".").resolve("example").toAbsolutePath().normalize().toString();
assertThat(sortedProjects.get(1).getBasedir().toString()).isEqualTo(modulePomPath);
String modulePomPath = LinuxWindowsPathUnifier
.unifiedPathString(Path.of(".").resolve("example").toAbsolutePath().normalize());
assertThat(LinuxWindowsPathUnifier.pathEquals(sortedProjects.get(1).getBasedir(), modulePomPath)).isTrue();
}
/**

View File

@@ -23,6 +23,7 @@ import org.openrewrite.maven.tree.MavenRepository;
import org.sonatype.plexus.components.cipher.PlexusCipherException;
import org.springframework.rewrite.parsers.RewriteExecutionContext;
import org.springframework.rewrite.scopes.ProjectMetadata;
import org.springframework.rewrite.utils.LinuxWindowsPathUnifier;
import java.net.URISyntaxException;
import java.nio.file.Path;
@@ -57,13 +58,10 @@ class MavenSettingsInitializerTest {
MavenRepository localRepository = mavenExecutionContextView.getLocalRepository();
assertThat(localRepository.getSnapshots()).isNull();
String tmpDir = removeTrailingSlash(System.getProperty("java.io.tmpdir"));
String customLocalRepository = "file://" + Path.of(System.getProperty("user.home"))
.resolve(".m2/repository")
.toAbsolutePath()
.normalize()
.toString();// new URI("file://" + tmpDir).toString();
assertThat(removeTrailingSlash(localRepository.getUri())).isEqualTo(customLocalRepository);
String expectedCustomLocalRepository = "file://" + LinuxWindowsPathUnifier.unifiedPathString(
Path.of(System.getProperty("user.home")).resolve(".m2/repository").toAbsolutePath().normalize());
assertThat(removeTrailingSlash(localRepository.getUri())).isEqualTo(expectedCustomLocalRepository);
assertThat(localRepository.getSnapshots()).isNull();
assertThat(localRepository.isKnownToExist()).isTrue();
assertThat(localRepository.getUsername()).isNull();

View File

@@ -15,6 +15,10 @@
*/
package org.springframework.rewrite.test.util;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.assertj.core.api.SoftAssertions;
import org.jetbrains.annotations.NotNull;
import org.openrewrite.ExecutionContext;
@@ -30,8 +34,8 @@ import org.openrewrite.style.Style;
import org.springframework.rewrite.parsers.SpringRewriteProperties;
import org.springframework.rewrite.parsers.RewriteProjectParsingResult;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.*;
import java.util.function.BiConsumer;
@@ -97,6 +101,8 @@ public class ParserParityTestHelper {
RewriteProjectParsingResult expectedParserResult = null;
RewriteProjectParsingResult actualParserResult = null;
resolveDependencies();
ParserExecutionHelper parserExecutionHelper = new ParserExecutionHelper();
if (isParallelParse) {
ParallelParsingResult result = parserExecutionHelper.parseParallel(baseDir, springRewriteProperties,
@@ -116,6 +122,39 @@ public class ParserParityTestHelper {
customParserResultParityChecker.accept(actualParserResult, expectedParserResult);
}
private void resolveDependencies() {
try {
DefaultInvoker defaultInvoker = new DefaultInvoker();
InvocationRequest request = new DefaultInvocationRequest();
request.setGoals(List.of("clean", "test-compile"));
request.setBaseDirectory(baseDir.toFile());
// request.setBatchMode(true);
request.setPomFile(baseDir.resolve("pom.xml").toFile());
String mavenHome = "";
if (System.getenv("MAVEN_HOME") != null) {
mavenHome = System.getenv("MAVEN_HOME");
}
else if (System.getenv("MVN_HOME") != null) {
mavenHome = System.getenv("MVN_HOME");
}
else if (System.getenv("M2_HOME") != null) {
mavenHome = System.getenv("M2_HOME");
}
else {
throw new IllegalStateException("Neither MVN_HOME nor MAVEN_HOME set but required by MavenInvoker.");
}
System.out.println("Using Maven %s".formatted(mavenHome));
request.setMavenHome(new File(mavenHome));
defaultInvoker.execute(request);
}
catch (MavenInvocationException e) {
throw new RuntimeException(e);
}
}
public interface CustomParserResultParityChecker
extends BiConsumer<RewriteProjectParsingResult, RewriteProjectParsingResult> {
@@ -280,7 +319,7 @@ public class ParserParityTestHelper {
.ignoringFields("modules", // checked further down
"dependencies", // checked further down
"parent.modules" // TODO:
// https://github.com/spring-projects-experimental/spring-boot-migrator/issues/991
// https://github.com/spring-projects-experimental/spring-boot-migrator/issues/991
)
.ignoringFieldsOfTypes(UUID.class)
.isEqualTo(expected);
@@ -363,20 +402,18 @@ public class ParserParityTestHelper {
&& f1.getFragment().equals(f2.getFragment());
}
else if (actual instanceof String) {
try {
URI f1 = new URI((String) actual);
URI f2 = new URI((String) expected);
return f1.getScheme() == null ? (f2.getScheme() == null ? true : false)
: f1.getScheme().equals(f2.getScheme())
&& (f1.getHost() == null ? (f2.getHost() == null ? true : false)
: f1.getHost().equals(f2.getHost()))
&& f1.getPath().equals(f2.getPath()) && f1.getFragment() == null
? (f2.getFragment() == null ? true : false)
: f1.getFragment().equals(f2.getFragment());
}
catch (URISyntaxException e) {
throw new RuntimeException(e);
}
URI f1 = new File((String) actual).toURI();
URI f2 = new File((String) expected).toURI();
// @formatter:off
return
f1.getScheme() != null && f2.getScheme() != null ? f1.getScheme().equals(f2.getScheme()) : f1.getScheme() == null && f2.getScheme() == null ? true : false
&&
f1.getHost() != null && f2.getHost() != null ? f1.getHost().equals(f2.getHost()) : f1.getHost() == null && f2.getHost() == null ? true : false
&&
f1.getPath() != null && f2.getPath() != null ? f1.getPath().equals(f2.getPath()) : f1.getPath() == null && f2.getPath() == null ? true : false
&&
f1.getFragment() != null && f2.getFragment() != null ? f1.getFragment().equals(f2.getFragment()) : f1.getFragment() == null && f2.getFragment() == null ? true : false;
// @formatter:on
}
else {
return false;