From 2e819c8160ccc0d5fd2092b89c4c16d2ea429452 Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Tue, 7 Nov 2023 00:44:24 -0800 Subject: [PATCH 1/3] More Windows fixes --- .../sbm/SpringBoot23To24MigrationTest.java | 6 +- .../test/RecipeIntegrationTestSupport.java | 24 +- components/sbm-core/pom.xml | 5 + .../migration/actions/AddMinimalPomXml.java | 3 +- .../actions/DocumentationExtraction.java | 9 +- .../sbm/engine/context/ProjectContext.java | 2 +- .../sbm/project/parser/ResourceParser.java | 7 +- .../project/resource/ProjectResourceSet.java | 51 +- .../sbm/build/Issue54Test.java | 10 +- .../OpenRewriteMavenBuildFileTest.java | 6 +- .../ForgivingParsingOfTestResourcesTest.java | 5 +- .../project/parser/RewriteXmlParserTest.java | 4 +- .../project/resource/TestProjectContext.java | 30 +- components/sbm-openrewrite/pom.xml | 5 + .../sbm/java/OpenRewriteTestSupport.java | 48 +- .../report/SpringBootUpgradeReportAction.java | 19 +- .../SpringBootUpgradeReportSection.java | 68 +- .../ActuatorEndpointsSanitizationHelper.java | 2 +- .../report/helper/BannerSupportHelper.java | 5 - .../helper/ChangesToDataPropertiesHelper.java | 5 - .../CommonsMultipartResolverHelper.java | 5 - .../helper/ConstructorBindingHelper.java | 5 - .../helper/IsSpring27Or30ProjectHelper.java | 4 - .../helper/JohnzonDependencyHelper.java | 5 - .../helper/LoggingDateFormatHelper.java | 5 - .../report/helper/PagingAndSortingHelper.java | 5 - ...MVCAndWebFluxUrlMatchingChangesHelper.java | 15 +- .../UpgradeSpringBootVersionHelper.java | 4 - .../recipes/27_30/report/sbu30-report.yaml | 16 +- ...iptDataSourceInitializationActionTest.java | 50 +- ...pacheSolrRepositorySectionBuilderTest.java | 2 +- .../config/ConfigRecipeTestHelper.java | 16 +- .../SpringBootUpgradeReportTestSupport.java | 66 +- ...ndpointsSanitizationReportSectionTest.java | 30 +- .../BannerSupportReportSectionTest.java | 20 +- .../ConstructorBindingReportSectionTest.java | 8 +- .../helper/PagingAndSortingHelperTest.java | 114 ++- ...ndWebFluxUrlMatchingChangesHelperTest.java | 5 + ...uxUrlMatchingChangesReportSectionTest.java | 50 +- .../sbm/jee/jms/AddJmsConfigTest.java | 226 ++--- .../MigrateEclipseLinkToSpringBootTest.java | 846 +++++++++--------- ...ngBootApplicationPropertiesActionTest.java | 8 +- .../mule/actions/MigrateMulesoftFileTest.java | 8 +- .../MuleToJavaDSLDwlTransformTest.java | 33 +- ...onfigXmlToJavaConfigurationActionTest.java | 194 ++-- ...dantMavenCompilerPluginPropertiesTest.java | 4 +- .../AddSpringBootContextTestClassTest.java | 160 ++-- .../AddSpringBootMainClassActionTest.java | 33 +- ...SpringBeanMethodDeclarationFinderTest.java | 17 +- .../SpringBootApplicationPropertiesTest.java | 4 +- ...plicationPropertiesResourceFilterTest.java | 2 +- pom.xml | 9 +- sbm-support-rewrite/pom.xml | 4 +- 53 files changed, 1135 insertions(+), 1152 deletions(-) diff --git a/components/openrewrite-spring-recipes/src/test/java/org/springframework/sbm/SpringBoot23To24MigrationTest.java b/components/openrewrite-spring-recipes/src/test/java/org/springframework/sbm/SpringBoot23To24MigrationTest.java index 5269b9ad0..090ae61d4 100644 --- a/components/openrewrite-spring-recipes/src/test/java/org/springframework/sbm/SpringBoot23To24MigrationTest.java +++ b/components/openrewrite-spring-recipes/src/test/java/org/springframework/sbm/SpringBoot23To24MigrationTest.java @@ -126,7 +126,7 @@ public void recipeUpdatesBootDependenciesAndParentVersion() throws IOException { sut.apply(projectContext); - assertThat(expectedPom).isEqualTo(projectContext.getBuildFile().print()); + assertThat(expectedPom).isEqualToNormalizingNewlines(projectContext.getBuildFile().print()); SpringBootApplicationProperties applicationProperties = projectContext.search(new SpringBootApplicationPropertiesResourceListFilter()).get(0); assertThat(applicationProperties.hasChanges()).isFalse(); @@ -200,7 +200,7 @@ public void recipeJpaInitPropertyAdded() throws IOException { ); SpringBootApplicationProperties applicationProperties = projectContext.search(new SpringBootApplicationPropertiesResourceListFilter()).get(0); - assertThat(applicationProperties.getProperty("spring.datasource.initialization-order").get()).isEqualTo("after-jpa"); + assertThat(applicationProperties.getProperty("spring.datasource.initialization-order")).hasValue("after-jpa"); verify(ui).askUserYesOrNo(InitDataSourceAfterJpaInitAction.QUESTION); verifyNoMoreInteractions(ui); @@ -218,7 +218,7 @@ public void recipeJpaInitPropertyAddedForSchemaSql() throws IOException { // sut.apply(projectContext); // // SpringBootApplicationProperties applicationProperties = projectContext.getFilteredResources(new SpringBootApplicationPropertiesResourceListFilter()).get(0); -// assertThat(applicationProperties.getProperty("spring.datasource.initialization-order").get()).isEqualTo("after-jpa"); +// assertThat(applicationProperties.getProperty("spring.datasource.initialization-order")).hasValue("after-jpa"); // // verify(ui).askUserYesOrNo(InitDataSourceAfterJpaInitAction.QUESTION); // verifyNoMoreInteractions(ui); diff --git a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java index 3b868ecba..c01356229 100644 --- a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java +++ b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java @@ -34,7 +34,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -50,6 +49,7 @@ public static Path getResultDir(String toDirName) { } private static final String TARGET_DIR = "./target/testcode"; + private static final String TEMPLATES = "./src/main/resources/templates"; @Setter(AccessLevel.PRIVATE) private Path rootDir; @Setter(AccessLevel.PRIVATE) @@ -68,10 +68,10 @@ public static RecipeIntegrationTestSupport withTargetDir(Path targetDir) { public static RecipeIntegrationTestSupport initializeProject(Path sourceDir, String targetDirName) { try { Resource classPathResource = new FileSystemResource(sourceDir.toString()); - File to = getResultDir(targetDirName).toFile(); + File to = getResultDir(targetDirName).toFile().getCanonicalFile(); FileUtils.deleteDirectory(to); FileUtils.forceMkdir(to); - FileUtils.copyDirectory(classPathResource.getFile(), to); + FileUtils.copyDirectory(classPathResource.getFile().getCanonicalFile(), to); RecipeIntegrationTestSupport recipeIntegrationTestSupport = new RecipeIntegrationTestSupport(); recipeIntegrationTestSupport.setRootDir(to.toPath()); recipeIntegrationTestSupport.setSourceDir(sourceDir); @@ -91,9 +91,11 @@ public static RecipeIntegrationTestSupport initializeProject(String targetDirNam public void andApplyRecipe(String recipeName) { SpringBeanProvider.run(ctx -> { - if (new File("./src/main/resources/templates").exists()) { - Configuration configuration = ctx.getBean("configuration", Configuration.class); // FIXME: two freemarker configurations exist - configuration.setDirectoryForTemplateLoading(new File("./src/main/resources/templates")); + Path templatesPath = Path.of(TEMPLATES).normalize().toAbsolutePath(); + if (Files.exists(templatesPath)) { + // FIXME: two freemarker configurations exist + Configuration configuration = ctx.getBean("configuration", Configuration.class); + configuration.setDirectoryForTemplateLoading(templatesPath.toFile().getCanonicalFile()); } ScanCommand scanCommand = ctx.getBean(ScanCommand.class); @@ -108,7 +110,7 @@ public void andApplyRecipe(String recipeName) { Recipe recipe = recipesFound.stream() .filter(r -> r.getName().equals(recipeName)) .findFirst() - .orElseThrow(() -> new RuntimeException("Could not find recipe '" + recipeName + "' in list of recipes found: " + recipesFound)); + .orElseThrow(() -> new RuntimeException("Could not find recipe '%s' in list of recipes found: %s".formatted(recipeName, recipesFound))); ApplyCommand applyCommand = ctx.getBean(ApplyCommand.class); applyCommand.execute(projectContext, recipe.getName()); }, @@ -134,12 +136,12 @@ public void andApplyRecipeComparingWithExpected(String recipeName) { List result; try (Stream walk = Files.walk(expectedProject)) { result = walk.filter(Files::isRegularFile) - .map(f -> expectedProject.relativize(f)) - .collect(Collectors.toList()); + .map(expectedProject::relativize) + .toList(); } - result.stream() - .forEach(r -> assertThat(expectedProject.resolve(r)).hasSameTextualContentAs(migratedProject.resolve(r))); + result.forEach(r -> assertThat(expectedProject.resolve(r).normalize().toAbsolutePath()) + .hasSameTextualContentAs(migratedProject.resolve(r).normalize().toAbsolutePath())); } catch (Exception exception) { throw new RuntimeException(exception); } diff --git a/components/sbm-core/pom.xml b/components/sbm-core/pom.xml index ad5daf447..fe2cb2f5a 100644 --- a/components/sbm-core/pom.xml +++ b/components/sbm-core/pom.xml @@ -172,6 +172,11 @@ jackson-dataformat-xml 2.14.1 + + org.openrewrite + rewrite-test + test + diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/build/migration/actions/AddMinimalPomXml.java b/components/sbm-core/src/main/java/org/springframework/sbm/build/migration/actions/AddMinimalPomXml.java index 0dbf77410..496baa350 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/build/migration/actions/AddMinimalPomXml.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/build/migration/actions/AddMinimalPomXml.java @@ -30,6 +30,7 @@ import org.springframework.sbm.engine.recipe.AbstractAction; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Path; @@ -59,7 +60,7 @@ public class AddMinimalPomXml extends AbstractAction { @Override public void apply(ProjectContext context) { String projectDir = context.getProjectRootDirectory().toString(); - String projectName = projectDir.replace(" ", "-").substring(projectDir.lastIndexOf("/") + 1); + String projectName = projectDir.replace(" ", "-").substring(projectDir.lastIndexOf(File.separator) + 1); Map params = new HashMap<>(); params.put("groupId", "com.example.change"); params.put("artifactId", projectName); diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/common/migration/actions/DocumentationExtraction.java b/components/sbm-core/src/main/java/org/springframework/sbm/common/migration/actions/DocumentationExtraction.java index 94c0a556b..40728845b 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/common/migration/actions/DocumentationExtraction.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/common/migration/actions/DocumentationExtraction.java @@ -23,6 +23,7 @@ import org.springframework.sbm.java.api.Member; import org.springframework.sbm.java.impl.OpenRewriteType; +import java.io.File; import java.nio.file.Path; import java.util.List; @@ -36,7 +37,7 @@ public void apply(ProjectContext context) { Path sourcePath = module.getBaseJavaSourceLocation().getSourceFolder(); Path sourceDir = rootDirectory.relativize(sourcePath); module.getMainJavaSources().stream() - .filter(js -> js.getResource().getAbsolutePath().endsWith(sourceDir.resolve(js.getPackageName().replace(".", "/") + "/" + js.getResource().getAbsolutePath().getFileName()))) + .filter(js -> filterPath(js, sourceDir)) .map(JavaSource::getTypes) .flatMap(List::stream) .filter(t -> OpenRewriteType.class.isAssignableFrom(t.getClass())) @@ -52,6 +53,12 @@ public void apply(ProjectContext context) { } + private static boolean filterPath(JavaSource js, Path sourceDir) { + String packageName = js.getPackageName().replace(".", File.separator); + Path resolved = sourceDir.resolve(packageName).resolve(js.getResource().getAbsolutePath().getFileName()); + return js.getResource().getAbsolutePath().endsWith(resolved); + } + private boolean filterActions(OpenRewriteType javaSource) { Class aClass = getaClass(javaSource); return Action.class.isAssignableFrom(aClass); diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/context/ProjectContext.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/context/ProjectContext.java index 975de0c69..4fa0d1c4c 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/context/ProjectContext.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/context/ProjectContext.java @@ -54,7 +54,7 @@ public class ProjectContext { private final RewriteMigrationResultMerger resultMerger; public ProjectContext(JavaRefactoringFactory javaRefactoringFactory, Path projectRootDirectory, ProjectResourceSet projectResources, BasePackageCalculator basePackageCalculator, JavaParser javaParser, ExecutionContext executionContext, RewriteMigrationResultMerger resultMerger) { - this.projectRootDirectory = projectRootDirectory.toAbsolutePath(); + this.projectRootDirectory = projectRootDirectory.normalize().toAbsolutePath(); this.projectResources = projectResources; this.javaRefactoringFactory = javaRefactoringFactory; this.basePackageCalculator = basePackageCalculator; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ResourceParser.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ResourceParser.java index ae093f58a..a43eaaa35 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ResourceParser.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ResourceParser.java @@ -34,6 +34,7 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.io.Resource; import org.springframework.sbm.engine.events.StartedScanningProjectResourceEvent; +import org.springframework.sbm.utils.LinuxWindowsPathUnifier; import org.springframework.stereotype.Component; import java.io.IOException; @@ -107,7 +108,7 @@ public List parse(Path baseDir, List relevantResources, Li parserAndParserInputMappings.put(plainTextParser, new ArrayList<>()); parserInputs.forEach(r -> { - Parser parser = parserAndParserInputMappings.keySet().stream() + Parser parser = parserAndParserInputMappings.keySet().stream() .filter(p -> p.accept(r)) .findFirst() .orElseThrow(() -> new RuntimeException("Could not find matching parser for " + r.getPath())); @@ -141,7 +142,7 @@ private Stream getSourceFileStream(Path baseDir, ExecutionContext ct .getValue() .stream() .map(resource -> (List) parseSingleResource(baseDir, ctx, e, resource)) - .flatMap(elem -> Stream.ofNullable(elem)) + .flatMap(Stream::ofNullable) .flatMap(List::stream); } @@ -149,7 +150,7 @@ private List parseSingleResource(Path baseDir, ExecutionCo try { return e.getKey().parseInputs(List.of(resource), baseDir, ctx); } catch(Exception ex) { - if(resource.getPath().toString().contains("src/test/resources")) { + if (LinuxWindowsPathUnifier.unifyPath(resource.getPath()).contains("src/test/resources")) { log.error("Could not parse resource '%s' using parser %s. Exception was: %s".formatted(resource.getPath(), e.getKey().getClass().getName(), ex.getMessage())); return null; } else { diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/resource/ProjectResourceSet.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/resource/ProjectResourceSet.java index 4c34c768e..53a1ab1a3 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/resource/ProjectResourceSet.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/resource/ProjectResourceSet.java @@ -19,9 +19,7 @@ import java.nio.file.Path; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.Stream; // TODO: make package private @@ -65,63 +63,18 @@ public int size() { return projectResources.size(); } -// /** -// * @deprecated use {@link ProjectContext#getFilteredResources(ProjectResourcesFilter)} -// * with {@link org.springframework.sbm.project.resource.filter.GenericTypeFilter} -// */ -// @Deprecated(forRemoval = true) -// public List> getProjections(Class projectionClass) { -// return typeFilteredList(projectionClass); -// } - public int indexOf(Path absolutePath) { return projectResources.stream() .map(ProjectResource::getAbsolutePath) - .collect(Collectors.toList()) + .toList() .indexOf(absolutePath); } void clearDeletedResources() { - Iterator> iterator = this.projectResources.iterator(); - while(iterator.hasNext()) { - RewriteSourceFileHolder current = iterator.next(); - if(current.isDeleted()) { - iterator.remove(); - } - } + this.projectResources.removeIf(BaseProjectResource::isDeleted); } public Stream> streamIncludingDeleted() { return projectResources.stream(); } -// -// public Stream filteredStream(ProjectResourceFilter filter) { -// return projectResources.stream() -// .filter(filter::satisfies); -// } - -// public Stream classFilteredStream(Class clazz) { -// return filteredStream(pr -> clazz.isAssignableFrom(pr.getClass())) -// .map(clazz::cast); -// } -// -// public Stream> typeFilteredStream(Class type) { -// return filteredStream(pr -> Objects.nonNull(pr.getType()) && type.isAssignableFrom(pr.getType())) -// .map(pr -> (RewriteSourceFileHolder)pr); -// } -// -// public List filteredList(ProjectResourceFilter filter) { -// return filteredStream(filter) -// .collect(Collectors.toList()); -// } -// -// public List classFilteredList(Class clazz) { -// return classFilteredStream(clazz) -// .collect(Collectors.toList()); -// } -// -// public List> typeFilteredList(Class type) { -// return typeFilteredStream(type) -// .collect(Collectors.toList()); -// } } diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/build/Issue54Test.java b/components/sbm-core/src/test/java/org/springframework/sbm/build/Issue54Test.java index a559cb1b5..fda498354 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/build/Issue54Test.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/build/Issue54Test.java @@ -15,20 +15,16 @@ */ package org.springframework.sbm.build; -import org.assertj.core.api.Assertions; import org.intellij.lang.annotations.Language; import org.junit.jupiter.api.Test; import org.openrewrite.maven.MavenParser; -import org.openrewrite.maven.internal.RawPom; import org.openrewrite.maven.tree.Dependency; import org.openrewrite.maven.tree.MavenResolutionResult; -import org.openrewrite.maven.tree.Pom; import org.openrewrite.xml.tree.Xml; import org.springframework.sbm.GitHubIssue; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.project.resource.TestProjectContext; -import java.io.ByteArrayInputStream; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -83,9 +79,9 @@ void scanMultiModuleProjectWithOptionalPropertyProvidedByParent() { List poms = MavenParser.builder().build().parse(pomA, pomB); - assertThat( - poms.get(1).getMarkers().findFirst(MavenResolutionResult.class).get().getPom().getProperties().get("boolean-variable") - ).isEqualTo("false"); + assertThat(poms.get(1).getMarkers().findFirst(MavenResolutionResult.class)) + .hasValueSatisfying(mrr -> assertThat(mrr.getPom().getProperties()).containsEntry("boolean-variable", "false") + ); List requestedDependencies = poms.get(1).getMarkers().findFirst(MavenResolutionResult.class).get().getPom().getRequestedDependencies(); diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java index 81a9eedea..72fff7378 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java @@ -2134,9 +2134,9 @@ void deserializePluginConfiguration() { plugin.getArtifactId().equals("maven-compiler-plugin")) .findAny().orElseThrow(); - assertThat(compilerPlugin.getConfiguration().getDeclaredStringValue("source").get()).isEqualTo("${source}"); - assertThat(compilerPlugin.getConfiguration().getDeclaredStringValue("target").get()).isEqualTo("17"); - assertThat(compilerPlugin.getConfiguration().getDeclaredStringValue("fork").get()).isEqualTo("false"); + assertThat(compilerPlugin.getConfiguration().getDeclaredStringValue("source")).hasValue("${source}"); + assertThat(compilerPlugin.getConfiguration().getDeclaredStringValue("target")).hasValue("17"); + assertThat(compilerPlugin.getConfiguration().getDeclaredStringValue("fork")).hasValue("false"); } @Test diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ForgivingParsingOfTestResourcesTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ForgivingParsingOfTestResourcesTest.java index d3bb48170..c3d3e3e25 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ForgivingParsingOfTestResourcesTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ForgivingParsingOfTestResourcesTest.java @@ -23,6 +23,7 @@ import org.springframework.sbm.project.resource.RewriteSourceFileHolder; import org.springframework.sbm.project.resource.TestProjectContext; import org.springframework.sbm.test.TestProjectContextInfo; +import org.springframework.sbm.utils.LinuxWindowsPathUnifier; import java.util.List; @@ -53,9 +54,9 @@ void test_renameMe() { List> parsedResources = context.getProjectResources().list(); assertThat(parsedResources).hasSize(3); assertThat(parsedResources.get(0).getSourcePath().toString()).isEqualTo("pom.xml"); - assertThat(parsedResources.get(1).getSourcePath().toString()).isEqualTo("src/test/resources/one.yaml"); + assertThat(LinuxWindowsPathUnifier.unifyPath(parsedResources.get(1).getSourcePath())).isEqualTo("src/test/resources/one.yaml"); // src/test/resources/error.yaml is ignored - assertThat(parsedResources.get(2).getSourcePath().toString()).isEqualTo("src/test/resources/three.yaml"); + assertThat(LinuxWindowsPathUnifier.unifyPath(parsedResources.get(2).getSourcePath())).isEqualTo("src/test/resources/three.yaml"); ParsingExecutionContextView contextView = ParsingExecutionContextView.view(projectContextInfo.executionContext()); assertThat(contextView.getParseFailures()).hasSize(1); assertThat(contextView.getParseFailures().get(0).getText()).isEqualTo(""" diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/RewriteXmlParserTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/RewriteXmlParserTest.java index 65a01dc61..45a65d5bd 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/RewriteXmlParserTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/RewriteXmlParserTest.java @@ -42,7 +42,7 @@ void parse() { String xml = "content"; RewriteSourceFileHolder parse = sut.parse(Path.of(".").toAbsolutePath(), Path.of("some.xml"), xml); assertThat(parse.getSourceFile().getRoot().getName()).isEqualTo("foo"); - assertThat(parse.getSourceFile().getRoot().getValue().get()).isEqualTo("content"); + assertThat(parse.getSourceFile().getRoot().getValue()).hasValue("content"); } @Test @@ -51,7 +51,7 @@ void testParse() { List> rewriteSourceFileHolders = sut.parse(List.of(file), Path.of("./testcode").toAbsolutePath().normalize(), new RewriteExecutionContext()); RewriteSourceFileHolder sourceFileHolder = rewriteSourceFileHolders.get(0); assertThat(sourceFileHolder.getSourceFile().getRoot().getName()).isEqualTo("shiporder"); - assertThat(sourceFileHolder.getSourceFile().getRoot().getChild("orderperson").get().getValue().get()).isEqualTo("John Smith"); + assertThat(sourceFileHolder.getSourceFile().getRoot().getChild("orderperson").get().getValue()).hasValue("John Smith"); } @Test diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java index 99973a6c8..62ab38ff2 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java @@ -17,6 +17,7 @@ import freemarker.template.Configuration; import org.apache.commons.lang3.SystemUtils; +import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NotNull; import org.openrewrite.ExecutionContext; import org.openrewrite.maven.cache.InMemoryMavenPomCache; @@ -337,12 +338,12 @@ public Builder addRegistrar(ProjectResourceWrapper projectResourceWrapper) { * The source Path is 'src/main/java' in the root module and the path inside is calculated from package declaration if it exists. */ @Deprecated - public Builder withJavaSource(String sourceCode) { + public Builder withJavaSource(@Language("java") String sourceCode) { return withJavaSources(sourceCode); } - public Builder withJavaSource(Path sourcePathDir, String sourceCode) { + public Builder withJavaSource(Path sourcePathDir, @Language("java") String sourceCode) { if (sourcePathDir.isAbsolute()) { throw new IllegalArgumentException("Source path must be relative to project root dir."); } @@ -352,11 +353,11 @@ public Builder withJavaSource(Path sourcePathDir, String sourceCode) { return this; } - public Builder withJavaSource(String sourcePath, String sourceCode) { + public Builder withJavaSource(String sourcePath, @Language("java") String sourceCode) { return withJavaSource(Path.of(sourcePath), sourceCode); } - public Builder withJavaSourceInModule(String modulePath, String sourceCode) { + public Builder withJavaSourceInModule(String modulePath, @Language("java") String sourceCode) { Path path = Path.of(modulePath); if (path.isAbsolute()) { throw new IllegalArgumentException("Source path must be relative to project root dir."); @@ -371,7 +372,7 @@ public Builder withJavaSourceInModule(String modulePath, String sourceCode) { * Adds the given Java sources to the list of compiled Java sources. * The source Path is 'src/main/java' in the root module and the path inside is calculated from package declaration if exists. */ - public Builder withJavaSources(String... sourceCodes) { + public Builder withJavaSources(@Language("java") String... sourceCodes) { Arrays.asList(sourceCodes).forEach(sourceCode -> { String fqName = JavaSourceUtil.retrieveFullyQualifiedClassFileName(sourceCode); Path sourcePath = Path.of("src/main/java").resolve(fqName); @@ -386,7 +387,7 @@ public Builder withJavaSources(String... sourceCodes) { * Adds the given Java sources to the list of compiled Java sources. * The source Path is 'src/test/java' in the root module and the path inside is calculated from package declaration if exists. */ - public Builder withJavaTestSources(String... sourceCodes) { + public Builder withJavaTestSources(@Language("java") String... sourceCodes) { Arrays.asList(sourceCodes).forEach(sourceCode -> { String fqName = JavaSourceUtil.retrieveFullyQualifiedClassFileName(sourceCode); Path sourcePath = Path.of("src/test/java").resolve(fqName); @@ -408,18 +409,18 @@ public Builder withBuildFileHavingDependencies(String... dependencyCoordinate) { return this; } - public Builder withMavenRootBuildFileSource(String pomSource) { + public Builder withMavenRootBuildFileSource(@Language("xml") String pomSource) { this.resourcesWithRelativePaths.put(Path.of("pom.xml"), pomSource); return this; } @Deprecated - public Builder withMavenBuildFileSource(Path path, String pomSource) { + public Builder withMavenBuildFileSource(Path path, @Language("xml") String pomSource) { this.withProjectResource(projectRoot.resolve(path).normalize(), pomSource); return this; } - public Builder withMavenBuildFileSource(String sourceDir, String pomSource) { + public Builder withMavenBuildFileSource(String sourceDir, @Language("xml") String pomSource) { Path sourcePath = Path.of(sourceDir); if (!sourceDir.endsWith("pom.xml")) { sourcePath = sourcePath.resolve("pom.xml"); @@ -443,6 +444,7 @@ public Builder withDummyRootBuildFile() { throw new IllegalArgumentException("ProjectContext already contains pom.xml files."); } + @Language("xml") String xml = """ @@ -479,7 +481,10 @@ public ProjectContext serializeProjectContext(Path targetDir) { public ProjectContext build() { verifyValidBuildFileSetup(); + Path pathOfPomXml = Path.of("pom.xml"); + if (!containsAnyPomXml()) { + @Language("xml") String xml = """ @@ -497,7 +502,7 @@ public ProjectContext build() { .replace("{{dependencies}}", getDependenciesSection()) .replace("{{springParentPom}}", getSpringParentPomSection()); - resourcesWithRelativePaths.put(Path.of("pom.xml"), xml); + resourcesWithRelativePaths.put(pathOfPomXml, xml); } @@ -545,9 +550,8 @@ public ProjectContext build() { // replace with mocks if (mockedBuildFile != null) { // TODO: add javadoc. - Path pomPath = Path.of("pom.xml"); - when(mockedBuildFile.getSourcePath()).thenReturn(pomPath); - projectContext.getProjectResources().replace(projectRoot.resolve(pomPath).normalize(), mockedBuildFile); + when(mockedBuildFile.getSourcePath()).thenReturn(pathOfPomXml); + projectContext.getProjectResources().replace(projectRoot.resolve(pathOfPomXml).normalize(), mockedBuildFile); } return projectContext; diff --git a/components/sbm-openrewrite/pom.xml b/components/sbm-openrewrite/pom.xml index a7daaa8e0..f67f80e72 100644 --- a/components/sbm-openrewrite/pom.xml +++ b/components/sbm-openrewrite/pom.xml @@ -104,6 +104,11 @@ spring-boot-starter-test test + + org.openrewrite + rewrite-test + test + diff --git a/components/sbm-openrewrite/src/test/java/org/springframework/sbm/java/OpenRewriteTestSupport.java b/components/sbm-openrewrite/src/test/java/org/springframework/sbm/java/OpenRewriteTestSupport.java index ff9bc94ca..3960674e7 100644 --- a/components/sbm-openrewrite/src/test/java/org/springframework/sbm/java/OpenRewriteTestSupport.java +++ b/components/sbm-openrewrite/src/test/java/org/springframework/sbm/java/OpenRewriteTestSupport.java @@ -15,8 +15,10 @@ */ package org.springframework.sbm.java; +import org.intellij.lang.annotations.Language; import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.openrewrite.*; +import org.openrewrite.test.RewriteTest; import org.springframework.sbm.java.util.JavaSourceUtil; import org.springframework.sbm.testhelper.common.utils.TestDiff; import org.assertj.core.api.Assertions; @@ -42,7 +44,7 @@ public class OpenRewriteTestSupport { * The first class name and package is used to retrieve the file path of the J.CompilationUnit. * * @param classpath entries in artifact:gruopId:version format. - * @param sourceCodes + * @param sourceCodes source code * @return list of J.CompilationUnits */ public static List createCompilationUnitsFromStrings(List classpath, String... sourceCodes) { @@ -61,7 +63,7 @@ public static List createCompilationUnitsFromStrings(List * The first class name and package is used to retrieve the file path of the J.CompilationUnit. * - * @param sourceCodes + * @param sourceCodes source code * @return list of J.CompilationUnits */ public static List createCompilationUnitsFromStrings(String... sourceCodes) { @@ -73,7 +75,7 @@ public static List createCompilationUnitsFromStrings(String.. *

* The first class name and package is used to retrieve the file path of the J.CompilationUnit. * - * @param sourceCode + * @param sourceCode source code * @return the created J.CompilationUnit */ public static J.CompilationUnit createCompilationUnitFromString(String sourceCode) { @@ -112,7 +114,7 @@ public static

void verifyChange(Supplier> v * @param expected source code after applying the visitor * @param classpath required for resolving dependencies to create a CompilationUnit from given */ - public static

void verifyChange(JavaIsoVisitor visitor, String given, String expected, String... classpath) { + public static void verifyChange(JavaIsoVisitor visitor, String given, String expected, String... classpath) { J.CompilationUnit compilationUnit = createCompilationUnit(given, classpath); verifyChange(visitor, compilationUnit, expected); } @@ -133,7 +135,7 @@ public static

void verifyChange(JavaIsoVisitor visitor, St * @param given CompilationUnit the visitor will be applied on * @param expected source code after applying the visitor */ - public static

void verifyChange(JavaIsoVisitor visitor, J.CompilationUnit given, String expected) { + public static void verifyChange(JavaIsoVisitor visitor, J.CompilationUnit given, String expected) { final Collection newChanges = refactor(given, visitor).getResults(); Assertions.assertThat(newChanges.iterator().hasNext()).as("No change was found.").isTrue(); Assertions.assertThat(given.printAll()) @@ -148,7 +150,7 @@ public static

void verifyChange(JavaIsoVisitor visitor, J. /** * Verifies that applying the visitor to given results in expected. *

- * It's does not check that given equals before in the change. + * It does not check that given equals before in the change. * Use this method if you had to create a CompilationUnit, e.g. to define a scope for the tested visitor. * If the visitor is not scoped it is probably easier (and less caller code) * to use @@ -160,7 +162,7 @@ public static

void verifyChange(JavaIsoVisitor visitor, J. * @param given CompilationUnit the visitor will be applied on * @param expected source code after applying the visitor */ - public static

void verifyChangeIgnoringGiven(JavaIsoVisitor visitor, String given, String expected, String... classpath) { + public static void verifyChangeIgnoringGiven(JavaIsoVisitor visitor, String given, String expected, String... classpath) { J.CompilationUnit compilationUnit = createCompilationUnit(given, classpath); final Collection newChanges = refactor(compilationUnit, visitor).getResults(); Assertions.assertThat(newChanges.iterator().hasNext()).as("No change was found.").isTrue(); @@ -176,7 +178,7 @@ public static

void verifyChangeIgnoringGiven(JavaIsoVisitor void verifyNoChange(Supplier> visitor, String given, String... classpath) { + public static void verifyNoChange(Supplier> visitor, String given, String... classpath) { J.CompilationUnit compilationUnit = createCompilationUnit(given, classpath); final Collection newChanges = refactor(compilationUnit, visitor.get()).getResults(); Assertions.assertThat(newChanges).isEmpty(); @@ -189,7 +191,7 @@ public static

void verifyNoChange(Supplier> * @param given the source code to apply the visitor on * @param classpath required to compile the given sourceCode in 'groupId:artifactId:version' format */ - public static

void verifyNoChange(JavaIsoVisitor visitor, String given, String... classpath) { + public static void verifyNoChange(JavaIsoVisitor visitor, String given, String... classpath) { J.CompilationUnit compilationUnit = createCompilationUnit(given, classpath); final Collection newChanges = refactor(compilationUnit, visitor).getResults(); Assertions.assertThat(newChanges).isEmpty(); @@ -201,7 +203,7 @@ public static

void verifyNoChange(JavaIsoVisitor visitor, * @param given sourceCode * @param classpath provided in 'groupId:artifactId:version' format */ - public static J.CompilationUnit createCompilationUnit(String given, String... classpath) { + public static J.CompilationUnit createCompilationUnit(@Language("java") String given, String... classpath) { JavaParser javaParser = getJavaParser(classpath); List compilationUnits = javaParser @@ -241,30 +243,8 @@ public static List getClasspathFiles(String... classpath) { .collect(Collectors.toList()); } - private static

RecipeRun refactor(J.CompilationUnit given, JavaVisitor visitor) { - GenericOpenRewriteTestRecipe> recipe = new GenericOpenRewriteTestRecipe<>(visitor); + private static RecipeRun refactor(J.CompilationUnit given, JavaVisitor visitor) { + Recipe recipe = RewriteTest.toRecipe(() -> visitor); return recipe.run(List.of(given)); } - - /** - * Helper class to avoid circular dependency to the module containing {@code GenericOpenRewriteRecipe} - */ - private static class GenericOpenRewriteTestRecipe> extends Recipe { - - private final V visitor; - - public GenericOpenRewriteTestRecipe(V visitor) { - this.visitor = visitor; - } - - @Override - protected TreeVisitor getVisitor() { - return visitor; - } - - @Override - public String getDisplayName() { - return visitor.getClass().getSimpleName(); - } - } } diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java index 252a28830..b8ebe6e46 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java @@ -38,7 +38,6 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; -import java.util.stream.Stream; /** * Special Action generates a Spring Boot Upgrade report. @@ -117,14 +116,10 @@ public Condition getCondition() { @Override public void apply(ProjectContext context) { - - List renderedSections = new ArrayList<>(); sections.stream() .filter(s -> s.shouldRender(context)) - .forEach(section -> { - renderedSections.add(section.render(context)); - }); + .forEach(section -> renderedSections.add(section.render(context))); Map data = dataProvider.getData(context, sections); String renderedHeader = renderTemplate("header", header, data); @@ -160,15 +155,12 @@ private String renderReport(String renderedHeader, List sections, String } private String renderRunAllRecipesButton() { - - StringBuilder sb = new StringBuilder(); - List recipes = sections .stream() .flatMap(section -> section.getRemediation().getPossibilities().stream()) - .map(p -> p.getRecipe()) + .map(RemediationPossibility::getRecipe) .filter(recipe -> recipe != null && !recipe.isEmpty()) - .collect(Collectors.toList()); + .toList(); String renderedRecipeInputs = IntStream .range(0, recipes.size()) @@ -196,15 +188,12 @@ private String renderRunAllRecipesButton() { } private String renderTemplate(String key, String content, Map data) { - try (StringWriter writer = new StringWriter()) { freemarkerSupport.getStringLoader().putTemplate(key, content); Template report = freemarkerSupport.getConfiguration().getTemplate(key); report.process(data, writer); return writer.toString(); - } catch (IOException e) { - throw new RuntimeException(e); - } catch (TemplateException e) { + } catch (IOException | TemplateException e) { throw new RuntimeException(e); } } diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java index 4c88f35d7..4e0c16206 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java @@ -16,7 +16,6 @@ package org.springframework.sbm.boot.upgrade_27_30.report; import com.fasterxml.jackson.annotation.JsonIgnore; -import freemarker.core.ParseException; import freemarker.template.*; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -24,9 +23,7 @@ import lombok.Setter; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.sbm.build.api.BuildFile; import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.engine.recipe.Condition; import javax.validation.constraints.NotEmpty; import java.io.IOException; @@ -38,8 +35,9 @@ /** * A section in a generated report for Spring Boot 3 upgrade, rendered as Asciidoc from a freemarker template string. - * The {@link Helper} is condition and evaluates if the section should be rendered. - * If the section should be rendered, the {@link Helper} provides the data extracted from {@link ProjectContext} to render the template. + * The {@link SpringBootUpgradeReportSectionHelper Helper} is condition and evaluates if the section should be rendered. + * If the section should be rendered, the {@link SpringBootUpgradeReportSectionHelper Helper} provides the data extracted + * from {@link ProjectContext} to render the template. * * @author Fabian Krüger */ @@ -50,6 +48,8 @@ public class SpringBootUpgradeReportSection { public static final String CHANGE_HEADER = "What Changed"; public static final String AFFECTED = "Why is the application affected"; public static final String REMEDIATION = "Remediation"; + private static final String GITHUB_ISSUE = "**Issue:** https://github.com/spring-projects-experimental/spring-boot-migrator/issues/%1$d[#%1$d^, role=\"ext-link\"] + %n"; + private static final String GITHUB_CONTRIBUTOR = "https://github.com/%1$s[@%1$s^, role=\"ext-link\"]"; private static final String ls = System.lineSeparator(); /** * The spring project(s)/modules this change comes from. @@ -99,8 +99,6 @@ public boolean shouldRender(ProjectContext context) { return helper.evaluate(context); } - - public String render(ProjectContext context) { if (getHelper().evaluate(context)) { Map params = getHelper().getData(); @@ -109,19 +107,12 @@ public String render(ProjectContext context) { String templateContent = buildTemplate(); renderTemplate(params, writer, templateContent); return writer.toString(); - } catch (TemplateException e) { - throw new RuntimeException(e); - } catch (TemplateNotFoundException e) { - throw new RuntimeException(e); - } catch (ParseException e) { - throw new RuntimeException(e); - } catch (MalformedTemplateNameException e) { - throw new RuntimeException(e); - } catch (IOException e) { + } catch (TemplateException | IOException e) { throw new RuntimeException(e); } } - throw new IllegalArgumentException("Could not render Section '"+ getTitle()+"', evaluating the context returned false"); + + throw new IllegalArgumentException("Could not render Section '%s', evaluating the context returned false".formatted(getTitle())); } private void renderTemplate(Map params, StringWriter writer, String templateContent) throws IOException, TemplateException { @@ -160,7 +151,7 @@ private void renderRemediationDescription(StringBuilder sb) { } private void renderRemediationTitle(StringBuilder sb) { - sb.append("==== " + REMEDIATION).append(ls); + sb.append("==== %s%n".formatted(REMEDIATION)); } private void renderAffectedSubSection(StringBuilder sb) { @@ -169,7 +160,7 @@ private void renderAffectedSubSection(StringBuilder sb) { } private void renderAffectedDescription(StringBuilder sb) { - sb.append(getAffected()).append(ls); + sb.append("%s%n".formatted(getAffected())); } private void renderChangeSubSection(StringBuilder sb) { @@ -178,7 +169,7 @@ private void renderChangeSubSection(StringBuilder sb) { } private void renderAffectedTitle(StringBuilder sb) { - sb.append("==== " + AFFECTED).append(ls); + sb.append("==== %s%n".formatted(AFFECTED)); } private void renderChangeDecription(StringBuilder sb) { @@ -195,23 +186,23 @@ private void renderLineBreak(StringBuilder sb) { } void renderGitHubInfo(StringBuilder sb) { - if(gitHubIssue != null) { - sb.append("**Issue:** https://github.com/spring-projects-experimental/spring-boot-migrator/issues/").append(gitHubIssue).append("[#").append(gitHubIssue).append("^, role=\"ext-link\"] ").append(" + ").append(ls); + if (gitHubIssue != null) { + sb.append(GITHUB_ISSUE.formatted(gitHubIssue)); } - if(contributors != null) { + if (contributors != null) { List authors = getAuthors(); sb.append("**Contributors:** "); - String authorsString = authors.stream().map(a -> "https://github.com/" + a.getHandle() + "[@" + a.getHandle() + "^, role=\"ext-link\"]").collect(Collectors.joining(", ")); - sb.append(authorsString).append(" + ").append(ls); + String authorsString = authors.stream().map(a -> GITHUB_CONTRIBUTOR.formatted(a.getHandle())).collect(Collectors.joining(", ")); + sb.append(authorsString).append("%s + %n".formatted(authorsString)); } - if(projects != null){ - String projectsList = projects.stream().collect(Collectors.joining(", ")); - sb.append("**Projects:** ").append(projectsList).append(ls); + if (projects != null) { + String projectsList = String.join(", ", projects); + sb.append("**Projects:** %s%n".formatted(projectsList)); } } private void renderSectionTitle(StringBuilder sb) { - sb.append("=== ").append(title).append(ls); + sb.append("=== %s%n".formatted(title)); } public List getAuthors() { @@ -235,11 +226,11 @@ public List getAuthors() { private String renderRemediation() { StringBuilder sb = new StringBuilder(); - if(remediation.getDescription() != null) { - sb.append(remediation.getDescription()).append(ls); + if (remediation.getDescription() != null) { + sb.append("%s%n".formatted(remediation.getDescription())); } sb.append(ls); - if(remediation.getPossibilities().isEmpty()) { + if (remediation.getPossibilities().isEmpty()) { renderResourcesList(sb, remediation); renderRecipeButton(sb, remediation.getRecipe()); } else { @@ -249,14 +240,13 @@ private String renderRemediation() { } private void renderRemediationPossibility(StringBuilder sb, RemediationPossibility p) { - sb.append("===== ").append(p.getTitle()).append(ls); - sb.append(p.getDescription()).append(ls).append(ls); + sb.append("===== %s%n%s%n%n".formatted(p.getTitle(), p.getDescription())); renderResourcesList(sb, p); renderRecipeButton(sb, p.getRecipe()); } private void renderRecipeButton(StringBuilder sb, String recipe) { - if(recipe != null && !recipe.isEmpty()) { + if (recipe != null && !recipe.isEmpty()) { sb.append(ls).append(ls); /* - """ + """.replace("\n", System.lineSeparator()) ); } } diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/ChangeJavaxPackagesToJakartaTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/ChangeJavaxPackagesToJakartaTest.java index b4d49d011..acab05e8e 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/ChangeJavaxPackagesToJakartaTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/ChangeJavaxPackagesToJakartaTest.java @@ -15,14 +15,15 @@ */ package org.springframework.sbm.boot.upgrade_27_30; +import org.intellij.lang.annotations.Language; import org.junit.jupiter.api.Test; import org.openrewrite.java.ChangePackage; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.java.api.JavaSource; import org.springframework.sbm.project.resource.TestProjectContext; +import org.springframework.sbm.utils.LinuxWindowsPathUnifier; import java.util.List; -import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -31,34 +32,43 @@ public class ChangeJavaxPackagesToJakartaTest { @Test void collectingJavaxPackages() { - String javaClass1 = - "package com.example;\n" + - "import javax.money.MonetaryAmount;\n" + - "public class SomeClass {\n" + - " public MonetaryAmount convertToEntityAttribute() {\n" + - " return null;\n" + - " }\n" + - "}"; - - String javaClass2 = - "package com.example;\n" + - "import javax.persistence.Converter;\n" + - "public class SomeClass2 {\n" + - " public Converter getConverter() {\n" + - " return null;\n" + - " }\n" + - "}"; + @Language("java") + String javaClass1 = """ + package com.example; + import javax.money.MonetaryAmount; + public class SomeClass { + public MonetaryAmount convertToEntityAttribute() { + return null; + } + } + """; + + @Language("java") + String javaClass2 = """ + package com.example; + import javax.persistence.Converter; + public class SomeClass2 { + public Converter getConverter() { + return null; + } + } + """; + + @Language("java") + String javaClass3 = """ + package com.example; + public class NoImports {} + """; + + @Language("java") + String javaClass4 = """ + package com.example; + import java.math.BigDecimal; + public class OtherImports { + private BigDecimal number; + } + """; - String javaClass3 = - "package com.example;\n" + - "public class NoImports {}"; - - String javaClass4 = - "package com.example;\n" + - "import java.math.BigDecimal;\n" + - "public class OtherImports {\n" + - " private BigDecimal number;\n" + - "}"; ProjectContext context = TestProjectContext.buildProjectContext() .withBuildFileHavingDependencies("javax.money:money-api:1.1") .withJavaSource("src/main/java", javaClass1) @@ -67,13 +77,13 @@ void collectingJavaxPackages() { .withJavaSource("src/main/java", javaClass4) .build(); - List matches = context.getProjectJavaSources().asStream() + List matches = context.getProjectJavaSources().stream() .filter(js -> js.hasImportStartingWith("javax.")) - .collect(Collectors.toList()); + .toList(); assertThat(matches).hasSize(2); - assertThat(matches.get(0).getSourcePath().toString()).isEqualTo("src/main/java/com/example/SomeClass.java"); - assertThat(matches.get(1).getSourcePath().toString()).isEqualTo("src/main/java/com/example/SomeClass2.java"); + assertThat(LinuxWindowsPathUnifier.unifyPath(matches.get(0).getSourcePath())).isEqualTo("src/main/java/com/example/SomeClass.java"); + assertThat(LinuxWindowsPathUnifier.unifyPath(matches.get(1).getSourcePath())).isEqualTo("src/main/java/com/example/SomeClass2.java"); matches.forEach(m -> System.out.println(m.getSourcePath())); } diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java index 01f4ea025..63a439e3c 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java @@ -49,7 +49,7 @@ public void rendersBannerSupportInformation() { The scan found banner image files here: * `%1$s` - * `%2%s` + * `%2$s` ==== Remediation diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/ChangesToDataPropertiesReportSectionTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/ChangesToDataPropertiesReportSectionTest.java index e01c42cfe..4d8c12661 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/ChangesToDataPropertiesReportSectionTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/ChangesToDataPropertiesReportSectionTest.java @@ -24,6 +24,8 @@ import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.resource.TestProjectContext; +import java.nio.file.Path; + /** * @author Fabian Krüger @@ -40,6 +42,10 @@ void changesToDataPropertiesSection_renders() { .withProjectResource("src/main/resources/application-another.properties", "spring.data.here=there") .build(); + Path projectRoot = context.getProjectRootDirectory(); + Path props1 = Path.of("src", "main", "resources", "application.properties"); + Path props2 = Path.of("src", "main", "resources", "application-another.properties"); + SpringBootUpgradeReportTestSupport.generatedSection("Changes to Data Properties") .fromProjectContext(context) .shouldRenderAs( @@ -53,16 +59,23 @@ void changesToDataPropertiesSection_renders() { ==== Why is the application affected The scan found properties with `spring.data` prefix but no dependency matching `org.springframework.data:.*`. - * file:///src/main/resources/application.properties[`src/main/resources/application.properties`] + * %s[`%s`] ** `spring.data.foo` - * file:///src/main/resources/application-another.properties[`src/main/resources/application-another.properties`] + * %s[`%s`] ** `spring.data.here` ==== Remediation Either add `spring-data` dependency, rename the property or remove it in case it's not required anymore. - """); + """.formatted( + projectRoot.resolve(props1).toUri(), + props1, + projectRoot.resolve(props2).toUri(), + props2 + + ) + ); } @Test diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringFactoriesHelperTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringFactoriesHelperTest.java index 71c2791ff..ab37a92a5 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringFactoriesHelperTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringFactoriesHelperTest.java @@ -19,6 +19,8 @@ import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.project.resource.TestProjectContext; +import java.nio.file.Path; + import static org.assertj.core.api.Assertions.assertThat; class SpringFactoriesHelperTest { @@ -43,6 +45,9 @@ public void detectsFileWithSpringFactories() { assertThat(sut.getData()).isNotNull(); assertThat(sut.getData().get("files")).hasSize(1); - assertThat(sut.getData().get("files").get(0)).contains("src/main/resources/META-INF/spring.factories"); + + Path actual = context.getProjectRootDirectory().resolve(Path.of("src/main/resources/META-INF/spring.factories")); + Path expected = Path.of(sut.getData().get("files").get(0)); + assertThat(expected).isEqualTo(actual); } } diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java index 218fedf32..8e1e6ed22 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java @@ -165,10 +165,11 @@ public void configurePathMatch(PathMatchConfigurer configurer) { """.formatted( - projectRoot.resolve(restController1Path).toUri(), - restController1Path, + // Note the controller order here, sorted by package / absolute path projectRoot.resolve(restController2Path).toUri(), - restController2Path + restController2Path, + projectRoot.resolve(restController1Path).toUri(), + restController1Path ); SpringBootUpgradeReportTestSupport.generatedSection("Spring MVC and WebFlux URL matching changes") diff --git a/docs/boot-3.0.0-M3-upgrade.adoc b/docs/boot-3.0.0-M3-upgrade.adoc index 500200e68..4d9adac11 100644 --- a/docs/boot-3.0.0-M3-upgrade.adoc +++ b/docs/boot-3.0.0-M3-upgrade.adoc @@ -61,7 +61,7 @@ All variables used in the template must be provided by `getData`. The scan found properties with `spring.data` prefix but no dependency matching `org.springframework.data:.*`. <#list matches as match> <2> - * file://${match.absolutePath}[`${match.relativePath}`] + * ${match.absolutePath.toUri()}[`${match.relativePath}`] <#list match.propertiesFound as property> ** `${property}` @@ -232,7 +232,7 @@ https://github.com/Buzzardo/spring-style-guide/blob/master/spring-style-guide.ad The scan found properties with `spring.data` prefix but no dependency matching `org.springframework.data:.*`. <#list matches as match> - * file://${match.absolutePath}[`${match.relativePath}`] + * ${match.absolutePath.toUri()}[`${match.relativePath}`] <#list match.propertiesFound as property> ** `${property}`