From 08430ad1afb0308c5a8a439062cca87693ef9973 Mon Sep 17 00:00:00 2001 From: Tobias Haindl Date: Sat, 22 Jun 2024 14:11:56 +0200 Subject: [PATCH] GH-644 - Add option to clean the output directory in documentation generation. --- .../modulith/docs/Documenter.java | 40 +++++++++++++++--- .../modulith/docs/DocumenterTest.java | 42 +++++++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/spring-modulith-docs/src/main/java/org/springframework/modulith/docs/Documenter.java b/spring-modulith-docs/src/main/java/org/springframework/modulith/docs/Documenter.java index 5b6ee6a1..be9a9d45 100644 --- a/spring-modulith-docs/src/main/java/org/springframework/modulith/docs/Documenter.java +++ b/spring-modulith-docs/src/main/java/org/springframework/modulith/docs/Documenter.java @@ -183,14 +183,14 @@ public class Documenter { *
  • The Module Canvas for each module.
  • * * - * @param options must not be {@literal null}. + * @param diagramOptions must not be {@literal null}. * @param canvasOptions must not be {@literal null}. * @return the current instance, will never be {@literal null}. */ - public Documenter writeDocumentation(DiagramOptions options, CanvasOptions canvasOptions) { + public Documenter writeDocumentation(DiagramOptions diagramOptions, CanvasOptions canvasOptions) { if (this.options.clean) { - clear(); + clearOutputFolder(); } return writeModulesAsPlantUml(options) @@ -610,10 +610,15 @@ public class Documenter { .createComponentView(container, prefix + options.toString(), ""); } - private void clear() { + private void clearOutputFolder() { - try { - Files.deleteIfExists(Paths.get(options.outputFolder)); + Path outputPath = Paths.get(options.outputFolder); + if (!outputPath.toFile().exists()) { + return; + } + + try (Stream paths = Files.walk(outputPath)) { + paths.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); } catch (IOException o_O) { throw new RuntimeException(o_O); } @@ -1289,14 +1294,37 @@ public class Documenter { this.clean = clean; } + /** + * Creates a default {@link Options} instance configuring a default output folder based on the detected build tool (see {@link Options#DEFAULT_LOCATION}). + * Use {@link #withOutputFolder(String)} if you want to customize the output folder. + * Per default the output folder is wiped before any files are written to it. + * Use {@link #withoutClean()} to disable cleaning of the output folder. + * + * @return will never be {@literal null}. + * @see #withoutClean() + * @see #withOutputFolder(String) + */ public static Options defaults() { return new Options(DEFAULT_LOCATION, true); } + /** + * Disables the cleaning of the output folder before any file is written. + * + * @return will never be {@literal null}. + */ public Options withoutClean() { return new Options(outputFolder, false); } + /** + * Configures the output folder for the created files. + * The given directory is wiped before any files are written to it. + * + * @param folder if null the default location based on the detected build tool will be used (see {@link Options#DEFAULT_LOCATION}). + * The given folder will be created if it does not exist already. Existing folders are supported as well. + * @return will never be {@literal null}. + */ public Options withOutputFolder(String folder) { return new Options(folder, clean); } diff --git a/spring-modulith-integration-test/src/test/java/org/springframework/modulith/docs/DocumenterTest.java b/spring-modulith-integration-test/src/test/java/org/springframework/modulith/docs/DocumenterTest.java index ec6cc624..d3c1deb9 100644 --- a/spring-modulith-integration-test/src/test/java/org/springframework/modulith/docs/DocumenterTest.java +++ b/spring-modulith-integration-test/src/test/java/org/springframework/modulith/docs/DocumenterTest.java @@ -27,10 +27,12 @@ import java.util.Optional; import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.springframework.modulith.core.ApplicationModule; import org.springframework.modulith.core.ApplicationModules; import org.springframework.modulith.core.DependencyType; import org.springframework.modulith.docs.Documenter.DiagramOptions; +import org.springframework.modulith.docs.Documenter.Options; import org.springframework.util.function.ThrowingConsumer; import com.acme.myproject.Application; @@ -139,6 +141,46 @@ class DocumenterTest { }); } + @Test + void shouldCleanOutputLocation(@TempDir Path outputDirectory) throws IOException { + + var filePath = createTestFile(outputDirectory); + var nestedFiledPath = createTestFileInSubdirectory(outputDirectory); + + new Documenter(ApplicationModules.of(Application.class), outputDirectory.toString()).writeDocumentation(); + + assertThat(filePath).doesNotExist(); + assertThat(nestedFiledPath).doesNotExist(); + assertThat(Files.list(outputDirectory)).isNotEmpty(); + } + + @Test + void shouldNotCleanOutputLocation(@TempDir Path outputDirectory) throws IOException { + + var filePath = createTestFile(outputDirectory); + var nestedFiledPath = createTestFileInSubdirectory(outputDirectory); + + new Documenter(ApplicationModules.of(Application.class), + Options.defaults().withOutputFolder(outputDirectory.toString()).withoutClean()) + .writeDocumentation(); + + assertThat(filePath).exists(); + assertThat(nestedFiledPath).exists(); + assertThat(Files.list(outputDirectory)).isNotEmpty(); + } + + private static Path createTestFile(Path tempDir) throws IOException { + return createFile(tempDir.resolve("some-old-module.adoc")); + } + + private static Path createTestFileInSubdirectory(Path tempDir) throws IOException { + return createFile(tempDir.resolve("some-subdirectory").resolve("old-module.adoc")); + } + + private static Path createFile(Path filePath) throws IOException { + return Files.createDirectories(filePath); + } + private static void deleteDirectoryContents(Path path) throws IOException { if (Files.exists(path) && Files.isDirectory(path)) {