From 6e07263f1abad9591f3b4d23946deedfc8facd79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Mon, 7 Mar 2022 19:05:54 +0100 Subject: [PATCH 01/17] wip - Replace Resource with Spring Resource - Fix dir for PathScanner test - Adds PreconditionCheck --- .../sbm/engine/commands/ScanCommand.java | 2 +- .../sbm/engine/git/GitSupport.java | 17 ++- ...henGitSupportEnabledPreconditionCheck.java | 85 ++++++++++++ .../JavaSourceDirExistsPrecondition.java | 21 +++ .../JavaVersionPreconditionCheck.java | 17 +++ .../MavenBuildFileExistsPrecondition.java | 23 +++ .../precondition/PreconditionCheck.java | 29 ++++ .../precondition/PreconditionCheckResult.java | 11 ++ .../PreconditionVerificationResult.java | 26 ++++ .../precondition/PreconditionVerifier.java | 21 +++ .../project/parser/MavenProjectParser.java | 105 +++++++------- .../parser/ProjectContextInitializer.java | 53 +++---- .../sbm/project/parser/Resource.java | 25 ---- .../BuildFileExistsPreconditionCheckTest.java | 38 +++++ ...itSupportEnabledPreconditionCheckTest.java | 29 ++++ ...aSourceDirExistsPreconditionCheckTest.java | 45 ++++++ .../JavaVersionPreconditionCheckTest.java | 39 ++++++ .../PreconditionCheckVerifierTest.java | 49 +++++++ .../PreconditionVerifierIntegrationTest.java | 131 ++++++++++++++++++ .../sbm/project/parser/PathScannerTest.java | 6 +- .../project/parser/RewriteXmlParserTest.java | 10 +- .../project/resource/TestProjectContext.java | 26 ++-- .../testcode/{ => path-scanner}/.gitignore | 0 .../{ => path-scanner}/lib/dummy-dep.jar | 0 .../{ => path-scanner}/module1/pom.xml | 0 .../main/java/com/example/SomeJavaClass.java | 0 .../module1/src/main/resources/schema.sql | 0 .../module1/src/main/resources/some.html | 0 .../module1/src/main/resources/some.jsp | 0 .../src/main/resources/some.properties | 0 .../module1/src/main/resources/some.txt | 0 .../module1/src/main/resources/some.xhtml | 0 .../module1/src/main/resources/some.xml | 0 .../module1/src/main/resources/some.xsd | 0 .../module1/src/main/resources/some.yaml | 0 .../src/main/webapp/META-INF/some.wsdl | 0 .../module1/src/main/webapp/META-INF/some.xsl | 0 .../src/main/webapp/META-INF/some.xslt | 0 .../{ => path-scanner}/module2/pom.xml | 0 .../src/test/java/com/example/FooTest.java | 0 .../module2/src/test/resources/test.whatever | 0 .../testcode/{ => path-scanner}/pom.xml | 0 42 files changed, 678 insertions(+), 130 deletions(-) create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPrecondition.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPrecondition.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java delete mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/project/parser/Resource.java create mode 100644 components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java create mode 100644 components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java create mode 100644 components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java create mode 100644 components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java create mode 100644 components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java create mode 100644 components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java rename components/sbm-core/testcode/{ => path-scanner}/.gitignore (100%) rename components/sbm-core/testcode/{ => path-scanner}/lib/dummy-dep.jar (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/pom.xml (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/java/com/example/SomeJavaClass.java (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/schema.sql (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.html (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.jsp (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.properties (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.txt (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.xhtml (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.xml (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.xsd (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/resources/some.yaml (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/webapp/META-INF/some.wsdl (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/webapp/META-INF/some.xsl (100%) rename components/sbm-core/testcode/{ => path-scanner}/module1/src/main/webapp/META-INF/some.xslt (100%) rename components/sbm-core/testcode/{ => path-scanner}/module2/pom.xml (100%) rename components/sbm-core/testcode/{ => path-scanner}/module2/src/test/java/com/example/FooTest.java (100%) rename components/sbm-core/testcode/{ => path-scanner}/module2/src/test/resources/test.whatever (100%) rename components/sbm-core/testcode/{ => path-scanner}/pom.xml (100%) diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java index b3170ce82..a78c61e14 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java @@ -15,11 +15,11 @@ */ package org.springframework.sbm.engine.commands; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectRootPathResolver; import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.parser.ProjectContextInitializer; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; import java.nio.file.Path; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java index 71cb6ce60..997186e3d 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java @@ -15,9 +15,6 @@ */ package org.springframework.sbm.engine.git; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.project.resource.ApplicationProperties; -import org.springframework.sbm.project.resource.RepositoryNotFoundException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.jgit.api.*; @@ -26,6 +23,9 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.project.resource.ApplicationProperties; +import org.springframework.sbm.project.resource.RepositoryNotFoundException; import org.springframework.stereotype.Component; import java.io.File; @@ -128,7 +128,7 @@ public Optional getLatestCommit(File repo) { * * @param repo the location of the repo to search for. {@code .git} is added to file location if not contained */ - public static Repository getRepository(File repo) { + public Repository getRepository(File repo) { try { FileRepositoryBuilder builder = new FileRepositoryBuilder(); if (!repo.toString().endsWith(".git")) { @@ -243,6 +243,15 @@ public void commitWhenGitAvailable(ProjectContext context, String appliedRecipeN } } + public static Optional getBranchName(File repo) { + Git git = initGit(repo); + try { + return Optional.of(git.getRepository().getBranch()); + } catch (IOException e) { + return Optional.empty(); + } + } + private List makeRelativeToRoot(List paths, File projectRootDir) { return paths.stream() .map(p -> projectRootDir.toPath().relativize(Path.of(p).toAbsolutePath().normalize())) diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java new file mode 100644 index 000000000..668f4ac66 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java @@ -0,0 +1,85 @@ +package org.springframework.sbm.engine.precondition; + +import lombok.RequiredArgsConstructor; +import org.springframework.core.annotation.Order; +import org.springframework.core.io.Resource; +import org.springframework.sbm.engine.git.Commit; +import org.springframework.sbm.engine.git.GitSupport; +import org.springframework.sbm.project.resource.ApplicationProperties; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; + +import static org.springframework.sbm.engine.precondition.PreconditionCheck.ResultState.FAILED; +import static org.springframework.sbm.engine.precondition.PreconditionCheck.ResultState.PASSED; + +/** + * Checks Git preconditions when {@code sbm.gitSupportEnabled=true}. + * + * Preconditions are + * + * - A .git dir must exist under project root. + * - No uncommitted changes must exist. + * - No untracked resources must exist. + */ +@Order(99) +@Component +@RequiredArgsConstructor +class DoesGitDirExistWhenGitSupportEnabledPreconditionCheck extends PreconditionCheck { + + private final ApplicationProperties applicationProperties; + + private static final String NO_GIT_DIR_EXISTS = "'sbm.gitSupportEnabled' is 'true' but no '.git' dir exists in project dir. Either disable git support or initialize git."; + private static final String HAS_UNCOMMITTED_CHANGES = "'sbm.gitSupportEnabled' is 'true' but uncommitted changes were found. Commit all changes before scan."; + private final String CHECK_PASSED = "'sbm.gitSupportEnabled' is 'true', changes will be committed to branch [%s] after each recipe."; + private final String CHECK_IGNORED = "'sbm.gitSupportEnabled' is 'false', Nothing will be committed."; + private final GitSupport gitSupport; + + @Override + public PreconditionCheckResult verify(Path projectRoot, List projectResources) { + if (applicationProperties.isGitSupportEnabled()) { + if (noGitDirExists(projectRoot)) { + return new PreconditionCheckResult(FAILED, NO_GIT_DIR_EXISTS); + } + else if (hasUncommittedChanges(projectRoot)) { + return new PreconditionCheckResult(FAILED, HAS_UNCOMMITTED_CHANGES); + } else { + return new PreconditionCheckResult(PASSED, String.format(CHECK_PASSED, getBranch(projectRoot))); + } + } + return new PreconditionCheckResult(PASSED, CHECK_IGNORED); + } + + private String getBranch(Path projectRoot) { + File repo = projectRoot.resolve(".git").normalize().toAbsolutePath().toFile(); + Optional branchName = gitSupport.getBranchName(repo); + if (branchName.isPresent()) { + return branchName.get(); + } else { + return "not found!"; + } + } + + private boolean hasUncommittedChanges(Path projectRoot) { + File repo = projectRoot.resolve(".git").normalize().toAbsolutePath().toFile(); + Optional latestCommit = gitSupport.getLatestCommit(repo); + if(latestCommit.isEmpty()) { + return true; + } + return gitSupport.hasUncommittedChangesOrDifferentRevision(repo, latestCommit.get().getHash()); + } + + private boolean noGitDirExists(Path projectRoot) { + Path path = projectRoot.resolve(".git").normalize().toAbsolutePath(); + if (!path.toFile().exists() || !path.toFile().isDirectory()) { + return true; + } + else { + return false; + } + } + +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPrecondition.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPrecondition.java new file mode 100644 index 000000000..9d0e36583 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPrecondition.java @@ -0,0 +1,21 @@ +package org.springframework.sbm.engine.precondition; + +import org.springframework.core.io.Resource; + +import java.nio.file.Path; +import java.util.List; + +class JavaSourceDirExistsPrecondition extends PreconditionCheck { + + private final String JAVA_SRC_DIR = "src/main/java"; + + @Override + public PreconditionCheckResult verify(Path projectRoot, List projectResources) { + if (projectResources.stream() + .noneMatch(r -> projectRoot.relativize(getPath(r)).startsWith(Path.of(JAVA_SRC_DIR).toString()))) { + return new PreconditionCheckResult(ResultState.FAILED, "PreconditionCheck check could not find a '" + JAVA_SRC_DIR + "' dir. This dir is required."); + } + return new PreconditionCheckResult(ResultState.PASSED, "Found required source dir 'src/main/java'."); + } + +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java new file mode 100644 index 000000000..6f9e6cee5 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java @@ -0,0 +1,17 @@ +package org.springframework.sbm.engine.precondition; + +import org.springframework.core.io.Resource; + +import java.nio.file.Path; +import java.util.List; + +class JavaVersionPreconditionCheck extends PreconditionCheck { + @Override + public PreconditionCheckResult verify(Path projectRoot, List projectResources) { + String javaVersion = System.getProperty("java.specification.version"); + if(! "11".equals(javaVersion)) { + return new PreconditionCheckResult(ResultState.WARN, String.format("Java 11 is required. Check found Java %s.", javaVersion)); + } + return new PreconditionCheckResult(ResultState.PASSED, String.format("Required Java version (%s) was found.", javaVersion)); + } +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPrecondition.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPrecondition.java new file mode 100644 index 000000000..5f808a7b1 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPrecondition.java @@ -0,0 +1,23 @@ +package org.springframework.sbm.engine.precondition; + +import org.springframework.core.annotation.Order; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +import java.nio.file.Path; +import java.util.List; + +@Order(1) +@Component +class MavenBuildFileExistsPrecondition extends PreconditionCheck { + + @Override + public PreconditionCheckResult verify(Path projectRoot, List projectResources) { + if(projectResources.stream().noneMatch(r -> "pom.xml".equals(getPath(r).getFileName().toString()))) { + return new PreconditionCheckResult(ResultState.FAILED, "SBM requires a Maven build file. Please provide a minimal pom.xml."); + } else { + return new PreconditionCheckResult(ResultState.PASSED, "Found pom.xml."); + } + } + +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java new file mode 100644 index 000000000..91851c97c --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java @@ -0,0 +1,29 @@ +package org.springframework.sbm.engine.precondition; + + +import org.springframework.core.io.Resource; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +abstract class PreconditionCheck { + + private ResultState resultState; + + public abstract PreconditionCheckResult verify(Path projectRoot, List projectResources); + + public enum ResultState { + WARN, FAILED, PASSED; + } + + + protected Path getPath(Resource r) { + try { + return r.getFile().toPath(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java new file mode 100644 index 000000000..92da2ef74 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java @@ -0,0 +1,11 @@ +package org.springframework.sbm.engine.precondition; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +class PreconditionCheckResult { + private final PreconditionCheck.ResultState state; + private final String message; +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java new file mode 100644 index 000000000..93b955811 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java @@ -0,0 +1,26 @@ +package org.springframework.sbm.engine.precondition; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +public class PreconditionVerificationResult { + @Deprecated + private List messages = new ArrayList<>(); + @Getter + private List results = new ArrayList<>(); + + @Deprecated + public List getMessages() { + return messages; + } + + public void addMessage(String message) { + this.messages.add(message); + } + + public void addResult(PreconditionCheckResult preconditionCheckResult) { + this.results.add(preconditionCheckResult); + } +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java new file mode 100644 index 000000000..467d596d3 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java @@ -0,0 +1,21 @@ +package org.springframework.sbm.engine.precondition; + +import lombok.RequiredArgsConstructor; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +import java.nio.file.Path; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class PreconditionVerifier { + + private final List preconditions; + + public PreconditionVerificationResult verifyPreconditions(Path projectRoot, List projectResources) { + PreconditionVerificationResult result = new PreconditionVerificationResult(); + preconditions.stream().forEach(pc -> result.addResult(pc.verify(projectRoot, projectResources))); + return result; + } +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java index 079c22544..ff26816c2 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java @@ -15,7 +15,6 @@ */ package org.springframework.sbm.project.parser; -import org.springframework.sbm.engine.events.*; import org.openrewrite.ExecutionContext; import org.openrewrite.Parser; import org.openrewrite.SourceFile; @@ -42,6 +41,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.sbm.engine.events.*; import java.io.FileReader; import java.io.IOException; @@ -89,10 +91,10 @@ public List parse(Path projectDirectory, List resources) { List filteredMavenPoms = filterMavenPoms(resources); List inputs = filteredMavenPoms.stream() - .map(r -> new Parser.Input(r.getPath(), + .map(r -> new Parser.Input(getPath(r), () -> { - eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(r.getPath())); - InputStream is = r.getContent(); + eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(getPath(r))); + InputStream is = getInputStream(r); return is; } ) @@ -125,9 +127,9 @@ public List parse(Path projectDirectory, List resources) { List javaSources = getJavaSources(projectDirectory, resources, maven); - List javaSourcesInput = javaSources.stream().map(js -> new Parser.Input(js.getPath(), () -> { - eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(js.getPath())); - InputStream content = js.getContent(); + List javaSourcesInput = javaSources.stream().map(js -> new Parser.Input(getPath(js), () -> { + eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(getPath(js))); + InputStream content = getInputStream(js); return content; })).collect(Collectors.toList()); @@ -143,9 +145,9 @@ public List parse(Path projectDirectory, List resources) { javaParser.setClasspath(testDependencies); List testJavaSources = getTestJavaSources(projectDirectory, resources, maven); - List testJavaSourcesInput = testJavaSources.stream().map(js -> new Parser.Input(js.getPath(), () -> { - eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(js.getPath())); - return js.getContent(); + List testJavaSourcesInput = testJavaSources.stream().map(js -> new Parser.Input(getPath(js), () -> { + eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(getPath(js))); + return getInputStream(js); })).collect(Collectors.toList()); eventPublisher.publishEvent(new StartedScanningProjectResourceSetEvent("Java [test]: '" + maven.getModel().getArtifactId() + "'", testJavaSourcesInput.size())); @@ -163,13 +165,29 @@ public List parse(Path projectDirectory, List resources) { return ListUtils.map(sourceFiles, s -> s.withMarkers(s.getMarkers().addIfAbsent(gitProvenance))); } + private InputStream getInputStream(Resource r) { + try { + return r.getInputStream(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private Path getPath(Resource r) { + try { + return r.getFile().toPath(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private List getWebappResources(Path projectDir, List resources, Maven maven) { if (!"jar".equals(maven.getMavenModel().getPom().getPackaging()) && !"bundle".equals(maven.getMavenModel().getPom().getPackaging())) { return emptyList(); } Path inPath = projectDir.resolve(maven.getSourcePath()).getParent().resolve(Paths.get("src", "main", "webapp")); return resources.stream() - .filter(r -> r.getPath().startsWith(inPath) /* && Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) + .filter(r -> getPath(r).startsWith(inPath) /* && Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) .collect(Collectors.toList()); } @@ -183,14 +201,14 @@ private List getMulesoftResources(Path projectDir, List reso // Path mulePath = projectDir.resolve(maven.getSourcePath()).getParent().resolve(Paths.get("src", "main", "mule")); // Path apiPath = projectDir.resolve(maven.getSourcePath()).getParent().resolve(Paths.get("src", "main", "api")); return resources.stream() - .filter(r -> mulePaths.stream().anyMatch(appPath -> r.getPath().startsWith(appPath.toString())) /* && Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) + .filter(r -> mulePaths.stream().anyMatch(appPath -> getPath(r).startsWith(appPath.toString())) /* && Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) .collect(Collectors.toList()); } - public static List filterMavenPoms(List resources) { + public List filterMavenPoms(List resources) { return resources.stream() - .filter(p -> p.getPath().getFileName().toString().equals("pom.xml") && + .filter(p -> getPath(p).getFileName().toString().equals("pom.xml") && !p.toString().contains("/src/")) .collect(Collectors.toList()); } @@ -201,7 +219,7 @@ public List getJavaSources(Path projectDir, List resources, // } Path inPath = projectDir.resolve(maven.getSourcePath()).getParent().resolve(Paths.get("src", "main", "java")); return resources.stream() - .filter(r -> r.getPath().startsWith(inPath) && r.getPath().toString().endsWith(".java")) + .filter(r -> getPath(r).startsWith(inPath) && getPath(r).toString().endsWith(".java")) .collect(Collectors.toList()); } @@ -211,7 +229,7 @@ public List getTestJavaSources(Path projectDir, List resourc // } Path inPath = projectDir.resolve(maven.getSourcePath()).getParent().resolve(Paths.get("src", "test", "java")); return resources.stream() - .filter(r -> r.getPath().startsWith(inPath) && r.getPath().toString().endsWith(".java")) + .filter(r -> getPath(r).startsWith(inPath) && getPath(r).toString().endsWith(".java")) .collect(Collectors.toList()); } @@ -222,7 +240,7 @@ public List getResources(Path projectDir, List resources, Ma // } Path inPath = projectDir.resolve(maven.getSourcePath()).getParent().resolve(Paths.get("src", "main", "resources")); return resources.stream() - .filter(r -> r.getPath().startsWith(inPath) /* && Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) + .filter(r -> getPath(r).startsWith(inPath) /* && Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) .collect(Collectors.toList()); } @@ -232,29 +250,14 @@ public List getTestResources(Path projectDir, List resources // } Path inPath = projectDir.resolve(maven.getSourcePath()).getParent().resolve(Paths.get("src", "test", "resources")); return resources.stream() - .filter(r -> r.getPath().startsWith(inPath) /*&& Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) + .filter(r -> getPath(r).startsWith(inPath) /*&& Stream.of(".properties", ".xml", ".yml", ".yaml").anyMatch(fe -> r.getPath().toString().endsWith(fe))*/) .collect(Collectors.toList()); } private List mapToResource(List testResources) { + return testResources.stream() - .map(p -> - new Resource() { - @Override - public Path getPath() { - return p; - } - - @Override - public InputStream getContent() { - try { - return Files.newInputStream(p); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - ) + .map(p -> new FileSystemResource(p)) .collect(Collectors.toList()); } @@ -306,10 +309,10 @@ private void parseResources(List resources, Path projectDirectory, Lis XmlParser xmlParser = new XmlParser(); List xmlFiles = resources.stream() - .filter(p -> xmlParser.accept(p.getPath())) - .map(r -> new Parser.Input(r.getPath(), () -> { - eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(r.getPath())); - return r.getContent(); + .filter(p -> xmlParser.accept(getPath(p))) + .map(r -> new Parser.Input(getPath(r), () -> { + eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(getPath(r))); + return getInputStream(r); })) .collect(Collectors.toList()); @@ -329,10 +332,10 @@ private void parseResources(List resources, Path projectDirectory, Lis YamlParser yamlParser = new YamlParser(); List yamlFiles = resources.stream() - .filter(p -> yamlParser.accept(p.getPath())) - .map(r -> new Parser.Input(r.getPath(), () -> { - eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(r.getPath())); - return r.getContent(); + .filter(p -> yamlParser.accept(getPath(p))) + .map(r -> new Parser.Input(getPath(r), () -> { + eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(getPath(r))); + return getInputStream(r); })) .collect(Collectors.toList()); @@ -351,10 +354,10 @@ private void parseResources(List resources, Path projectDirectory, Lis PropertiesParser propertiesParser = new PropertiesParser(); List propertiesFiles = resources.stream() - .filter(p -> propertiesParser.accept(p.getPath())) - .map(r -> new Parser.Input(r.getPath(), () -> { - eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(r.getPath())); - return r.getContent(); + .filter(p -> propertiesParser.accept(getPath(p))) + .map(r -> new Parser.Input(getPath(r), () -> { + eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(getPath(r))); + return getInputStream(r); })) .collect(Collectors.toList()); @@ -374,10 +377,10 @@ private void parseResources(List resources, Path projectDirectory, Lis eventPublisher.publishEvent(new StartedScanningProjectResourceSetEvent("other files", propertiesFiles.size())); List otherFiles = resources.stream() - .filter(p -> !xmlParser.accept(p.getPath()) && !yamlParser.accept(p.getPath()) && !propertiesParser.accept(p.getPath())) - .map(r -> new Parser.Input(r.getPath(), () -> { - eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(r.getPath())); - return r.getContent(); + .filter(p -> !xmlParser.accept(getPath(p)) && !yamlParser.accept(getPath(p)) && !propertiesParser.accept(getPath(p))) + .map(r -> new Parser.Input(getPath(r), () -> { + eventPublisher.publishEvent(new StartedScanningProjectResourceEvent(getPath(r))); + return getInputStream(r); })) .collect(Collectors.toList()); diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java index 2c59479b6..372c32830 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java @@ -15,20 +15,22 @@ */ package org.springframework.sbm.project.parser; -import org.springframework.sbm.engine.git.Commit; -import org.springframework.sbm.engine.git.GitSupport; +import lombok.RequiredArgsConstructor; +import org.openrewrite.SourceFile; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.io.Resource; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectContextFactory; +import org.springframework.sbm.engine.events.ActionLogEvent; +import org.springframework.sbm.engine.git.Commit; +import org.springframework.sbm.engine.git.GitSupport; +import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; +import org.springframework.sbm.engine.precondition.PreconditionVerifier; import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.resource.ProjectResourceSet; import org.springframework.sbm.project.resource.RewriteSourceFileHolder; -import lombok.RequiredArgsConstructor; -import org.openrewrite.SourceFile; -import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; -import java.io.IOException; -import java.io.InputStream; import java.nio.file.Path; import java.util.List; import java.util.Optional; @@ -42,6 +44,8 @@ public class ProjectContextInitializer { private final PathScanner pathScanner; private final RewriteMavenParserFactory rewriteMavenParserFactory; private final GitSupport gitSupport; + private final PreconditionVerifier preconditionVerifier; + private final ApplicationEventPublisher eventPublisher; public ProjectContext initProjectContext(Path projectDir, RewriteExecutionContext rewriteExecutionContext) { final Path absoluteProjectDir = projectDir.toAbsolutePath().normalize(); @@ -49,8 +53,10 @@ public ProjectContext initProjectContext(Path projectDir, RewriteExecutionContex initializeGitRepoIfNoneExists(absoluteProjectDir); MavenProjectParser mavenProjectParser = rewriteMavenParserFactory.createRewriteMavenParser(absoluteProjectDir, rewriteExecutionContext); - List scannedResources = pathScanner.scan(absoluteProjectDir); - List resources = map(scannedResources); + List resources = pathScanner.scan(absoluteProjectDir); + + PreconditionVerificationResult preconditionVerificationResult = preconditionVerifier.verifyPreconditions(absoluteProjectDir, resources); + publishResult(preconditionVerificationResult); List parsedResources = mavenProjectParser.parse(absoluteProjectDir, resources); List> rewriteSourceFileHolders = wrapRewriteSourceFiles(absoluteProjectDir, parsedResources); @@ -63,6 +69,12 @@ public ProjectContext initProjectContext(Path projectDir, RewriteExecutionContex return projectContext; } + private void publishResult(PreconditionVerificationResult preconditionVerificationResult) { + preconditionVerificationResult.getResults().forEach(r -> { + eventPublisher.publishEvent(new ActionLogEvent()); + }); + } + private List> wrapRewriteSourceFiles(Path absoluteProjectDir, List parsedByRewrite) { List> rewriteProjectResources = parsedByRewrite.stream() .map(sf -> wrapRewriteSourceFile(absoluteProjectDir, sf)) @@ -92,27 +104,4 @@ void initializeGitRepoIfNoneExists(Path absoluteProjectDir) { } } - private List map(List notParsedByRewrite) { - List resources = notParsedByRewrite.stream().map(r -> new org.springframework.sbm.project.parser.Resource() { - @Override - public Path getPath() { - try { - return r.getFile().toPath(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public InputStream getContent() { - try { - return r.getInputStream(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }).collect(Collectors.toList()); - return resources; - } - } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/Resource.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/Resource.java deleted file mode 100644 index 771946402..000000000 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/Resource.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2021 - 2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.sbm.project.parser; - -import java.io.InputStream; -import java.nio.file.Path; - -public interface Resource { - Path getPath(); - - InputStream getContent(); -} diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java new file mode 100644 index 000000000..2d275eeb6 --- /dev/null +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java @@ -0,0 +1,38 @@ +package org.springframework.sbm.engine.precondition; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.Resource; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class BuildFileExistsPreconditionCheckTest { + + @Test + void shouldReturnErrorMessageIfNoMavenBuildFileExists() { + MavenBuildFileExistsPrecondition sut = new MavenBuildFileExistsPrecondition(); + Path projectRoot = Path.of("."); + PreconditionCheckResult checkResult = sut.verify(projectRoot, List.of()); + assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); + assertThat(checkResult.getMessage()).isEqualTo("SBM requires a Maven build file. Please provide a minimal pom.xml."); + } + + @Test + void shouldReturnSuccessIfMavenBuildFileExists() throws IOException { + MavenBuildFileExistsPrecondition sut = new MavenBuildFileExistsPrecondition(); + Resource buildGradle = mock(Resource.class); + File buildGradleFile = mock(File.class); + when(buildGradle.getFile()).thenReturn(buildGradleFile); + when(buildGradleFile.toPath()).thenReturn(Path.of("./foo/pom.xml").toAbsolutePath().normalize()); + PreconditionCheckResult checkResult = sut.verify(Path.of("./foo").toAbsolutePath().normalize(), List.of(buildGradle)); + assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(checkResult.getMessage()).isEqualTo("Found pom.xml."); + } + +} \ No newline at end of file diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java new file mode 100644 index 000000000..3ca15feb9 --- /dev/null +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java @@ -0,0 +1,29 @@ +package org.springframework.sbm.engine.precondition; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.Resource; +import org.springframework.sbm.engine.git.GitSupport; +import org.springframework.sbm.project.resource.ApplicationProperties; + +import java.nio.file.Path; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest { + + @Test + void gitSupportDisabled() { + ApplicationProperties applicationProperties = new ApplicationProperties(); + applicationProperties.setGitSupportEnabled(false); + + DoesGitDirExistWhenGitSupportEnabledPreconditionCheck sut = new DoesGitDirExistWhenGitSupportEnabledPreconditionCheck(applicationProperties, new GitSupport(applicationProperties)); + + Path projectRoot = Path.of("./test-dummy").toAbsolutePath().normalize(); + List projectResources = List.of(); + PreconditionCheckResult checkResult = sut.verify(projectRoot, projectResources); + + assertThat(checkResult.getState()).isSameAs(PreconditionCheck.ResultState.PASSED); + } + +} \ No newline at end of file diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java new file mode 100644 index 000000000..d3e987326 --- /dev/null +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java @@ -0,0 +1,45 @@ +package org.springframework.sbm.engine.precondition; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.Resource; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +class JavaSourceDirExistsPreconditionCheckTest { + @Test + void shouldReturnFailedMessageWhenJavaSourceDirNotExists() throws IOException { + JavaSourceDirExistsPrecondition sut = new JavaSourceDirExistsPrecondition(); + Resource r1 = mock(Resource.class); + File f1 = mock(File.class); + when(f1.toPath()).thenReturn(Path.of("src/main/resources")); + when(r1.getFile()).thenReturn(f1); + List resources = List.of(r1); + PreconditionCheckResult checkResult = sut.verify(Path.of("."), resources); + assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); + assertThat(checkResult.getMessage()).isEqualTo("PreconditionCheck check could not find a 'src/main/java' dir. This dir is required."); + verify(r1).getFile(); + verify(f1).toPath(); + } + + @Test + void shouldReturnSuccessMessageWhenJavaSourceDirExists() throws IOException { + JavaSourceDirExistsPrecondition sut = new JavaSourceDirExistsPrecondition(); + Resource r1 = mock(Resource.class); + File f1 = mock(File.class); + when(f1.toPath()).thenReturn(Path.of("src/main/java")); + when(r1.getFile()).thenReturn(f1); + List resources = List.of(r1); + PreconditionCheckResult checkResult = sut.verify(Path.of("."), resources); + assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(checkResult.getMessage()).isEqualTo("Found required source dir 'src/main/java'."); + verify(r1).getFile(); + verify(f1).toPath(); + } + +} \ No newline at end of file diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java new file mode 100644 index 000000000..86655c745 --- /dev/null +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java @@ -0,0 +1,39 @@ +package org.springframework.sbm.engine.precondition; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.Resource; + +import java.nio.file.Path; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class JavaVersionPreconditionCheckTest { + + @Test + void unsupportedJavaVersionShouldTriggerWarning() { + JavaVersionPreconditionCheck sut = new JavaVersionPreconditionCheck(); + Path projectRoot = Path.of("./test-dummy").toAbsolutePath().normalize(); + List resources = List.of(); + + System.setProperty("java.specification.version", "10"); + + PreconditionCheckResult checkResult = sut.verify(projectRoot, resources); + assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.WARN); + assertThat(checkResult.getMessage()).isEqualTo("Java 11 is required. Check found Java 10."); + } + + @Test + void supportedJavaVersionShouldPass() { + JavaVersionPreconditionCheck sut = new JavaVersionPreconditionCheck(); + Path projectRoot = Path.of("./test-dummy").toAbsolutePath().normalize(); + List resources = List.of(); + + System.setProperty("java.specification.version", "11"); + + PreconditionCheckResult checkResult = sut.verify(projectRoot, resources); + assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(checkResult.getMessage()).isEqualTo("Required Java version (11) was found."); + } + +} \ No newline at end of file diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java new file mode 100644 index 000000000..e148c1b9b --- /dev/null +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java @@ -0,0 +1,49 @@ +package org.springframework.sbm.engine.precondition; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.Resource; + +import java.nio.file.Path; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +class PreconditionCheckVerifierTest { + + @Test + void shouldApplyAllPreconditionChecks() { + PreconditionCheck p1 = mock(PreconditionCheck.class); + PreconditionCheck p2 = mock(PreconditionCheck.class); + PreconditionCheck p3 = mock(PreconditionCheck.class); + List preconditions = List.of(p1, p2, p3); + PreconditionVerifier sut = new PreconditionVerifier(preconditions); + + List resources = List.of(); + + Path projectRoot = Path.of("."); + when(p1.verify(projectRoot, resources)).thenReturn(new PreconditionCheckResult(PreconditionCheck.ResultState.FAILED, "message 1")); + when(p2.verify(projectRoot, resources)).thenReturn(new PreconditionCheckResult(PreconditionCheck.ResultState.PASSED, "passed")); + when(p3.verify(projectRoot, resources)).thenReturn(new PreconditionCheckResult(PreconditionCheck.ResultState.WARN, "message 3")); + + PreconditionVerificationResult preconditionVerificationResult = sut.verifyPreconditions(projectRoot, resources); + + assertThat(preconditionVerificationResult.getResults()).hasSize(3); + PreconditionCheckResult result1 = preconditionVerificationResult.getResults().get(0); + assertThat(result1.getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); + assertThat(result1.getMessage()).isEqualTo("message 1"); + + PreconditionCheckResult result2 = preconditionVerificationResult.getResults().get(1); + assertThat(result2.getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(result2.getMessage()).isEqualTo("passed"); + + PreconditionCheckResult result3 = preconditionVerificationResult.getResults().get(2); + assertThat(result3.getState()).isEqualTo(PreconditionCheck.ResultState.WARN); + assertThat(result3.getMessage()).isEqualTo("message 3"); + + verify(p1).verify(projectRoot, resources); + verify(p2).verify(projectRoot, resources); + verify(p3).verify(projectRoot, resources); + } + +} \ No newline at end of file diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java new file mode 100644 index 000000000..0e3d512fe --- /dev/null +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java @@ -0,0 +1,131 @@ +package org.springframework.sbm.engine.precondition; + +import org.eclipse.jgit.api.Git; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.core.io.Resource; +import org.springframework.sbm.engine.git.GitSupport; +import org.springframework.sbm.project.TestDummyResource; +import org.springframework.sbm.project.resource.ApplicationProperties; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@SpringBootTest(classes = { + ApplicationProperties.class, + PreconditionVerifier.class, + GitSupport.class, + PreconditionVerifierIntegrationTest.TestConfig.class +}) +public class PreconditionVerifierIntegrationTest { + + /* + * Initialize all beans extending {@source PreconditionCheck}. + * Populate and inject list of Checks ordered by their given @Order. + */ + @Configuration + @ComponentScan(includeFilters = {@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, classes = PreconditionCheck.class)}) + public static class TestConfig { } + + @Autowired + private PreconditionVerifier sut; + + @Autowired + private ApplicationProperties applicationProperties; + + @Autowired + private GitSupport gitSupport; + + @Test + void allChecksFailed() { + Path projectRoot = Path.of("./test-dummy").toAbsolutePath().normalize(); + + List resources = List.of(); + + System.setProperty("java.specification.version", "9"); + + applicationProperties.setGitSupportEnabled(true); + + PreconditionVerificationResult preconditionVerificationResult = sut.verifyPreconditions(projectRoot, resources); + + assertThat(applicationProperties.isGitSupportEnabled()).isTrue(); + assertThat(preconditionVerificationResult.getResults()).hasSize(4); + assertThat(preconditionVerificationResult.getResults().get(0).getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); + assertThat(preconditionVerificationResult.getResults().get(0).getMessage()).isEqualTo("SBM requires a Maven build file. Please provide a minimal pom.xml."); + assertThat(preconditionVerificationResult.getResults().get(1).getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); + assertThat(preconditionVerificationResult.getResults().get(1).getMessage()).isEqualTo("'sbm.gitSupportEnabled' is 'true' but no '.git' dir exists in project dir. Either disable git support or initialize git."); + assertThat(preconditionVerificationResult.getResults().get(2).getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); + assertThat(preconditionVerificationResult.getResults().get(2).getMessage()).isEqualTo("PreconditionCheck check could not find a 'src/main/java' dir. This dir is required."); + assertThat(preconditionVerificationResult.getResults().get(3).getState()).isEqualTo(PreconditionCheck.ResultState.WARN); + assertThat(preconditionVerificationResult.getResults().get(3).getMessage()).isEqualTo("Java 11 is required. Check found Java 9."); + } + + @Test + void allChecksSucceed(@TempDir Path tempDir) throws IOException { + Path projectRoot = tempDir.resolve("./test-dummy").toAbsolutePath().normalize(); + + // Add MyClass.java + Path resolve = projectRoot.resolve("src/main/java/MyClass.java"); + Files.createDirectories(resolve.getParent()); + Path path = Files.writeString(resolve, "", StandardOpenOption.CREATE_NEW); + Resource javaResource = createResource(path); + + // pom.xml exists + Resource buildFileResource = mock(Resource.class); + File buildFile = mock(File.class); + when(buildFile.toPath()).thenReturn(projectRoot.resolve("pom.xml")); + when(buildFileResource.getFile()).thenReturn(buildFile); + + // Java version is 11 + System.setProperty("java.specification.version", "11"); + + // git enabled + applicationProperties.setGitSupportEnabled(true); + + // .git exists +// Path git = Files.createDirectories(projectRoot.resolve(".git")); +// Resource gitResource = createResource(git); + Path gitDir = projectRoot.resolve(".git"); + File repo = gitDir.toFile(); + Git git = gitSupport.initGit(repo); + gitSupport.add(repo, "*"); + gitSupport.commit(repo, "initial commit"); + Resource gitResource = createResource(gitDir); + + List resources = List.of(javaResource, buildFileResource, gitResource); + + + PreconditionVerificationResult preconditionVerificationResult = sut.verifyPreconditions(projectRoot, resources); + + assertThat(applicationProperties.isGitSupportEnabled()).isTrue(); + assertThat(preconditionVerificationResult.getResults()).hasSize(4); + assertThat(preconditionVerificationResult.getResults().get(0).getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(preconditionVerificationResult.getResults().get(0).getMessage()).isEqualTo("Found pom.xml."); + assertThat(preconditionVerificationResult.getResults().get(1).getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(preconditionVerificationResult.getResults().get(1).getMessage()).isEqualTo("'sbm.gitSupportEnabled' is 'true', changes will be committed to branch [master] after each recipe."); + assertThat(preconditionVerificationResult.getResults().get(2).getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(preconditionVerificationResult.getResults().get(2).getMessage()).isEqualTo("Found required source dir 'src/main/java'."); + assertThat(preconditionVerificationResult.getResults().get(3).getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(preconditionVerificationResult.getResults().get(3).getMessage()).isEqualTo("Required Java version (11) was found."); + } + + @NotNull + private Resource createResource(Path path) { + return new TestDummyResource(path, ""); + } + +} diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/PathScannerTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/PathScannerTest.java index 80ea46eb5..51b7d245a 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/PathScannerTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/PathScannerTest.java @@ -15,11 +15,11 @@ */ package org.springframework.sbm.project.parser; -import org.springframework.sbm.project.resource.ApplicationProperties; -import org.springframework.sbm.project.resource.ResourceHelper; import org.junit.jupiter.api.Test; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; +import org.springframework.sbm.project.resource.ApplicationProperties; +import org.springframework.sbm.project.resource.ResourceHelper; import java.io.IOException; import java.nio.file.Path; @@ -29,7 +29,7 @@ class PathScannerTest { - public static final String TESTCODE_DIR = "./testcode/module1/src/main/webapp/META-INF"; + public static final String TESTCODE_DIR = "./testcode/path-scanner/module1/src/main/webapp/META-INF"; @Test void returnsAllWhenNoPatternMatches() throws IOException { 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 233eeed06..2f84dd16f 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 @@ -15,13 +15,13 @@ */ package org.springframework.sbm.project.parser; -import org.springframework.sbm.project.TestDummyResource; -import org.springframework.sbm.openrewrite.RewriteExecutionContext; -import org.springframework.sbm.project.resource.RewriteSourceFileHolder; -import org.springframework.sbm.xml.parser.RewriteXmlParser; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openrewrite.xml.tree.Xml; +import org.springframework.sbm.openrewrite.RewriteExecutionContext; +import org.springframework.sbm.project.TestDummyResource; +import org.springframework.sbm.project.resource.RewriteSourceFileHolder; +import org.springframework.sbm.xml.parser.RewriteXmlParser; import java.nio.file.Path; import java.util.List; @@ -47,7 +47,7 @@ void parse() { @Test void testParse() { - Path file = Path.of("testcode/module1/src/main/resources/some.xml").toAbsolutePath(); + Path file = Path.of("testcode/path-scanner/module1/src/main/resources/some.xml").toAbsolutePath(); 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"); 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 739e707f1..8d566824c 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 @@ -15,12 +15,19 @@ */ package org.springframework.sbm.project.resource; +import org.jetbrains.annotations.NotNull; +import org.openrewrite.Parser; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.annotation.Order; +import org.springframework.core.io.Resource; import org.springframework.sbm.build.impl.OpenRewriteMavenBuildFile; import org.springframework.sbm.build.migration.MavenPomCacheProvider; import org.springframework.sbm.build.resource.BuildFileResourceWrapper; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectContextFactory; import org.springframework.sbm.engine.git.GitSupport; +import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; +import org.springframework.sbm.engine.precondition.PreconditionVerifier; import org.springframework.sbm.java.JavaSourceProjectResourceWrapper; import org.springframework.sbm.java.refactoring.JavaRefactoringFactory; import org.springframework.sbm.java.refactoring.JavaRefactoringFactoryImpl; @@ -32,11 +39,6 @@ import org.springframework.sbm.project.parser.PathScanner; import org.springframework.sbm.project.parser.ProjectContextInitializer; import org.springframework.sbm.project.parser.RewriteMavenParserFactory; -import org.jetbrains.annotations.NotNull; -import org.openrewrite.Parser; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.core.annotation.Order; -import org.springframework.core.io.Resource; import java.io.ByteArrayInputStream; import java.io.File; @@ -177,7 +179,7 @@ */ public class TestProjectContext { - private static final Path DEFAULT_PROJECT_ROOT = Path.of(".").resolve("dummy-test-path").normalize().toAbsolutePath(); + private static final Path DEFAULT_PROJECT_ROOT = Path.of(".").resolve("target").resolve("dummy-test-path").normalize().toAbsolutePath(); private static final String DEFAULT_PACKAGE_NAME = "not.found"; @@ -409,6 +411,12 @@ public ProjectContext build() { PathScanner pathScanner = mock(PathScanner.class); when(pathScanner.scan(projectRoot)).thenReturn(scannedResources); + // precondition verifier should check resorces + PreconditionVerifier preconditionVerifier = mock(PreconditionVerifier.class); + PreconditionVerificationResult preconditionVerificationResult = new PreconditionVerificationResult(); + when(preconditionVerifier.verifyPreconditions(projectRoot, scannedResources)).thenReturn(preconditionVerificationResult); + + // create beans ProjectResourceSetHolder projectResourceSetHolder = new ProjectResourceSetHolder(); JavaRefactoringFactory javaRefactoringFactory = new JavaRefactoringFactoryImpl(projectResourceSetHolder); @@ -423,7 +431,7 @@ public ProjectContext build() { // create ProjectContextInitializer ProjectContextFactory projectContextFactory = new ProjectContextFactory(resourceWrapperRegistry, projectResourceSetHolder, javaRefactoringFactory, new BasePackageCalculator(applicationProperties)); - ProjectContextInitializer projectContextInitializer = createProjectContextInitializer(pathScanner, projectContextFactory); + ProjectContextInitializer projectContextInitializer = createProjectContextInitializer(pathScanner, projectContextFactory, preconditionVerifier); // create ProjectContext ProjectContext projectContext = projectContextInitializer.initProjectContext(projectRoot, new RewriteExecutionContext(eventPublisher)); @@ -452,14 +460,14 @@ private Integer getOrder(ProjectResourceWrapper l1) { } @NotNull - private ProjectContextInitializer createProjectContextInitializer(PathScanner pathScanner, ProjectContextFactory projectContextFactory) { + private ProjectContextInitializer createProjectContextInitializer(PathScanner pathScanner, ProjectContextFactory projectContextFactory, PreconditionVerifier preconditionVerifier) { RewriteMavenParserFactory rewriteMavenParserFactory = new RewriteMavenParserFactory(new MavenPomCacheProvider(), eventPublisher); GitSupport gitSupport = mock(GitSupport.class); when(gitSupport.repoExists(projectRoot.toFile())).thenReturn(true); when(gitSupport.getLatestCommit(projectRoot.toFile())).thenReturn(Optional.empty()); - ProjectContextInitializer projectContextInitializer = new ProjectContextInitializer(projectContextFactory, pathScanner, rewriteMavenParserFactory, gitSupport); + ProjectContextInitializer projectContextInitializer = new ProjectContextInitializer(projectContextFactory, pathScanner, rewriteMavenParserFactory, gitSupport, preconditionVerifier); return projectContextInitializer; } diff --git a/components/sbm-core/testcode/.gitignore b/components/sbm-core/testcode/path-scanner/.gitignore similarity index 100% rename from components/sbm-core/testcode/.gitignore rename to components/sbm-core/testcode/path-scanner/.gitignore diff --git a/components/sbm-core/testcode/lib/dummy-dep.jar b/components/sbm-core/testcode/path-scanner/lib/dummy-dep.jar similarity index 100% rename from components/sbm-core/testcode/lib/dummy-dep.jar rename to components/sbm-core/testcode/path-scanner/lib/dummy-dep.jar diff --git a/components/sbm-core/testcode/module1/pom.xml b/components/sbm-core/testcode/path-scanner/module1/pom.xml similarity index 100% rename from components/sbm-core/testcode/module1/pom.xml rename to components/sbm-core/testcode/path-scanner/module1/pom.xml diff --git a/components/sbm-core/testcode/module1/src/main/java/com/example/SomeJavaClass.java b/components/sbm-core/testcode/path-scanner/module1/src/main/java/com/example/SomeJavaClass.java similarity index 100% rename from components/sbm-core/testcode/module1/src/main/java/com/example/SomeJavaClass.java rename to components/sbm-core/testcode/path-scanner/module1/src/main/java/com/example/SomeJavaClass.java diff --git a/components/sbm-core/testcode/module1/src/main/resources/schema.sql b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/schema.sql similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/schema.sql rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/schema.sql diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.html b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.html similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.html rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.html diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.jsp b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.jsp similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.jsp rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.jsp diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.properties b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.properties similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.properties rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.properties diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.txt b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.txt similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.txt rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.txt diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.xhtml b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.xhtml similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.xhtml rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.xhtml diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.xml b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.xml similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.xml rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.xml diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.xsd b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.xsd similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.xsd rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.xsd diff --git a/components/sbm-core/testcode/module1/src/main/resources/some.yaml b/components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.yaml similarity index 100% rename from components/sbm-core/testcode/module1/src/main/resources/some.yaml rename to components/sbm-core/testcode/path-scanner/module1/src/main/resources/some.yaml diff --git a/components/sbm-core/testcode/module1/src/main/webapp/META-INF/some.wsdl b/components/sbm-core/testcode/path-scanner/module1/src/main/webapp/META-INF/some.wsdl similarity index 100% rename from components/sbm-core/testcode/module1/src/main/webapp/META-INF/some.wsdl rename to components/sbm-core/testcode/path-scanner/module1/src/main/webapp/META-INF/some.wsdl diff --git a/components/sbm-core/testcode/module1/src/main/webapp/META-INF/some.xsl b/components/sbm-core/testcode/path-scanner/module1/src/main/webapp/META-INF/some.xsl similarity index 100% rename from components/sbm-core/testcode/module1/src/main/webapp/META-INF/some.xsl rename to components/sbm-core/testcode/path-scanner/module1/src/main/webapp/META-INF/some.xsl diff --git a/components/sbm-core/testcode/module1/src/main/webapp/META-INF/some.xslt b/components/sbm-core/testcode/path-scanner/module1/src/main/webapp/META-INF/some.xslt similarity index 100% rename from components/sbm-core/testcode/module1/src/main/webapp/META-INF/some.xslt rename to components/sbm-core/testcode/path-scanner/module1/src/main/webapp/META-INF/some.xslt diff --git a/components/sbm-core/testcode/module2/pom.xml b/components/sbm-core/testcode/path-scanner/module2/pom.xml similarity index 100% rename from components/sbm-core/testcode/module2/pom.xml rename to components/sbm-core/testcode/path-scanner/module2/pom.xml diff --git a/components/sbm-core/testcode/module2/src/test/java/com/example/FooTest.java b/components/sbm-core/testcode/path-scanner/module2/src/test/java/com/example/FooTest.java similarity index 100% rename from components/sbm-core/testcode/module2/src/test/java/com/example/FooTest.java rename to components/sbm-core/testcode/path-scanner/module2/src/test/java/com/example/FooTest.java diff --git a/components/sbm-core/testcode/module2/src/test/resources/test.whatever b/components/sbm-core/testcode/path-scanner/module2/src/test/resources/test.whatever similarity index 100% rename from components/sbm-core/testcode/module2/src/test/resources/test.whatever rename to components/sbm-core/testcode/path-scanner/module2/src/test/resources/test.whatever diff --git a/components/sbm-core/testcode/pom.xml b/components/sbm-core/testcode/path-scanner/pom.xml similarity index 100% rename from components/sbm-core/testcode/pom.xml rename to components/sbm-core/testcode/path-scanner/pom.xml From b63ba0600912f7c082736370597799079684995e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Tue, 8 Mar 2022 17:30:41 +0100 Subject: [PATCH 02/17] Prints result of precondition check in CLI --- .../PreconditionVerificationRenderer.java | 54 +++++++++++++ .../sbm/shell/ScanShellCommand.java | 75 +++++++++++-------- .../sbm/SpringBoot23To24MigrationTest.java | 24 +++--- .../ProjectContextFileSystemTestSupport.java | 12 ++- .../commands/ApplicableRecipeListCommand.java | 15 ++-- .../sbm/engine/commands/ApplyCommand.java | 29 ++++--- .../sbm/engine/commands/ScanCommand.java | 26 ++++++- ...JavaSourceDirExistsPreconditionCheck.java} | 10 ++- .../JavaVersionPreconditionCheck.java | 2 + ...avenBuildFileExistsPreconditionCheck.java} | 2 +- .../precondition/PreconditionCheck.java | 2 +- .../precondition/PreconditionCheckResult.java | 2 +- ...econditionVerificationFailedException.java | 14 ++++ .../PreconditionVerificationResult.java | 19 ++--- .../precondition/PreconditionVerifier.java | 2 +- .../parser/ProjectContextInitializer.java | 20 +---- .../BuildFileExistsPreconditionCheckTest.java | 4 +- ...aSourceDirExistsPreconditionCheckTest.java | 19 ++++- .../parser/ProjectContextInitializerTest.java | 71 +++++++++++------- .../project/resource/TestProjectContext.java | 24 +++--- 20 files changed, 277 insertions(+), 149 deletions(-) create mode 100644 applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java rename components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/{JavaSourceDirExistsPrecondition.java => JavaSourceDirExistsPreconditionCheck.java} (56%) rename components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/{MavenBuildFileExistsPrecondition.java => MavenBuildFileExistsPreconditionCheck.java} (91%) create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java new file mode 100644 index 000000000..3a94ccefb --- /dev/null +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java @@ -0,0 +1,54 @@ +package org.springframework.sbm.shell; + +import org.jline.utils.AttributedStringBuilder; +import org.jline.utils.AttributedStyle; +import org.jline.utils.Colors; +import org.springframework.sbm.engine.precondition.PreconditionCheck; +import org.springframework.sbm.engine.precondition.PreconditionCheckResult; +import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; +import org.springframework.stereotype.Component; + +@Component +public class PreconditionVerificationRenderer { + + public String renderPreconditionCheckResults(PreconditionVerificationResult result) { + AttributedStringBuilder stringBuilder = new AttributedStringBuilder(); + stringBuilder.style(stringBuilder.style().DEFAULT.bold().foreground(Colors.rgbColor("black"))); + stringBuilder.append("\n\n").append(String.format("Checked preconditions for '%s'", result.getProjectRoot())).append("\n"); + + result.getResults().forEach(r -> { + stringBuilder.append(renderCheckResult(r)); + }); + stringBuilder.append("\n"); + return stringBuilder.toAnsi(); + } + + private String renderCheckResult(PreconditionCheckResult r) { + AttributedStringBuilder builder = new AttributedStringBuilder(); + + // TODO: move rendering of status into central place + if(r.getState().equals(PreconditionCheck.ResultState.FAILED)) { + builder.style(builder.style().DEFAULT.bold().foreground(Colors.rgbColor("red"))); + builder.append(" [X]"); + builder.style(builder.style().DEFAULT); + } + + if(r.getState().equals(PreconditionCheck.ResultState.PASSED)) { + builder.style(AttributedStyle.DEFAULT.bold().foreground(Colors.rgbColor("green"))); + builder.append("[ok]"); + builder.style(AttributedStyle.DEFAULT); + } + + if(r.getState().equals(PreconditionCheck.ResultState.WARN)) { + builder.style(AttributedStyle.DEFAULT.bold().foreground(Colors.rgbColor("yellow"))); + builder.append(" [!]"); + builder.style(AttributedStyle.DEFAULT); + } + + builder.append(" ").append(r.getMessage()); + builder.append("\n"); + + return builder.toAnsi(); + } + +} diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java index 1b7d0eac4..8573e2d07 100644 --- a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java @@ -15,17 +15,19 @@ */ package org.springframework.sbm.shell; -import org.springframework.sbm.engine.commands.ApplicableRecipeListCommand; -import org.springframework.sbm.engine.commands.ScanCommand; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.engine.context.ProjectContextHolder; -import org.springframework.sbm.engine.recipe.Recipe; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; import org.jline.utils.AttributedString; import org.jline.utils.AttributedStringBuilder; import org.jline.utils.AttributedStyle; import org.jline.utils.Colors; +import org.springframework.core.io.Resource; +import org.springframework.sbm.engine.commands.ApplicableRecipeListCommand; +import org.springframework.sbm.engine.commands.ScanCommand; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectContextHolder; +import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; +import org.springframework.sbm.engine.recipe.Recipe; import org.springframework.shell.standard.ShellComponent; import org.springframework.shell.standard.ShellMethod; import org.springframework.shell.standard.ShellOption; @@ -36,34 +38,47 @@ @RequiredArgsConstructor public class ScanShellCommand { - private final ScanCommand scanCommand; - private final ApplicableRecipeListRenderer applicableRecipeListRenderer; - private final ApplicableRecipeListCommand applicableRecipeListCommand; - private final ProjectContextHolder contextHolder; + private final ScanCommand scanCommand; + + private final ApplicableRecipeListRenderer applicableRecipeListRenderer; + + private final ApplicableRecipeListCommand applicableRecipeListCommand; + + private final ProjectContextHolder contextHolder; + private final PreconditionVerificationRenderer preconditionVerificationRenderer; + + @ShellMethod(key = { "scan", "s" }, + value = "Scans the target project directory and get the list of applicable recipes.") + public AttributedString scan(@ShellOption(defaultValue = ".", + help = "The root directory of the target application.") String projectRoot) { + + AttributedStringBuilder stringBuilder = buildHeader(projectRoot); - @ShellMethod(key = {"scan", "s"}, value = "Scans the target project directory and get the list of applicable recipes.") - public AttributedString scan( - @ShellOption( - defaultValue = ".", - help = "The root directory of the target application." - ) String projectRoot) { + List resources = scanCommand.scanProjectRoot(projectRoot); + PreconditionVerificationResult result = scanCommand.checkPreconditions(projectRoot, resources); + String renderedPreconditionCheckResults = preconditionVerificationRenderer.renderPreconditionCheckResults(result); + stringBuilder.append(renderedPreconditionCheckResults); - AttributedStringBuilder header = buildHeader(projectRoot); - System.out.println(header.toAnsi()); + if ( ! result.hasError()) { + System.out.println(stringBuilder.toAnsi()); + stringBuilder = new AttributedStringBuilder(); + ProjectContext projectContext = scanCommand.execute(projectRoot); + contextHolder.setProjectContext(projectContext); + List recipes = applicableRecipeListCommand.execute(projectContext); + AttributedString recipeList = applicableRecipeListRenderer.render(recipes); + stringBuilder.append(recipeList); + } - ProjectContext projectContext = scanCommand.execute(projectRoot); - contextHolder.setProjectContext(projectContext); + return stringBuilder.toAttributedString(); + } - List recipes = applicableRecipeListCommand.execute(projectContext); - return applicableRecipeListRenderer.render(recipes); - } + @NotNull + private AttributedStringBuilder buildHeader(String projectRoot) { + AttributedStringBuilder builder = new AttributedStringBuilder(); + builder.append("\n"); + builder.style(AttributedStyle.DEFAULT.italicDefault().boldDefault().foreground(Colors.rgbColor("green"))); + builder.append("scanning '" + projectRoot + "'"); + return builder; + } - @NotNull - private AttributedStringBuilder buildHeader(String projectRoot) { - AttributedStringBuilder builder = new AttributedStringBuilder(); - builder.append("\n"); - builder.style(AttributedStyle.DEFAULT.italicDefault().boldDefault().foreground(Colors.rgbColor("green"))); - builder.append("scanning '" + projectRoot + "'"); - return builder; - } } 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 4c8e68abc..211b52407 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 @@ -15,24 +15,26 @@ */ package org.springframework.sbm; -import org.springframework.sbm.engine.recipe.UserInteractions; -import org.springframework.sbm.test.ProjectContextFileSystemTestSupport; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.openrewrite.RewriteExecutionContext; -import org.springframework.sbm.project.parser.ProjectContextInitializer; -import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties; -import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter; -import org.springframework.sbm.engine.recipe.Recipe; -import org.springframework.sbm.spring.migration.actions.InitDataSourceAfterJpaInitAction; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.core.io.Resource; +import org.springframework.sbm.boot.properties.api.SpringBootApplicationProperties; +import org.springframework.sbm.boot.properties.search.SpringBootApplicationPropertiesResourceListFilter; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.recipe.Recipe; +import org.springframework.sbm.engine.recipe.UserInteractions; +import org.springframework.sbm.openrewrite.RewriteExecutionContext; +import org.springframework.sbm.project.parser.ProjectContextInitializer; +import org.springframework.sbm.spring.migration.actions.InitDataSourceAfterJpaInitAction; +import org.springframework.sbm.test.ProjectContextFileSystemTestSupport; import java.io.IOException; import java.nio.file.Path; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -111,8 +113,10 @@ public void recipeUpdatesBootDependenciesAndParentVersion() throws IOException { + " \n" + "\n"; + List resources = List.of(); - ProjectContext projectContext = contextInitializer.initProjectContext(Path.of("./testcode/boot-23-app/given"), new RewriteExecutionContext());projectContext.getApplicationModules().getRootModule().getMainResourceSet().addStringResource("src/main/resources/data.sql", "# Empty file"); + ProjectContext projectContext = contextInitializer.initProjectContext(Path.of("./testcode/boot-23-app/given"), resources, new RewriteExecutionContext()); + projectContext.getApplicationModules().getRootModule().getMainResourceSet().addStringResource("src/main/resources/data.sql", "# Empty file"); when(ui.askUserYesOrNo(InitDataSourceAfterJpaInitAction.QUESTION)).thenReturn(false); diff --git a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java index 01a31c413..40d43d919 100644 --- a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java +++ b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java @@ -15,12 +15,14 @@ */ package org.springframework.sbm.test; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.openrewrite.RewriteExecutionContext; -import org.springframework.sbm.project.parser.ProjectContextInitializer; import lombok.Getter; import lombok.Setter; import org.apache.commons.io.FileUtils; +import org.springframework.core.io.Resource; +import org.springframework.sbm.engine.commands.ScanCommand; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.openrewrite.RewriteExecutionContext; +import org.springframework.sbm.project.parser.ProjectContextInitializer; import java.io.IOException; import java.nio.file.Path; @@ -61,7 +63,9 @@ public static ProjectContext createProjectContextFromDir(String projectRootDir, final ProjectContextHolder projectContextHolder = new ProjectContextHolder(); SpringBeanProvider.run(ctx -> { ProjectContextInitializer projectContextBuilder = ctx.getBean(ProjectContextInitializer.class); - ProjectContext projectContext = projectContextBuilder.initProjectContext(projectRoot, new RewriteExecutionContext()); + ScanCommand scanCommand = ctx.getBean(ScanCommand.class); + List resources = scanCommand.scanProjectRoot(to.toString()); + ProjectContext projectContext = projectContextBuilder.initProjectContext(projectRoot, resources, new RewriteExecutionContext()); projectContextHolder.setContext(projectContext); }, beanClasses.toArray(new Class[]{}) diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplicableRecipeListCommand.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplicableRecipeListCommand.java index 4d725c644..c295186c8 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplicableRecipeListCommand.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplicableRecipeListCommand.java @@ -15,16 +15,14 @@ */ package org.springframework.sbm.engine.commands; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectRootPathResolver; import org.springframework.sbm.engine.recipe.Recipe; import org.springframework.sbm.engine.recipe.Recipes; import org.springframework.sbm.engine.recipe.RecipesBuilder; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.engine.context.ProjectRootPathResolver; -import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.parser.ProjectContextInitializer; import org.springframework.stereotype.Component; -import java.nio.file.Path; import java.util.List; @Component @@ -46,10 +44,11 @@ protected ApplicableRecipeListCommand(ProjectRootPathResolver projectRootPathRes @Deprecated // FIXME: Refactor: inheriting AbstractCommand forces this method! public List execute(String... arguments) { - Path projectRoot = projectRootPathResolver.getProjectRootOrDefault(arguments[0]); - // FIXME: This call creates a new ProjectResourceSet which is not correct. - ProjectContext context = projectContextBuilder.initProjectContext(projectRoot, new RewriteExecutionContext()); - return getApplicableRecipes(context); +// Path projectRoot = projectRootPathResolver.getProjectRootOrDefault(arguments[0]); +// // FIXME: This call creates a new ProjectResourceSet which is not correct. +// ProjectContext context = projectContextBuilder.initProjectContext(projectRoot, new RewriteExecutionContext()); +// return getApplicableRecipes(context); + return null; } private List getApplicableRecipes(ProjectContext context) { diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplyCommand.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplyCommand.java index aa8e9a2b0..3aaf1db50 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplyCommand.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ApplyCommand.java @@ -15,20 +15,18 @@ */ package org.springframework.sbm.engine.commands; +import org.springframework.sbm.common.filter.DeletedResourcePathStringFilter; +import org.springframework.sbm.common.filter.ModifiedResourcePathStringFilter; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectContextSerializer; +import org.springframework.sbm.engine.context.ProjectRootPathResolver; import org.springframework.sbm.engine.git.GitSupport; import org.springframework.sbm.engine.git.ProjectSyncVerifier; import org.springframework.sbm.engine.recipe.Recipe; import org.springframework.sbm.engine.recipe.RecipesBuilder; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.engine.context.ProjectContextSerializer; -import org.springframework.sbm.engine.context.ProjectRootPathResolver; -import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.parser.ProjectContextInitializer; -import org.springframework.sbm.common.filter.DeletedResourcePathStringFilter; -import org.springframework.sbm.common.filter.ModifiedResourcePathStringFilter; import org.springframework.stereotype.Component; -import java.nio.file.Path; import java.util.List; @Component @@ -88,14 +86,15 @@ public Recipe execute(ProjectContext projectContext, String recipeName) { @Override @Deprecated public Recipe execute(String... arguments) { - if (arguments == null || arguments.length < 2) { - throw new IllegalArgumentException("Apply command needs project path (as first) and recipe name (as second) to be provided"); - } else { - Path projectRoot = projectRootPathResolver.getProjectRootOrDefault(arguments[0]); - // FIXME: This triggers a new scan which shouldn't be required. Retrieve current ProjectContext from...? and use it here. - ProjectContext context = projectContextBuilder.initProjectContext(projectRoot, new RewriteExecutionContext()); - return applyCommandHelper.applyRecipe(context, arguments[1]); - } +// if (arguments == null || arguments.length < 2) { +// throw new IllegalArgumentException("Apply command needs project path (as first) and recipe name (as second) to be provided"); +// } else { +// Path projectRoot = projectRootPathResolver.getProjectRootOrDefault(arguments[0]); +// // FIXME: This triggers a new scan which shouldn't be required. Retrieve current ProjectContext from...? and use it here. +// ProjectContext context = projectContextBuilder.initProjectContext(projectRoot, new RewriteExecutionContext()); +// return applyCommandHelper.applyRecipe(context, arguments[1]); +// } + return null; } } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java index a78c61e14..be5344f31 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/commands/ScanCommand.java @@ -16,13 +16,18 @@ package org.springframework.sbm.engine.commands; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.io.Resource; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectRootPathResolver; +import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; +import org.springframework.sbm.engine.precondition.PreconditionVerifier; import org.springframework.sbm.openrewrite.RewriteExecutionContext; +import org.springframework.sbm.project.parser.PathScanner; import org.springframework.sbm.project.parser.ProjectContextInitializer; import org.springframework.stereotype.Component; import java.nio.file.Path; +import java.util.List; @Component public class ScanCommand extends AbstractCommand { @@ -31,17 +36,34 @@ public class ScanCommand extends AbstractCommand { private final ProjectRootPathResolver projectRootPathResolver; private final ProjectContextInitializer projectContextInitializer; private final ApplicationEventPublisher eventPublisher; + private final PathScanner pathScanner; + private final PreconditionVerifier preconditionVerifier; @Deprecated - public ScanCommand(ProjectRootPathResolver projectRootPathResolver, ProjectContextInitializer projectContextInitializer, ApplicationEventPublisher eventPublisher) { + public ScanCommand(ProjectRootPathResolver projectRootPathResolver, ProjectContextInitializer projectContextInitializer, ApplicationEventPublisher eventPublisher, PathScanner pathScanner, PreconditionVerifier preconditionVerifier) { super(COMMAND_NAME); this.projectRootPathResolver = projectRootPathResolver; this.projectContextInitializer = projectContextInitializer; this.eventPublisher = eventPublisher; + this.pathScanner = pathScanner; + this.preconditionVerifier = preconditionVerifier; } public ProjectContext execute(String... arguments) { Path projectRoot = projectRootPathResolver.getProjectRootOrDefault(arguments[0]); - return projectContextInitializer.initProjectContext(projectRoot, new RewriteExecutionContext(eventPublisher)); + + List resources = pathScanner.scan(projectRoot); + + return projectContextInitializer.initProjectContext(projectRoot, resources, new RewriteExecutionContext(eventPublisher)); + } + + public List scanProjectRoot(String projectRoot) { + Path projectRootPath = projectRootPathResolver.getProjectRootOrDefault(projectRoot); + return pathScanner.scan(projectRootPath); + } + + public PreconditionVerificationResult checkPreconditions(String projectRoot, List resources) { + Path projectRootPath = projectRootPathResolver.getProjectRootOrDefault(projectRoot); + return preconditionVerifier.verifyPreconditions(projectRootPath, resources); } } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPrecondition.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheck.java similarity index 56% rename from components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPrecondition.java rename to components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheck.java index 9d0e36583..97d82ebea 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPrecondition.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheck.java @@ -1,18 +1,24 @@ package org.springframework.sbm.engine.precondition; import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; +import java.io.File; import java.nio.file.Path; import java.util.List; -class JavaSourceDirExistsPrecondition extends PreconditionCheck { +@Component +class JavaSourceDirExistsPreconditionCheck extends PreconditionCheck { + private static final String PATTERN = "/**/src/main/java/**"; private final String JAVA_SRC_DIR = "src/main/java"; + private AntPathMatcher antPathMatcher = new AntPathMatcher(File.separator); @Override public PreconditionCheckResult verify(Path projectRoot, List projectResources) { if (projectResources.stream() - .noneMatch(r -> projectRoot.relativize(getPath(r)).startsWith(Path.of(JAVA_SRC_DIR).toString()))) { + .noneMatch(r -> antPathMatcher.match(projectRoot.resolve(PATTERN).normalize().toString(), getPath(r).toAbsolutePath().toString()))) { return new PreconditionCheckResult(ResultState.FAILED, "PreconditionCheck check could not find a '" + JAVA_SRC_DIR + "' dir. This dir is required."); } return new PreconditionCheckResult(ResultState.PASSED, "Found required source dir 'src/main/java'."); diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java index 6f9e6cee5..e3481e5f5 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java @@ -1,10 +1,12 @@ package org.springframework.sbm.engine.precondition; import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; import java.nio.file.Path; import java.util.List; +@Component class JavaVersionPreconditionCheck extends PreconditionCheck { @Override public PreconditionCheckResult verify(Path projectRoot, List projectResources) { diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPrecondition.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPreconditionCheck.java similarity index 91% rename from components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPrecondition.java rename to components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPreconditionCheck.java index 5f808a7b1..fab307071 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPrecondition.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPreconditionCheck.java @@ -9,7 +9,7 @@ @Order(1) @Component -class MavenBuildFileExistsPrecondition extends PreconditionCheck { +class MavenBuildFileExistsPreconditionCheck extends PreconditionCheck { @Override public PreconditionCheckResult verify(Path projectRoot, List projectResources) { diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java index 91851c97c..b16b4ba9a 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java @@ -7,7 +7,7 @@ import java.nio.file.Path; import java.util.List; -abstract class PreconditionCheck { +public abstract class PreconditionCheck { private ResultState resultState; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java index 92da2ef74..5112b0159 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java @@ -5,7 +5,7 @@ @Getter @RequiredArgsConstructor -class PreconditionCheckResult { +public class PreconditionCheckResult { private final PreconditionCheck.ResultState state; private final String message; } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java new file mode 100644 index 000000000..31a7fda8c --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java @@ -0,0 +1,14 @@ +package org.springframework.sbm.engine.precondition; + +import lombok.Getter; + +public class PreconditionVerificationFailedException extends RuntimeException { + + @Getter + private PreconditionVerificationResult preconditionVerificationResult; + + public PreconditionVerificationFailedException(PreconditionVerificationResult preconditionVerificationResult) { + this.preconditionVerificationResult = preconditionVerificationResult; + } + +} diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java index 93b955811..4339583a5 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java @@ -1,26 +1,27 @@ package org.springframework.sbm.engine.precondition; import lombok.Getter; +import lombok.RequiredArgsConstructor; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +@RequiredArgsConstructor public class PreconditionVerificationResult { - @Deprecated - private List messages = new ArrayList<>(); @Getter private List results = new ArrayList<>(); + private final Path projectRoot; - @Deprecated - public List getMessages() { - return messages; + public void addResult(PreconditionCheckResult preconditionCheckResult) { + this.results.add(preconditionCheckResult); } - public void addMessage(String message) { - this.messages.add(message); + public boolean hasError() { + return results.stream().anyMatch(r -> r.getState().equals(PreconditionCheck.ResultState.FAILED)); } - public void addResult(PreconditionCheckResult preconditionCheckResult) { - this.results.add(preconditionCheckResult); + public Path getProjectRoot() { + return projectRoot; } } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java index 467d596d3..822f5cff4 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java @@ -14,7 +14,7 @@ public class PreconditionVerifier { private final List preconditions; public PreconditionVerificationResult verifyPreconditions(Path projectRoot, List projectResources) { - PreconditionVerificationResult result = new PreconditionVerificationResult(); + PreconditionVerificationResult result = new PreconditionVerificationResult(projectRoot); preconditions.stream().forEach(pc -> result.addResult(pc.verify(projectRoot, projectResources))); return result; } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java index 372c32830..19345af42 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/ProjectContextInitializer.java @@ -17,15 +17,11 @@ import lombok.RequiredArgsConstructor; import org.openrewrite.SourceFile; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.io.Resource; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectContextFactory; -import org.springframework.sbm.engine.events.ActionLogEvent; import org.springframework.sbm.engine.git.Commit; import org.springframework.sbm.engine.git.GitSupport; -import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; -import org.springframework.sbm.engine.precondition.PreconditionVerifier; import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.resource.ProjectResourceSet; import org.springframework.sbm.project.resource.RewriteSourceFileHolder; @@ -41,23 +37,15 @@ public class ProjectContextInitializer { private final ProjectContextFactory projectContextFactory; - private final PathScanner pathScanner; private final RewriteMavenParserFactory rewriteMavenParserFactory; private final GitSupport gitSupport; - private final PreconditionVerifier preconditionVerifier; - private final ApplicationEventPublisher eventPublisher; - public ProjectContext initProjectContext(Path projectDir, RewriteExecutionContext rewriteExecutionContext) { + public ProjectContext initProjectContext(Path projectDir, List resources, RewriteExecutionContext rewriteExecutionContext) { final Path absoluteProjectDir = projectDir.toAbsolutePath().normalize(); initializeGitRepoIfNoneExists(absoluteProjectDir); MavenProjectParser mavenProjectParser = rewriteMavenParserFactory.createRewriteMavenParser(absoluteProjectDir, rewriteExecutionContext); - List resources = pathScanner.scan(absoluteProjectDir); - - PreconditionVerificationResult preconditionVerificationResult = preconditionVerifier.verifyPreconditions(absoluteProjectDir, resources); - publishResult(preconditionVerificationResult); - List parsedResources = mavenProjectParser.parse(absoluteProjectDir, resources); List> rewriteSourceFileHolders = wrapRewriteSourceFiles(absoluteProjectDir, parsedResources); @@ -69,12 +57,6 @@ public ProjectContext initProjectContext(Path projectDir, RewriteExecutionContex return projectContext; } - private void publishResult(PreconditionVerificationResult preconditionVerificationResult) { - preconditionVerificationResult.getResults().forEach(r -> { - eventPublisher.publishEvent(new ActionLogEvent()); - }); - } - private List> wrapRewriteSourceFiles(Path absoluteProjectDir, List parsedByRewrite) { List> rewriteProjectResources = parsedByRewrite.stream() .map(sf -> wrapRewriteSourceFile(absoluteProjectDir, sf)) diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java index 2d275eeb6..29a099483 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java @@ -16,7 +16,7 @@ class BuildFileExistsPreconditionCheckTest { @Test void shouldReturnErrorMessageIfNoMavenBuildFileExists() { - MavenBuildFileExistsPrecondition sut = new MavenBuildFileExistsPrecondition(); + MavenBuildFileExistsPreconditionCheck sut = new MavenBuildFileExistsPreconditionCheck(); Path projectRoot = Path.of("."); PreconditionCheckResult checkResult = sut.verify(projectRoot, List.of()); assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); @@ -25,7 +25,7 @@ void shouldReturnErrorMessageIfNoMavenBuildFileExists() { @Test void shouldReturnSuccessIfMavenBuildFileExists() throws IOException { - MavenBuildFileExistsPrecondition sut = new MavenBuildFileExistsPrecondition(); + MavenBuildFileExistsPreconditionCheck sut = new MavenBuildFileExistsPreconditionCheck(); Resource buildGradle = mock(Resource.class); File buildGradleFile = mock(File.class); when(buildGradle.getFile()).thenReturn(buildGradleFile); diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java index d3e987326..edca2f926 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java @@ -14,7 +14,7 @@ class JavaSourceDirExistsPreconditionCheckTest { @Test void shouldReturnFailedMessageWhenJavaSourceDirNotExists() throws IOException { - JavaSourceDirExistsPrecondition sut = new JavaSourceDirExistsPrecondition(); + JavaSourceDirExistsPreconditionCheck sut = new JavaSourceDirExistsPreconditionCheck(); Resource r1 = mock(Resource.class); File f1 = mock(File.class); when(f1.toPath()).thenReturn(Path.of("src/main/resources")); @@ -29,7 +29,7 @@ void shouldReturnFailedMessageWhenJavaSourceDirNotExists() throws IOException { @Test void shouldReturnSuccessMessageWhenJavaSourceDirExists() throws IOException { - JavaSourceDirExistsPrecondition sut = new JavaSourceDirExistsPrecondition(); + JavaSourceDirExistsPreconditionCheck sut = new JavaSourceDirExistsPreconditionCheck(); Resource r1 = mock(Resource.class); File f1 = mock(File.class); when(f1.toPath()).thenReturn(Path.of("src/main/java")); @@ -42,4 +42,19 @@ void shouldReturnSuccessMessageWhenJavaSourceDirExists() throws IOException { verify(f1).toPath(); } + @Test + void shouldReturnSuccessMessageWhenJavaSourceDirExistsInChildModule() throws IOException { + JavaSourceDirExistsPreconditionCheck sut = new JavaSourceDirExistsPreconditionCheck(); + Resource r1 = mock(Resource.class); + File f1 = mock(File.class); + when(f1.toPath()).thenReturn(Path.of("module1/src/main/java").toAbsolutePath()); + when(r1.getFile()).thenReturn(f1); + List resources = List.of(r1); + PreconditionCheckResult checkResult = sut.verify(Path.of(".").toAbsolutePath(), resources); + assertThat(checkResult.getState()).isEqualTo(PreconditionCheck.ResultState.PASSED); + assertThat(checkResult.getMessage()).isEqualTo("Found required source dir 'src/main/java'."); + verify(r1).getFile(); + verify(f1).toPath(); + } + } \ No newline at end of file diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ProjectContextInitializerTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ProjectContextInitializerTest.java index 368689dad..999ca4670 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ProjectContextInitializerTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/parser/ProjectContextInitializerTest.java @@ -15,14 +15,6 @@ */ package org.springframework.sbm.project.parser; -import org.springframework.sbm.build.migration.MavenPomCacheProvider; -import org.springframework.sbm.engine.git.GitSupport; -import org.springframework.sbm.java.refactoring.JavaRefactoringFactoryImpl; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.engine.context.ProjectContextFactory; -import org.springframework.sbm.openrewrite.RewriteExecutionContext; -import org.springframework.sbm.project.resource.*; -import org.springframework.sbm.xml.parser.RewriteXmlParser; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; @@ -37,20 +29,36 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; +import org.springframework.sbm.build.migration.MavenPomCacheProvider; +import org.springframework.sbm.engine.commands.ScanCommand; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectContextFactory; +import org.springframework.sbm.engine.context.ProjectRootPathResolver; +import org.springframework.sbm.engine.git.GitSupport; +import org.springframework.sbm.engine.precondition.PreconditionVerifier; +import org.springframework.sbm.java.refactoring.JavaRefactoringFactoryImpl; +import org.springframework.sbm.java.util.BasePackageCalculator; +import org.springframework.sbm.openrewrite.RewriteExecutionContext; +import org.springframework.sbm.project.resource.*; +import org.springframework.sbm.xml.parser.RewriteXmlParser; import org.springframework.util.FileSystemUtils; import java.io.IOException; import java.nio.file.Path; import java.util.List; -import static org.springframework.sbm.project.parser.ResourceVerifier.*; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; +import static org.springframework.sbm.project.parser.ResourceVerifier.*; @SpringBootTest(classes = { ProjectContextInitializer.class, + BasePackageCalculator.class, + ProjectRootPathResolver.class, + PreconditionVerifier.class, ProjectContextFactory.class, RewriteMavenParserFactory.class, MavenPomCacheProvider.class, @@ -60,17 +68,21 @@ ResourceHelper.class, ResourceLoader.class, GitSupport.class, + ScanCommand.class, ProjectResourceSetHolder.class, JavaRefactoringFactoryImpl.class, ProjectResourceWrapperRegistry.class }, properties = {"sbm.gitSupportEnabled=false"}) class ProjectContextInitializerTest { - private Path projectDirectory = Path.of("./testcode").toAbsolutePath().normalize(); + private Path projectDirectory = Path.of("./testcode/path-scanner").toAbsolutePath().normalize(); @Autowired private ProjectContextInitializer sut; + @Autowired + private ScanCommand scanCommand; + @BeforeEach void beforeEach() throws IOException { FileSystemUtils.deleteRecursively(projectDirectory.toAbsolutePath().resolve(".git")); @@ -89,14 +101,15 @@ void test() { ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class); RewriteExecutionContext executionContext = new RewriteExecutionContext(eventPublisher); - ProjectContext projectContext = sut.initProjectContext(projectDirectory, executionContext); + List resources = scanCommand.scanProjectRoot(projectDirectory.toString()); + ProjectContext projectContext = sut.initProjectContext(projectDirectory, resources, executionContext); List> projectResources = projectContext.getProjectResources().list(); assertThat(projectDirectory.toAbsolutePath().resolve(".git")).exists(); assertThat(projectResources).hasSize(18); - verifyResource("testcode/pom.xml") + verifyResource("testcode/path-scanner/pom.xml") .wrappedInstanceOf(Maven.class) .havingMarkers( mavenModelMarker("com.example:example-project-parent:1.0.0-SNAPSHOT"), @@ -108,7 +121,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/pom.xml") + verifyResource("testcode/path-scanner/module1/pom.xml") .wrappedInstanceOf(Maven.class) .havingMarkers( mavenModelMarker("com.example:module1:1.0.0-SNAPSHOT"), @@ -119,7 +132,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/java/com/example/SomeJavaClass.java") + verifyResource("testcode/path-scanner/module1/src/main/java/com/example/SomeJavaClass.java") .wrappedInstanceOf(J.CompilationUnit.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -130,7 +143,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/schema.sql") + verifyResource("testcode/path-scanner/module1/src/main/resources/schema.sql") .wrappedInstanceOf(PlainText.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -141,7 +154,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.xml") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.xml") .wrappedInstanceOf(Xml.Document.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -152,7 +165,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.yaml") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.yaml") .wrappedInstanceOf(Yaml.Documents.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -163,7 +176,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.properties") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.properties") .wrappedInstanceOf(Properties.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -174,7 +187,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.html") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.html") .wrappedInstanceOf(PlainText.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -185,7 +198,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.jsp") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.jsp") .wrappedInstanceOf(PlainText.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -196,7 +209,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.txt") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.txt") .wrappedInstanceOf(PlainText.class) .havingMarkers(buildToolMarker("Maven", "3.6"), javaVersionMarker(11, "maven.compiler.source", "maven.compiler.target"), @@ -206,7 +219,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.xhtml") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.xhtml") .wrappedInstanceOf(Xml.Document.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -217,7 +230,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/resources/some.xsd") + verifyResource("testcode/path-scanner/module1/src/main/resources/some.xsd") .wrappedInstanceOf(Xml.Document.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -228,7 +241,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/webapp/META-INF/some.wsdl") + verifyResource("testcode/path-scanner/module1/src/main/webapp/META-INF/some.wsdl") .wrappedInstanceOf(Xml.Document.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -239,7 +252,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/webapp/META-INF/some.xsl") + verifyResource("testcode/path-scanner/module1/src/main/webapp/META-INF/some.xsl") .wrappedInstanceOf(Xml.Document.class) .havingMarkers(buildToolMarker("Maven", "3.6"), javaVersionMarker(11, "maven.compiler.source", "maven.compiler.target"), @@ -249,7 +262,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module1/src/main/webapp/META-INF/some.xslt") + verifyResource("testcode/path-scanner/module1/src/main/webapp/META-INF/some.xslt") .wrappedInstanceOf(Xml.Document.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -261,7 +274,7 @@ void test() { .isContainedIn(projectResources); // module2 - verifyResource("testcode/module2/pom.xml") + verifyResource("testcode/path-scanner/module2/pom.xml") .wrappedInstanceOf(Maven.class) .havingMarkers( mavenModelMarker("com.example:module2:1.0.0-SNAPSHOT"), @@ -272,7 +285,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module2/src/test/java/com/example/FooTest.java") + verifyResource("testcode/path-scanner/module2/src/test/java/com/example/FooTest.java") .wrappedInstanceOf(J.CompilationUnit.class) .havingMarkers( buildToolMarker("Maven", "3.6"), @@ -283,7 +296,7 @@ void test() { ) .isContainedIn(projectResources); - verifyResource("testcode/module2/src/test/resources/test.whatever") + verifyResource("testcode/path-scanner/module2/src/test/resources/test.whatever") .wrappedInstanceOf(PlainText.class) .havingMarkers( buildToolMarker("Maven", "3.6"), 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 8d566824c..a97af72a7 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 @@ -26,8 +26,6 @@ import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectContextFactory; import org.springframework.sbm.engine.git.GitSupport; -import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; -import org.springframework.sbm.engine.precondition.PreconditionVerifier; import org.springframework.sbm.java.JavaSourceProjectResourceWrapper; import org.springframework.sbm.java.refactoring.JavaRefactoringFactory; import org.springframework.sbm.java.refactoring.JavaRefactoringFactoryImpl; @@ -36,7 +34,6 @@ import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.TestDummyResource; import org.springframework.sbm.project.parser.DependencyHelper; -import org.springframework.sbm.project.parser.PathScanner; import org.springframework.sbm.project.parser.ProjectContextInitializer; import org.springframework.sbm.project.parser.RewriteMavenParserFactory; @@ -408,13 +405,14 @@ public ProjectContext build() { List scannedResources = mapToResources(resources); // path scanner should return the dummy resources - PathScanner pathScanner = mock(PathScanner.class); - when(pathScanner.scan(projectRoot)).thenReturn(scannedResources); +// PathScanner pathScanner = mock(PathScanner.class); +// when(pathScanner.scan(projectRoot)).thenReturn(scannedResources); - // precondition verifier should check resorces - PreconditionVerifier preconditionVerifier = mock(PreconditionVerifier.class); - PreconditionVerificationResult preconditionVerificationResult = new PreconditionVerificationResult(); - when(preconditionVerifier.verifyPreconditions(projectRoot, scannedResources)).thenReturn(preconditionVerificationResult); + // precondition verifier should check resources + // currently ignored and only called by ScanShellCommand +// PreconditionVerifier preconditionVerifier = mock(PreconditionVerifier.class); +// PreconditionVerificationResult preconditionVerificationResult = new PreconditionVerificationResult(projectRoot); +// when(preconditionVerifier.verifyPreconditions(projectRoot, scannedResources)).thenReturn(preconditionVerificationResult); // create beans @@ -431,10 +429,10 @@ public ProjectContext build() { // create ProjectContextInitializer ProjectContextFactory projectContextFactory = new ProjectContextFactory(resourceWrapperRegistry, projectResourceSetHolder, javaRefactoringFactory, new BasePackageCalculator(applicationProperties)); - ProjectContextInitializer projectContextInitializer = createProjectContextInitializer(pathScanner, projectContextFactory, preconditionVerifier); + ProjectContextInitializer projectContextInitializer = createProjectContextInitializer(projectContextFactory); // create ProjectContext - ProjectContext projectContext = projectContextInitializer.initProjectContext(projectRoot, new RewriteExecutionContext(eventPublisher)); + ProjectContext projectContext = projectContextInitializer.initProjectContext(projectRoot, scannedResources, new RewriteExecutionContext(eventPublisher)); // replace with mocks if (mockedBuildFile != null) { @@ -460,14 +458,14 @@ private Integer getOrder(ProjectResourceWrapper l1) { } @NotNull - private ProjectContextInitializer createProjectContextInitializer(PathScanner pathScanner, ProjectContextFactory projectContextFactory, PreconditionVerifier preconditionVerifier) { + private ProjectContextInitializer createProjectContextInitializer(ProjectContextFactory projectContextFactory) { RewriteMavenParserFactory rewriteMavenParserFactory = new RewriteMavenParserFactory(new MavenPomCacheProvider(), eventPublisher); GitSupport gitSupport = mock(GitSupport.class); when(gitSupport.repoExists(projectRoot.toFile())).thenReturn(true); when(gitSupport.getLatestCommit(projectRoot.toFile())).thenReturn(Optional.empty()); - ProjectContextInitializer projectContextInitializer = new ProjectContextInitializer(projectContextFactory, pathScanner, rewriteMavenParserFactory, gitSupport, preconditionVerifier); + ProjectContextInitializer projectContextInitializer = new ProjectContextInitializer(projectContextFactory, rewriteMavenParserFactory, gitSupport); return projectContextInitializer; } From 599e434eb7ea0e3354e11c1c17f468c576151bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Mon, 21 Mar 2022 10:16:41 +0100 Subject: [PATCH 03/17] Remove println and unused method --- .../Boot_24_25_SeparateCredentialsRecipeTest.java | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_24_25/recipes/Boot_24_25_SeparateCredentialsRecipeTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_24_25/recipes/Boot_24_25_SeparateCredentialsRecipeTest.java index 452ac68d3..7176582bf 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_24_25/recipes/Boot_24_25_SeparateCredentialsRecipeTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_24_25/recipes/Boot_24_25_SeparateCredentialsRecipeTest.java @@ -15,14 +15,10 @@ */ package org.springframework.sbm.boot.upgrade_24_25.recipes; -import org.springframework.sbm.test.RecipeIntegrationTestSupport; -import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; +import org.springframework.sbm.test.RecipeIntegrationTestSupport; import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; import static org.assertj.core.api.Assertions.assertThat; @@ -41,8 +37,7 @@ void test() throws IOException { Path datasourceInitializer = RecipeIntegrationTestSupport.getResultDir(applicationDir).resolve("src/main/java/com/example/springboot24to25example/DataSourceInitializerConfiguration.java"); Path applicationProperties = RecipeIntegrationTestSupport.getResultDir(applicationDir).resolve("src/main/resources/application.properties"); -// System.out.println(getContent(datasourceInitializer)); -// System.out.println(getContent(applicationProperties)); + String expectedApplicationProperties = "spring.jpa.hibernate.ddl-auto=none\n" + "spring.h2.console.enabled=true\n" + @@ -102,11 +97,5 @@ void test() throws IOException { assertThat(applicationProperties).hasContent(expectedApplicationProperties); assertThat(datasourceInitializer).hasContent(expectedDatasourceInitializer); } - @NotNull - private String getContent(Path report) throws IOException { - Charset charset = StandardCharsets.UTF_8; - return new String(Files.readAllBytes(report), charset); - } - } \ No newline at end of file From 09fcad7d612b89250160b4fae8bb53fb02734ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Tue, 22 Mar 2022 13:40:08 +0100 Subject: [PATCH 04/17] Add documentation, remove unused code --- .../sbm/shell/ScanShellCommand.java | 9 ++-- .../PreconditionVerifierIntegrationTest.java | 1 + docs/reference/concepts.adoc | 44 +++++++++++++++++++ docs/reference/howto.adoc | 5 +++ 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java index 8573e2d07..e05a8ec9f 100644 --- a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java @@ -52,16 +52,15 @@ public class ScanShellCommand { public AttributedString scan(@ShellOption(defaultValue = ".", help = "The root directory of the target application.") String projectRoot) { - AttributedStringBuilder stringBuilder = buildHeader(projectRoot); List resources = scanCommand.scanProjectRoot(projectRoot); PreconditionVerificationResult result = scanCommand.checkPreconditions(projectRoot, resources); - String renderedPreconditionCheckResults = preconditionVerificationRenderer.renderPreconditionCheckResults(result); - stringBuilder.append(renderedPreconditionCheckResults); + String renderedPreconditionCheckResults = preconditionVerificationRenderer.renderPreconditionCheckResults(result); + AttributedStringBuilder stringBuilder = buildHeader(projectRoot).append(renderedPreconditionCheckResults); if ( ! result.hasError()) { - System.out.println(stringBuilder.toAnsi()); - stringBuilder = new AttributedStringBuilder(); +// System.out.println(stringBuilder.toAnsi()); +// stringBuilder = new AttributedStringBuilder(); ProjectContext projectContext = scanCommand.execute(projectRoot); contextHolder.setProjectContext(projectContext); List recipes = applicableRecipeListCommand.execute(projectContext); diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java index 0e3d512fe..d824b3866 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java @@ -64,6 +64,7 @@ void allChecksFailed() { assertThat(applicationProperties.isGitSupportEnabled()).isTrue(); assertThat(preconditionVerificationResult.getResults()).hasSize(4); + assertThat(preconditionVerificationResult.hasError()).isTrue(); assertThat(preconditionVerificationResult.getResults().get(0).getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); assertThat(preconditionVerificationResult.getResults().get(0).getMessage()).isEqualTo("SBM requires a Maven build file. Please provide a minimal pom.xml."); assertThat(preconditionVerificationResult.getResults().get(1).getState()).isEqualTo(PreconditionCheck.ResultState.FAILED); diff --git a/docs/reference/concepts.adoc b/docs/reference/concepts.adoc index c7085a008..0a78c1faf 100644 --- a/docs/reference/concepts.adoc +++ b/docs/reference/concepts.adoc @@ -82,6 +82,50 @@ void apply(ProjectContext context) { Read the <> section to learn how you can provide new Specialized Resources. +=== Application Lifecycle + +==== Scan Application +The user provides a root directory to scan a project. +After scanning the given directory a set of preconditions is checked to verify that the scanned project can be successfully parsed. +See <> to learn how you can provide additional precondition checks. + +===== Parsing +When all preconditions are met the project resources are parsed and the abstract syntax tree (AST) gets created in memory. + +===== Specialized Resources +After parsing the project resources a set of ``ProjectResourceWrapper``s is called and generic resources can be replaced +with more specialized resources providing a specialized API for these resources. +Think of replacing a generic XML file representing `persistence.xml` (JPA deployment descriptor) with a specialized +resource representation offering an API to act on a specialized "JPA deployment descriptor". +See <> to learn how yo can provide specialized resources. + +===== Creating the ProjectContext +After replacing specialized resources the ProjectContext gets created. + +===== Display Applicable Recipes +With the `ProjectContext` in place SBM checks all ``Condition``s of recipes and their ``Action``s to find applicable recipes. +The resulting list of applicable recipes is then shown to the user to select and apply recipes against the scanned application. + +==== Apply Recipe +The user applies a recipe of the list of applicable recipes. + +===== Applying Recipe Actions +SBM provides the `ProjectContext` to the list of applicable ``Action``s and each `Action` modifies the AST through the +`ProjectContext` API. These modifications are only represented in memory. + +===== Verify Application In Sync +After applying all ``Action``s of the `Recipe` he changes need to be written back to filesystem. +When `sbm.gitSupportEnabled` is `true` SBM verifies that nothing changed in the scanned project while the recipe was applied. +If the git hash changed or non-indexed resources are found the changes are rolled back, the project must be synced, +re-scanned and the recipe needs to be re-applied. + +===== Writing Back Changes +When git support is disabled or the project is in sync the in-memory representation is written back to the file system. + +===== Commit Changes +When git support is enabled SBM commits the changes applied by running the recipe and the next recipe can be applied. + + === Modules Since 0.9.0 SBM starts to support https://maven.apache.org/guides/mini/guide-multiple-modules.html#the-reactor[multi module applications]. diff --git a/docs/reference/howto.adoc b/docs/reference/howto.adoc index 3818a2ba3..99d748b71 100644 --- a/docs/reference/howto.adoc +++ b/docs/reference/howto.adoc @@ -1,5 +1,10 @@ == How To + +=== Check Preconditions + + + === Implement Actions First step on your journey to implement a new recipe will be the implementation of an `Action`. Every Action that needs access to the ProjectContext to modify resources should extend `AbstractAction`. From ce44c6056ec735746361eba7399735d41035884f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Tue, 22 Mar 2022 13:41:45 +0100 Subject: [PATCH 05/17] Add gitgnore --- demos/demo-introduce-spring-cloud-config/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 demos/demo-introduce-spring-cloud-config/.gitignore diff --git a/demos/demo-introduce-spring-cloud-config/.gitignore b/demos/demo-introduce-spring-cloud-config/.gitignore new file mode 100644 index 000000000..428bf17ae --- /dev/null +++ b/demos/demo-introduce-spring-cloud-config/.gitignore @@ -0,0 +1,3 @@ +testcode/result/* +/**/.git +/.rewrite-cache/ From d61e50df50417c7ea69f32d601b156fe1acddb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Tue, 22 Mar 2022 21:22:39 +0100 Subject: [PATCH 06/17] Checking project sync uses status.isClean now, added documnentation --- .../sbm/shell/ConsolePrinter.java | 10 ++ .../sbm/shell/ScanCommandHeaderRenderer.java | 17 ++++ .../sbm/shell/ScanShellCommand.java | 28 +++--- .../sbm/shell/ConsolePrinterTest.java | 21 +++++ .../PreconditionVerificationRendererTest.java | 37 ++++++++ .../shell/ScanCommandHeaderRendererTest.java | 15 +++ .../sbm/shell/ScanShellCommandTest.java | 91 ++++++++++++++++--- .../sbm/engine/git/GitStatus.java | 67 ++++++++++++++ .../sbm/engine/git/GitSupport.java | 13 +++ ...henGitSupportEnabledPreconditionCheck.java | 15 ++- .../PreconditionVerifierIntegrationTest.java | 2 - docs/reference/testing.adoc | 64 ++++++++++++- 12 files changed, 336 insertions(+), 44 deletions(-) create mode 100644 applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java create mode 100644 applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java create mode 100644 applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java create mode 100644 applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java create mode 100644 applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java create mode 100644 components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java new file mode 100644 index 000000000..edc1878c3 --- /dev/null +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java @@ -0,0 +1,10 @@ +package org.springframework.sbm.shell; + +import org.springframework.stereotype.Component; + +@Component +public class ConsolePrinter { + public void println(String text) { + System.out.println(text); + } +} diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java new file mode 100644 index 000000000..e2a426d9c --- /dev/null +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java @@ -0,0 +1,17 @@ +package org.springframework.sbm.shell; + +import org.jline.utils.AttributedStringBuilder; +import org.jline.utils.AttributedStyle; +import org.jline.utils.Colors; +import org.springframework.stereotype.Component; + +@Component +public class ScanCommandHeaderRenderer { + public String renderHeader(String projectRoot) { + AttributedStringBuilder builder = new AttributedStringBuilder(); + builder.append("\n"); + builder.style(AttributedStyle.DEFAULT.italicDefault().boldDefault().foreground(Colors.rgbColor("green"))); + builder.append("scanning '" + projectRoot + "'"); + return builder.toAnsi(); + } +} diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java index e05a8ec9f..c772616c0 100644 --- a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java @@ -16,11 +16,8 @@ package org.springframework.sbm.shell; import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; import org.jline.utils.AttributedString; import org.jline.utils.AttributedStringBuilder; -import org.jline.utils.AttributedStyle; -import org.jline.utils.Colors; import org.springframework.core.io.Resource; import org.springframework.sbm.engine.commands.ApplicableRecipeListCommand; import org.springframework.sbm.engine.commands.ScanCommand; @@ -46,21 +43,29 @@ public class ScanShellCommand { private final ProjectContextHolder contextHolder; private final PreconditionVerificationRenderer preconditionVerificationRenderer; + private final ScanCommandHeaderRenderer scanCommandHeaderRenderer; + private final ConsolePrinter consolePrinter; - @ShellMethod(key = { "scan", "s" }, + @ShellMethod(key = { "scan", "s" }, value = "Scans the target project directory and get the list of applicable recipes.") public AttributedString scan(@ShellOption(defaultValue = ".", help = "The root directory of the target application.") String projectRoot) { List resources = scanCommand.scanProjectRoot(projectRoot); + String scanCommandHeader = scanCommandHeaderRenderer.renderHeader(projectRoot); PreconditionVerificationResult result = scanCommand.checkPreconditions(projectRoot, resources); String renderedPreconditionCheckResults = preconditionVerificationRenderer.renderPreconditionCheckResults(result); - AttributedStringBuilder stringBuilder = buildHeader(projectRoot).append(renderedPreconditionCheckResults); + AttributedStringBuilder stringBuilder = new AttributedStringBuilder(); + String output = stringBuilder + .append(scanCommandHeader) + .append(renderedPreconditionCheckResults) + .toAnsi(); + consolePrinter.println(output); + + stringBuilder = new AttributedStringBuilder(); if ( ! result.hasError()) { -// System.out.println(stringBuilder.toAnsi()); -// stringBuilder = new AttributedStringBuilder(); ProjectContext projectContext = scanCommand.execute(projectRoot); contextHolder.setProjectContext(projectContext); List recipes = applicableRecipeListCommand.execute(projectContext); @@ -71,13 +76,4 @@ public AttributedString scan(@ShellOption(defaultValue = ".", return stringBuilder.toAttributedString(); } - @NotNull - private AttributedStringBuilder buildHeader(String projectRoot) { - AttributedStringBuilder builder = new AttributedStringBuilder(); - builder.append("\n"); - builder.style(AttributedStyle.DEFAULT.italicDefault().boldDefault().foreground(Colors.rgbColor("green"))); - builder.append("scanning '" + projectRoot + "'"); - return builder; - } - } diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java new file mode 100644 index 000000000..656d82902 --- /dev/null +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java @@ -0,0 +1,21 @@ +package org.springframework.sbm.shell; + +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.assertj.core.api.Assertions.assertThat; + +class ConsolePrinterTest { + + @Test + void shouldPrintToConsole() { + ByteArrayOutputStream sysOutBuffer = new ByteArrayOutputStream(); + System.setOut(new PrintStream(sysOutBuffer)); + + ConsolePrinter sut = new ConsolePrinter(); + sut.println("some text"); + assertThat(sysOutBuffer.toString()).isEqualTo("some text\n"); + } +} \ No newline at end of file diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java new file mode 100644 index 000000000..d16619bed --- /dev/null +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java @@ -0,0 +1,37 @@ +package org.springframework.sbm.shell; + +import org.junit.jupiter.api.Test; +import org.springframework.sbm.engine.precondition.PreconditionCheck; +import org.springframework.sbm.engine.precondition.PreconditionCheckResult; +import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; + +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +class PreconditionVerificationRendererTest { + @Test + void renderPreconditionCheckResult() { + PreconditionVerificationRenderer sut = new PreconditionVerificationRenderer(); + Path projectRoot = Path.of("./foo").toAbsolutePath().normalize(); + + PreconditionVerificationResult checkResult = new PreconditionVerificationResult(projectRoot); + + PreconditionCheckResult passedResult = new PreconditionCheckResult(PreconditionCheck.ResultState.PASSED, "passed"); + checkResult.addResult(passedResult); + PreconditionCheckResult warnResult = new PreconditionCheckResult(PreconditionCheck.ResultState.WARN, "warn"); + checkResult.addResult(warnResult); + PreconditionCheckResult failedResult = new PreconditionCheckResult(PreconditionCheck.ResultState.FAILED, "failed"); + checkResult.addResult(failedResult); + + String s = sut.renderPreconditionCheckResults(checkResult); + assertThat(s).isEqualTo("\u001B[30;1m\n" + + "\n" + + "Checked preconditions for '/Users/fkrueger/git/spring-boot-migrator-oss/experimental/applications/spring-shell/foo'\n" + + "\u001B[32;1m[ok]\u001B[0m passed\n" + + "\u001B[93;1m [!]\u001B[0m warn\n" + + "\u001B[91;1m [X]\u001B[0m failed\n" + + "\n" + + "\u001B[0m"); + } +} \ No newline at end of file diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java new file mode 100644 index 000000000..bf8ff5e3e --- /dev/null +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java @@ -0,0 +1,15 @@ +package org.springframework.sbm.shell; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ScanCommandHeaderRendererTest { + + @Test + void renderHeader() { + ScanCommandHeaderRenderer sut = new ScanCommandHeaderRenderer(); + String s = sut.renderHeader("some/path"); + assertThat(s).isEqualTo("\n\u001B[32mscanning 'some/path'\u001B[0m"); + } +} \ No newline at end of file diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanShellCommandTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanShellCommandTest.java index efeb56d75..249d99c94 100644 --- a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanShellCommandTest.java +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanShellCommandTest.java @@ -15,20 +15,24 @@ */ package org.springframework.sbm.shell; -import org.springframework.sbm.engine.commands.ApplicableRecipeListCommand; -import org.springframework.sbm.engine.commands.ScanCommand; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.engine.context.ProjectContextHolder; -import org.springframework.sbm.engine.recipe.Recipe; import org.jline.utils.AttributedString; import org.jline.utils.AttributedStringBuilder; +import org.jline.utils.AttributedStyle; +import org.jline.utils.Colors; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.core.io.Resource; +import org.springframework.sbm.engine.commands.ApplicableRecipeListCommand; +import org.springframework.sbm.engine.commands.ScanCommand; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectContextHolder; +import org.springframework.sbm.engine.precondition.PreconditionVerificationResult; +import org.springframework.sbm.engine.recipe.Recipe; -import java.nio.file.Path; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -48,26 +52,87 @@ class ScanShellCommandTest { @Mock ProjectContextHolder contextHolder; + @Mock + PreconditionVerificationRenderer preconditionVerificationRenderer; + + @Mock + private ScanCommandHeaderRenderer scanCommandHeaderRenderer; + + @Mock + private ConsolePrinter consolePrinter; + @InjectMocks ScanShellCommand sut; @Test - void testScan() { - String projectRoot = "/test/projectRoot"; - Path rootPath = Path.of(projectRoot).toAbsolutePath().normalize(); - List recipes = List.of(); + void testScanWithFailingPreconditionChecksShouldPrintResult() { AttributedString attributedString = new AttributedStringBuilder().toAttributedString(); - // TODO: test printing of header + String projectRoot = "/test/projectRoot"; + List resources = List.of(); + + // scans given dir + when(scanCommand.scanProjectRoot(projectRoot)).thenReturn(resources); + // render header + String header = "header"; + when(scanCommandHeaderRenderer.renderHeader(projectRoot)).thenReturn(header); + // checking precondition returns error + PreconditionVerificationResult verificationResult = mock(PreconditionVerificationResult.class); + when(verificationResult.hasError()).thenReturn(true); + when(scanCommand.checkPreconditions(projectRoot, resources)).thenReturn(verificationResult); + // render verification result + String renderedVerificationResult = new AttributedStringBuilder().style(AttributedStyle.DEFAULT.italicDefault().boldDefault().foreground(Colors.rgbColor("green"))).append("result").toAnsi(); + when(preconditionVerificationRenderer.renderPreconditionCheckResults(verificationResult)).thenReturn(renderedVerificationResult); + + AttributedString result = sut.scan(projectRoot); + + ArgumentCaptor capturedOutput = ArgumentCaptor.forClass(String.class); + verify(consolePrinter).println(capturedOutput.capture()); + + // header and validation result rendered + assertThat(capturedOutput.getValue()).isEqualTo("header\u001B[32mresult\u001B[0m"); + + assertThat(result.toAnsi()).isEqualTo(attributedString.toAnsi()); + } + + @Test + void testScanWithSucceedingPreconditionChecksShouldPrintResultAndRenderApplicableRecipes() { + String recipeName = "The applicable recipe"; + List recipes = List.of(Recipe.builder().name(recipeName).build()); + + String projectRoot = "/test/projectRoot"; + List resources = List.of(); + // scans given dir + when(scanCommand.scanProjectRoot(projectRoot)).thenReturn(resources); + // render header + String header = "header"; + when(scanCommandHeaderRenderer.renderHeader(projectRoot)).thenReturn(header); + // checking precondition succeeds + PreconditionVerificationResult verificationResult = mock(PreconditionVerificationResult.class); + when(verificationResult.hasError()).thenReturn(false); + when(scanCommand.checkPreconditions(projectRoot, resources)).thenReturn(verificationResult); + // render verification result + String renderedVerificationResult = new AttributedStringBuilder().style(AttributedStyle.DEFAULT.italicDefault().boldDefault().foreground(Colors.rgbColor("green"))).append("result").toAnsi(); + when(preconditionVerificationRenderer.renderPreconditionCheckResults(verificationResult)).thenReturn(renderedVerificationResult); + // Creates ProjectContext ProjectContext projectContext = mock(ProjectContext.class); when(scanCommand.execute(projectRoot)).thenReturn(projectContext); + // find applicable recipes when(applicableRecipeListCommand.execute(projectContext)).thenReturn(recipes); - when(applicableRecipeListRenderer.render(recipes)).thenReturn(attributedString); + // render recipe list + AttributedString applicableRecipes = new AttributedStringBuilder().style(AttributedStyle.DEFAULT.italicDefault().boldDefault().foreground(Colors.rgbColor("red"))).append(recipeName).toAttributedString(); + when(applicableRecipeListRenderer.render(recipes)).thenReturn(applicableRecipes); AttributedString result = sut.scan(projectRoot); - assertThat(result).isSameAs(attributedString); + // list of recipes returned + assertThat(result.toAnsi()).isEqualTo("\u001B[91mThe applicable recipe\u001B[0m"); + // header and validation result rendered + ArgumentCaptor capturedOutput = ArgumentCaptor.forClass(String.class); + verify(consolePrinter).println(capturedOutput.capture()); + assertThat(capturedOutput.getValue()).isEqualTo("header\u001B[32mresult\u001B[0m"); + // ProjectContext was cached verify(contextHolder).setProjectContext(projectContext); } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java new file mode 100644 index 000000000..ebdace325 --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java @@ -0,0 +1,67 @@ +package org.springframework.sbm.engine.git; + +import org.eclipse.jgit.api.Status; +import org.eclipse.jgit.lib.IndexDiff; + +import java.util.Map; +import java.util.Set; + +public class GitStatus { + private Status wrapped; + + public GitStatus(Status wrapped) { + this.wrapped = wrapped; + } + + public boolean isClean() { + return wrapped.isClean(); + } + + public boolean hasUncommittedChanges() { + return wrapped.hasUncommittedChanges(); + } + + public Set getAdded() { + return wrapped.getAdded(); + } + + public Set getChanged() { + return wrapped.getChanged(); + } + + public Set getRemoved() { + return wrapped.getRemoved(); + } + + public Set getMissing() { + return wrapped.getMissing(); + } + + public Set getModified() { + return wrapped.getModified(); + } + + public Set getUntracked() { + return wrapped.getUntracked(); + } + + public Set getUntrackedFolders() { + return wrapped.getUntrackedFolders(); + } + + public Set getConflicting() { + return wrapped.getConflicting(); + } + + public Map getConflictingStageState() { + return wrapped.getConflictingStageState(); + } + + public Set getIgnoredNotInIndex() { + return wrapped.getIgnoredNotInIndex(); + } + + public Set getUncommittedChanges() { + return wrapped.getUncommittedChanges(); + } +} \ No newline at end of file diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java index 997186e3d..f446c6021 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java @@ -258,4 +258,17 @@ private List makeRelativeToRoot(List paths, File projectRootDir) .map(Path::toString) .collect(Collectors.toList()); } + + public GitStatus getStatus(File repo) { + try { + Git git = initGit(repo); + Status status = null; + status = git.status().call(); + GitStatus gitStatus = new GitStatus(status); + return gitStatus; + } catch (GitAPIException e) { + throw new RuntimeException("Could not get git status.", e); + } + } + } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java index 668f4ac66..671b68da2 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java @@ -3,7 +3,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.core.annotation.Order; import org.springframework.core.io.Resource; -import org.springframework.sbm.engine.git.Commit; +import org.springframework.sbm.engine.git.GitStatus; import org.springframework.sbm.engine.git.GitSupport; import org.springframework.sbm.project.resource.ApplicationProperties; import org.springframework.stereotype.Component; @@ -33,7 +33,7 @@ class DoesGitDirExistWhenGitSupportEnabledPreconditionCheck extends Precondition private final ApplicationProperties applicationProperties; private static final String NO_GIT_DIR_EXISTS = "'sbm.gitSupportEnabled' is 'true' but no '.git' dir exists in project dir. Either disable git support or initialize git."; - private static final String HAS_UNCOMMITTED_CHANGES = "'sbm.gitSupportEnabled' is 'true' but uncommitted changes were found. Commit all changes before scan."; + private static final String HAS_UNCOMMITTED_CHANGES = "'sbm.gitSupportEnabled' is 'true' but Git status is not clean. Commit all changes and add or ignore all resources before scan."; private final String CHECK_PASSED = "'sbm.gitSupportEnabled' is 'true', changes will be committed to branch [%s] after each recipe."; private final String CHECK_IGNORED = "'sbm.gitSupportEnabled' is 'false', Nothing will be committed."; private final GitSupport gitSupport; @@ -44,7 +44,7 @@ public PreconditionCheckResult verify(Path projectRoot, List projectRe if (noGitDirExists(projectRoot)) { return new PreconditionCheckResult(FAILED, NO_GIT_DIR_EXISTS); } - else if (hasUncommittedChanges(projectRoot)) { + else if (! isGitStatusClean(projectRoot)) { return new PreconditionCheckResult(FAILED, HAS_UNCOMMITTED_CHANGES); } else { return new PreconditionCheckResult(PASSED, String.format(CHECK_PASSED, getBranch(projectRoot))); @@ -63,13 +63,10 @@ private String getBranch(Path projectRoot) { } } - private boolean hasUncommittedChanges(Path projectRoot) { + private boolean isGitStatusClean(Path projectRoot) { File repo = projectRoot.resolve(".git").normalize().toAbsolutePath().toFile(); - Optional latestCommit = gitSupport.getLatestCommit(repo); - if(latestCommit.isEmpty()) { - return true; - } - return gitSupport.hasUncommittedChangesOrDifferentRevision(repo, latestCommit.get().getHash()); + GitStatus status = gitSupport.getStatus(repo); + return status.isClean(); } private boolean noGitDirExists(Path projectRoot) { diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java index d824b3866..cf45aefac 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java @@ -98,8 +98,6 @@ void allChecksSucceed(@TempDir Path tempDir) throws IOException { applicationProperties.setGitSupportEnabled(true); // .git exists -// Path git = Files.createDirectories(projectRoot.resolve(".git")); -// Resource gitResource = createResource(git); Path gitDir = projectRoot.resolve(".git"); File repo = gitDir.toFile(); Git git = gitSupport.initGit(repo); diff --git a/docs/reference/testing.adoc b/docs/reference/testing.adoc index 9be654d1c..e5450b6f7 100644 --- a/docs/reference/testing.adoc +++ b/docs/reference/testing.adoc @@ -52,7 +52,7 @@ Copies all resources from `./testcode/given/boot-23-app` to `./target/test-proje === RecipeIntegrationTestSupport -If you want to integration test a recipe, `RecipeIntegrationTestSupport` can help you. +If you want to integration test a recipe against a project read from filesystem, `RecipeIntegrationTestSupport` can help you. [source,java] ..... @@ -66,7 +66,63 @@ Path javaClass = RecipeIntegrationTestSupport.getResultDir(applicationDir).resol assertThat(javaClass).hasContent("..."); <4> ..... -<1> Provide a project, here under ./testcode/example-app/given -<2> Scan the project and apply the given recipe +<1> Provide a project, here under `./testcode/example-app/given`. +This project will be copied to a clean dir `target/test-projects/example-app` +<2> Scan the copied project and apply the given recipe against it <3> Retrieve the path to a resource after migration -<4> Verify the resource has expected content \ No newline at end of file +<4> Verify the resource has expected content + +=== IntegrationTestBaseClass +For end-to-end tests using the shell commands `IntegrationTestBaseClass` will be helpful. + +These are the most complete tests but also the slowest. + +NOTE: Currently these tests reside in `spring-shell` module. + +[source,java] +..... +public class MyFullBlownIntegrationTest extends IntegrationTestBaseClass { + @Override + protected String getTestSubDir() { <1> + return "some-dir/project-dir"; <2> + } + + @Test + @Tag("integration") + void migrateSomethingToSpringBoot() { + initializeTestProject(); <3> + scanProject(); <4> + applyRecipe("initialize-spring-boot-migration"); <5> + applyRecipe("migrate-x-to-boot"); <6> + // simulate manual step + replaceFile( <7> + getTestDir().resolve("src/test/java/com/example/jee/app/PersonServiceTest.java"), + getTestDir().resolve("manual-step/BootifiedPersonServiceTest.java") + ); + String localBusinessInterface = loadJavaFile("com.example.jee.app.ejb.local", "ABusinessInterface"); <8> + // verify @Local was removed + assertThat(localBusinessInterface).doesNotContain("@Local"); <9> + executeMavenGoals(getTestDir(), "clean", "package", "spring-boot:build-image"); <10> + int port = startDockerContainer("jee-app:8.0.5-SNAPSHOT", 8080); <11> + TestRestTemplate testRestTemplate = new TestRestTemplate(); <12> + // Test Servlet + String response = testRestTemplate.getForObject("http://localhost:" + port + "/HelloWorld", String.class); <13> + assertThat(response).isEqualTo("Hello World!"); <14> + } +} +..... + +<1> The `getTestSubDir()` method must be implemented. +<2> It must return the path to the test project in `src/test/resources` +<3> Copies test project from `src/test/resources/some-dir/project-dir` to `target/sbm-integration-test/some-dir/project-dir` +<4> Scans the copied test project, same as calling `scan` in CLI +<5> Apply the recipe `initialize-spring-boot-migration`, same as calling `apply initialize-spring-boot-migration` in CLI. +Changes will be reflected in the filesystem after this call. +<6> Apply another recipe `migrate-x-to-boot` +<7> Replace a file, here because the Test needs to be migrated manually +<8> Load the content a Java file as String +<9> Assertions about the context of the Java file +<10> Call `mvn clean package spring-boot:build-image` in the test project +<11> Start the docker image from the last step containing the migrated Spring application +<12> Create a RestTemplate +<13> Use the RestTemplate to retrive some data from the migrated Spring application running in Docker +<14> Verify the response \ No newline at end of file From cbdb2095eec176838f78657f41a1ba0c4f8cfc2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 10:36:48 +0100 Subject: [PATCH 07/17] Fixed precondition for MigrateJsf2xToSpringBootRecipeIntegrationTest --- ...sf2xToSpringBootRecipeIntegrationTest.java | 26 +++++++++++-------- .../testcode/jsf-2.x-migration/.gitignore | 1 + .../sbm/engine/git/GitSupport.java | 8 ++++++ ...henGitSupportEnabledPreconditionCheck.java | 4 +-- 4 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 applications/spring-shell/src/test/resources/testcode/jsf-2.x-migration/.gitignore diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/recipes/MigrateJsf2xToSpringBootRecipeIntegrationTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/recipes/MigrateJsf2xToSpringBootRecipeIntegrationTest.java index 75da68aff..49e5181ef 100644 --- a/applications/spring-shell/src/test/java/org/springframework/sbm/recipes/MigrateJsf2xToSpringBootRecipeIntegrationTest.java +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/recipes/MigrateJsf2xToSpringBootRecipeIntegrationTest.java @@ -15,19 +15,18 @@ */ package org.springframework.sbm.recipes; -import org.springframework.sbm.IntegrationTestBaseClass; -import org.springframework.sbm.engine.git.Commit; -import org.springframework.sbm.engine.git.GitSupport; -import org.springframework.sbm.project.resource.ApplicationProperties; +import org.eclipse.jgit.api.Git; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.springframework.sbm.IntegrationTestBaseClass; +import org.springframework.sbm.engine.git.Commit; +import org.springframework.sbm.engine.git.GitSupport; +import org.springframework.sbm.project.resource.ApplicationProperties; +import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.util.List; -import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -50,9 +49,10 @@ void testRecipe() throws IOException { intializeTestProject(); // create repo GitSupport gitSupport = initGitRepo(); - List modifiedResources = Files.list(getTestDir()).map(f -> f.toAbsolutePath().toString()).collect(Collectors.toList()); - List deletedResources = List.of(); - Commit initialCommit = gitSupport.addAllAndCommit(getTestDir().toFile(), "initial commit", modifiedResources, deletedResources); + Commit initialCommit = gitSupport.getLatestCommit(getTestDir().toFile()).get(); +// List modifiedResources = Files.list(getTestDir()).map(f -> f.toAbsolutePath().toString()).collect(Collectors.toList()); +// List deletedResources = List.of(); +// Commit initialCommit = gitSupport.addAllAndCommit(getTestDir().toFile(), "initial commit", modifiedResources, deletedResources); scanProject(); assertApplicableRecipesContain( @@ -75,7 +75,11 @@ private GitSupport initGitRepo() { ApplicationProperties applicationProperties = new ApplicationProperties(); applicationProperties.setGitSupportEnabled(true); GitSupport gitSupport = new GitSupport(applicationProperties); - gitSupport.initGit(getTestDir().toFile()); + File repo = getTestDir().toFile(); + Git git = gitSupport.initGit(repo); + gitSupport.add(repo, "."); + gitSupport.commit(repo, "initial commit"); + gitSupport.switchToBranch(repo, "main"); return gitSupport; } } diff --git a/applications/spring-shell/src/test/resources/testcode/jsf-2.x-migration/.gitignore b/applications/spring-shell/src/test/resources/testcode/jsf-2.x-migration/.gitignore new file mode 100644 index 000000000..1de565933 --- /dev/null +++ b/applications/spring-shell/src/test/resources/testcode/jsf-2.x-migration/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java index f446c6021..ce5f0be9b 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java @@ -271,4 +271,12 @@ public GitStatus getStatus(File repo) { } } + public void switchToBranch(File repo, String branchName) { + try { + Git git = initGit(repo); + git.checkout().setName(branchName).setCreateBranch(true).call(); + } catch (GitAPIException e) { + e.printStackTrace(); + } + } } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java index 671b68da2..eee915721 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java @@ -54,7 +54,7 @@ else if (! isGitStatusClean(projectRoot)) { } private String getBranch(Path projectRoot) { - File repo = projectRoot.resolve(".git").normalize().toAbsolutePath().toFile(); + File repo = projectRoot.normalize().toAbsolutePath().toFile(); Optional branchName = gitSupport.getBranchName(repo); if (branchName.isPresent()) { return branchName.get(); @@ -64,7 +64,7 @@ private String getBranch(Path projectRoot) { } private boolean isGitStatusClean(Path projectRoot) { - File repo = projectRoot.resolve(".git").normalize().toAbsolutePath().toFile(); + File repo = projectRoot.normalize().toAbsolutePath().toFile(); GitStatus status = gitSupport.getStatus(repo); return status.isClean(); } From 7f09ce4ecc55bc347aff813ff23887b6f20241c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 11:26:12 +0100 Subject: [PATCH 08/17] Add missing copyright headers --- .../springframework/sbm/shell/ConsolePrinter.java | 15 +++++++++++++++ .../shell/PreconditionVerificationRenderer.java | 15 +++++++++++++++ .../sbm/shell/ScanCommandHeaderRenderer.java | 15 +++++++++++++++ .../sbm/shell/ConsolePrinterTest.java | 15 +++++++++++++++ .../PreconditionVerificationRendererTest.java | 15 +++++++++++++++ .../sbm/shell/ScanCommandHeaderRendererTest.java | 15 +++++++++++++++ .../springframework/sbm/engine/git/GitStatus.java | 15 +++++++++++++++ ...istWhenGitSupportEnabledPreconditionCheck.java | 15 +++++++++++++++ .../JavaSourceDirExistsPreconditionCheck.java | 15 +++++++++++++++ .../JavaVersionPreconditionCheck.java | 15 +++++++++++++++ .../MavenBuildFileExistsPreconditionCheck.java | 15 +++++++++++++++ .../engine/precondition/PreconditionCheck.java | 15 +++++++++++++++ .../precondition/PreconditionCheckResult.java | 15 +++++++++++++++ .../PreconditionVerificationFailedException.java | 15 +++++++++++++++ .../PreconditionVerificationResult.java | 15 +++++++++++++++ .../engine/precondition/PreconditionVerifier.java | 15 +++++++++++++++ .../BuildFileExistsPreconditionCheckTest.java | 15 +++++++++++++++ ...henGitSupportEnabledPreconditionCheckTest.java | 15 +++++++++++++++ .../JavaSourceDirExistsPreconditionCheckTest.java | 15 +++++++++++++++ .../JavaVersionPreconditionCheckTest.java | 15 +++++++++++++++ .../PreconditionCheckVerifierTest.java | 15 +++++++++++++++ .../PreconditionVerifierIntegrationTest.java | 15 +++++++++++++++ 22 files changed, 330 insertions(+) diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java index edc1878c3..44b08f860 100644 --- a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ConsolePrinter.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.shell; import org.springframework.stereotype.Component; diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java index 3a94ccefb..42126a7a0 100644 --- a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/PreconditionVerificationRenderer.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.shell; import org.jline.utils.AttributedStringBuilder; diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java index e2a426d9c..9f27e3843 100644 --- a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanCommandHeaderRenderer.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.shell; import org.jline.utils.AttributedStringBuilder; diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java index 656d82902..b180821c5 100644 --- a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ConsolePrinterTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.shell; import org.junit.jupiter.api.Test; diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java index d16619bed..af38da214 100644 --- a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.shell; import org.junit.jupiter.api.Test; diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java index bf8ff5e3e..05166772f 100644 --- a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.shell; import org.junit.jupiter.api.Test; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java index ebdace325..2ffc927fe 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitStatus.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.git; import org.eclipse.jgit.api.Status; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java index eee915721..bc29c2b5c 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import lombok.RequiredArgsConstructor; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheck.java index 97d82ebea..096a0cb0c 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheck.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.springframework.core.io.Resource; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java index e3481e5f5..600130fdc 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheck.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.springframework.core.io.Resource; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPreconditionCheck.java index fab307071..753f1b230 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/MavenBuildFileExistsPreconditionCheck.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.springframework.core.annotation.Order; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java index b16b4ba9a..8a04dc414 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheck.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java index 5112b0159..a69cfe112 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionCheckResult.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import lombok.Getter; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java index 31a7fda8c..3e989b88d 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationFailedException.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import lombok.Getter; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java index 4339583a5..556934aa0 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerificationResult.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import lombok.Getter; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java index 822f5cff4..2f8a12269 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/PreconditionVerifier.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import lombok.RequiredArgsConstructor; diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java index 29a099483..01d20ac0b 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/BuildFileExistsPreconditionCheckTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.junit.jupiter.api.Test; diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java index 3ca15feb9..6f5d1279e 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheckTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.junit.jupiter.api.Test; diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java index edca2f926..aba7b5e32 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaSourceDirExistsPreconditionCheckTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.junit.jupiter.api.Test; diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java index 86655c745..754eaab2d 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/JavaVersionPreconditionCheckTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.junit.jupiter.api.Test; diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java index e148c1b9b..654b001cc 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionCheckVerifierTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.junit.jupiter.api.Test; diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java index cf45aefac..31e4d79aa 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.sbm.engine.precondition; import org.eclipse.jgit.api.Git; From f5cb82aa8f7bb4ad4ef1b0c98963b311b6e66453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 11:30:49 +0100 Subject: [PATCH 09/17] Run license header check on every push --- .github/workflows/check-license-headers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-license-headers.yml b/.github/workflows/check-license-headers.yml index cdcbca488..b2b90505a 100644 --- a/.github/workflows/check-license-headers.yml +++ b/.github/workflows/check-license-headers.yml @@ -1,7 +1,7 @@ name: Check License Lines on: push: - branches: [main] + branches: [**] jobs: check-license-lines: runs-on: ubuntu-latest From 57168b825ad3d5cb36af297bc85b8cf04b978b7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 11:31:14 +0100 Subject: [PATCH 10/17] Run license header check on every push --- .github/workflows/check-license-headers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-license-headers.yml b/.github/workflows/check-license-headers.yml index b2b90505a..627e359b7 100644 --- a/.github/workflows/check-license-headers.yml +++ b/.github/workflows/check-license-headers.yml @@ -1,7 +1,7 @@ name: Check License Lines on: push: - branches: [**] + branches: [*] jobs: check-license-lines: runs-on: ubuntu-latest From 0c5535ea200326852e017d7f6a05b9454334e4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 11:34:28 +0100 Subject: [PATCH 11/17] Run license header check on every push --- .github/workflows/check-license-headers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-license-headers.yml b/.github/workflows/check-license-headers.yml index 627e359b7..4d00e7f8d 100644 --- a/.github/workflows/check-license-headers.yml +++ b/.github/workflows/check-license-headers.yml @@ -1,7 +1,7 @@ name: Check License Lines on: push: - branches: [*] + branches: '**' jobs: check-license-lines: runs-on: ubuntu-latest From 5874b188720421408dcf2fd590501a4bfe0a2061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 11:42:56 +0100 Subject: [PATCH 12/17] Run maven build on every push --- .github/workflows/mvn-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/mvn-build.yml b/.github/workflows/mvn-build.yml index 2fd433ddc..c89dbdc69 100644 --- a/.github/workflows/mvn-build.yml +++ b/.github/workflows/mvn-build.yml @@ -1,5 +1,7 @@ name: Java CI on: + push: + branches: '**' pull_request: branches: - main From 09023461323341c2fb4dd5c2d3dff9c1aa8b72f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 12:09:14 +0100 Subject: [PATCH 13/17] Fix test --- .../DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java | 2 +- .../precondition/PreconditionVerifierIntegrationTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java index bc29c2b5c..846cb68ba 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java @@ -79,7 +79,7 @@ private String getBranch(Path projectRoot) { } private boolean isGitStatusClean(Path projectRoot) { - File repo = projectRoot.normalize().toAbsolutePath().toFile(); + File repo = projectRoot.resolve(".git").normalize().toAbsolutePath().toFile(); GitStatus status = gitSupport.getStatus(repo); return status.isClean(); } diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java index 31e4d79aa..16a792523 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java @@ -118,7 +118,7 @@ void allChecksSucceed(@TempDir Path tempDir) throws IOException { Git git = gitSupport.initGit(repo); gitSupport.add(repo, "*"); gitSupport.commit(repo, "initial commit"); - Resource gitResource = createResource(gitDir); + Resource gitResource = createResource(gitDir.toAbsolutePath().normalize()); List resources = List.of(javaResource, buildFileResource, gitResource); From 22f4da1ac66dd8d145f9a08e3b0d351abe222e06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 12:11:23 +0100 Subject: [PATCH 14/17] Run GitHub Actions on every push --- .github/workflows/check-license-headers.yml | 6 +++--- .github/workflows/mvn-build.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-license-headers.yml b/.github/workflows/check-license-headers.yml index 8174a3034..6a3cf9390 100644 --- a/.github/workflows/check-license-headers.yml +++ b/.github/workflows/check-license-headers.yml @@ -2,9 +2,9 @@ name: Check License Lines on: push: branches: '**' - pull_request: - branches: - - main +# pull_request: +# branches: +# - main jobs: check-license-lines: runs-on: ubuntu-latest diff --git a/.github/workflows/mvn-build.yml b/.github/workflows/mvn-build.yml index c89dbdc69..a84d26fbc 100644 --- a/.github/workflows/mvn-build.yml +++ b/.github/workflows/mvn-build.yml @@ -2,9 +2,9 @@ name: Java CI on: push: branches: '**' - pull_request: - branches: - - main +# pull_request: +# branches: +# - main jobs: build: runs-on: ubuntu-latest From 8f97bbd3f43609d8669cbe9c928e7f2df9c50507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 13:47:09 +0100 Subject: [PATCH 15/17] Fix test --- .../sbm/shell/PreconditionVerificationRendererTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java index af38da214..0f15b6d7b 100644 --- a/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/shell/PreconditionVerificationRendererTest.java @@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat; class PreconditionVerificationRendererTest { + @Test void renderPreconditionCheckResult() { PreconditionVerificationRenderer sut = new PreconditionVerificationRenderer(); @@ -42,7 +43,7 @@ void renderPreconditionCheckResult() { String s = sut.renderPreconditionCheckResults(checkResult); assertThat(s).isEqualTo("\u001B[30;1m\n" + "\n" + - "Checked preconditions for '/Users/fkrueger/git/spring-boot-migrator-oss/experimental/applications/spring-shell/foo'\n" + + "Checked preconditions for '" +projectRoot+ "'\n" + "\u001B[32;1m[ok]\u001B[0m passed\n" + "\u001B[93;1m [!]\u001B[0m warn\n" + "\u001B[91;1m [X]\u001B[0m failed\n" + From 7c20f47874e18fa97e674b0f2b971f6e505f236a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 14:09:22 +0100 Subject: [PATCH 16/17] Fix error when displaying the list of applicable recipes --- .../springframework/sbm/shell/RecipeRenderer.java | 15 ++++++++++----- .../sbm/engine/git/GitSupport.java | 3 +++ ...istWhenGitSupportEnabledPreconditionCheck.java | 3 +-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/RecipeRenderer.java b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/RecipeRenderer.java index 6fba3be5b..fd5d9e478 100644 --- a/applications/spring-shell/src/main/java/org/springframework/sbm/shell/RecipeRenderer.java +++ b/applications/spring-shell/src/main/java/org/springframework/sbm/shell/RecipeRenderer.java @@ -15,12 +15,12 @@ */ package org.springframework.sbm.shell; -import org.springframework.sbm.engine.recipe.Recipe; -import org.springframework.sbm.engine.recipe.RecipeAutomation; import org.jline.utils.AttributedString; import org.jline.utils.AttributedStringBuilder; import org.jline.utils.AttributedStyle; import org.jline.utils.Colors; +import org.springframework.sbm.engine.recipe.Recipe; +import org.springframework.sbm.engine.recipe.RecipeAutomation; import org.springframework.stereotype.Component; import java.util.List; @@ -37,13 +37,16 @@ public AttributedString renderRecipesList(String noRecipesTitle, String title, L if (foundRecipes.isEmpty()) { builder.append(noRecipesTitle); } else { + AttributedString titleString = renderTitle(title); + builder.append(titleString); AttributedString emojiMapping = renderEmojiMapping(); builder.append(emojiMapping); foundRecipes.forEach(recipe -> this.buildRecipePresentation(builder, recipe)); - AttributedString titleString = renderTitle(title); - builder.append(titleString); - builder.append("\n\n"); + + builder.append("\n"); + builder.append("Run command '> apply recipe-name' to apply a recipe."); + builder.append("\n"); } return builder.toAttributedString(); } @@ -71,7 +74,9 @@ public AttributedStringBuilder buildRecipePresentation(AttributedStringBuilder b private AttributedString renderTitle(String title) { AttributedStringBuilder builder = new AttributedStringBuilder(); builder.style(AttributedStyle.DEFAULT.bold()); + builder.append("\n"); builder.append(title); + builder.append("\n\n"); return builder.toAttributedString(); } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java index ce5f0be9b..24cf6bda8 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java @@ -150,6 +150,9 @@ public Repository getRepository(File repo) { */ public static Git initGit(File repo) { try { + if(repo.toPath().toString().endsWith(".git")) { + repo = repo.toPath().getParent().toAbsolutePath().normalize().toFile(); + } return Git.init().setDirectory(repo).call(); } catch (GitAPIException e) { throw new RuntimeException(e); diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java index 846cb68ba..ada775ea2 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java @@ -79,8 +79,7 @@ private String getBranch(Path projectRoot) { } private boolean isGitStatusClean(Path projectRoot) { - File repo = projectRoot.resolve(".git").normalize().toAbsolutePath().toFile(); - GitStatus status = gitSupport.getStatus(repo); + GitStatus status = gitSupport.getStatus(projectRoot.toFile()); return status.isClean(); } From 7d7c839ca4cb540ec02a5f0e58117c24542b6204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kr=C3=BCger?= Date: Wed, 23 Mar 2022 14:29:04 +0100 Subject: [PATCH 17/17] Fix test --- .../precondition/PreconditionVerifierIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java index 16a792523..e84974160 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/engine/precondition/PreconditionVerifierIntegrationTest.java @@ -113,10 +113,10 @@ void allChecksSucceed(@TempDir Path tempDir) throws IOException { applicationProperties.setGitSupportEnabled(true); // .git exists - Path gitDir = projectRoot.resolve(".git"); + Path gitDir = projectRoot; File repo = gitDir.toFile(); Git git = gitSupport.initGit(repo); - gitSupport.add(repo, "*"); + gitSupport.add(repo, "."); gitSupport.commit(repo, "initial commit"); Resource gitResource = createResource(gitDir.toAbsolutePath().normalize());