From 1323644f630c2c42336f786ed163dc9692d4c05c Mon Sep 17 00:00:00 2001 From: Samuel SCHNEGG Date: Tue, 7 Oct 2025 21:55:52 +0200 Subject: [PATCH 1/2] Skipped children simplification --- CHANGELOG.md | 4 ++ README.md | 10 ++--- .../example/ProjectStructure.java | 6 +-- .../renderer/file/DefaultFileFormatter.java | 44 +------------------ .../scanner/DefaultPathToTreeScanner.java | 21 +-------- .../scanner/TreeEntry.java | 12 +---- .../ChildLimitDynamicTest.java | 8 ++-- .../ChildLimitStaticTest.java | 8 ++-- .../FileTreePrettyPrinterBuilderTest.java | 2 +- .../jfiletreeprettyprinter/FilteringTest.java | 8 ++-- .../jfiletreeprettyprinter/MaxDepthTest.java | 4 +- 11 files changed, 32 insertions(+), 95 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16a35cc..553305e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- ## [0.0.6] - Unreleased +### Changed +- Child limit: do not print skipped children count +- Max depth: do not print "max depth reached" + --- ## [0.0.5] - 2025-10-04 diff --git a/README.md b/README.md index 374048c..43b37ea 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,7 @@ var prettyPrinter = FileTreePrettyPrinter.builder() > *Idea for a future version: option to allow custom emoji mapping* ## Child limit -You can set a fixed limit to the number of children displayed for each directory. +You can set a fixed limit to the number of children displayed for each directory. Each directory and file that pass filter (if set) counts for one. ```java // Example: ChildLimitStatic.java @@ -202,13 +202,13 @@ child_limit_static/ │ ├─ file_1_1 │ ├─ file_1_2 │ ├─ file_1_3 -│ └─ ... (2 files skipped) +│ └─ ... ├─ folder_2/ │ ├─ file_2_1 │ ├─ file_2_2 │ ├─ file_2_3 -│ └─ ... (2 files skipped) -└─ ... (3 directories skipped) +│ └─ ... +└─ ... ``` @@ -237,7 +237,7 @@ child_limit_dynamic/ │ ├─ file_1_4 │ └─ file_1_5 └─ node_modules/ - └─ ... (9 files skipped) + └─ ... ``` ## Line extension diff --git a/src/example/java/io/github/computerdaddyguy/jfiletreeprettyprinter/example/ProjectStructure.java b/src/example/java/io/github/computerdaddyguy/jfiletreeprettyprinter/example/ProjectStructure.java index 0bbf98b..10b3978 100644 --- a/src/example/java/io/github/computerdaddyguy/jfiletreeprettyprinter/example/ProjectStructure.java +++ b/src/example/java/io/github/computerdaddyguy/jfiletreeprettyprinter/example/ProjectStructure.java @@ -114,11 +114,11 @@ public static void main(String[] args) { ├─ 📂 src/main/java/ │ └─ 📂 io/github/computerdaddyguy/jfiletreeprettyprinter/ │ ├─ 📂 renderer/ - │ │ └─ ... (5 files and 2 directories skipped) + │ │ └─ ... │ ├─ 📂 scanner/ - │ │ └─ ... (4 files skipped) + │ │ └─ ... │ ├─ ☕ FileTreePrettyPrinter.java // Main entry point - │ └─ ... (10 files skipped) + │ └─ ... ├─ 🗺️ CHANGELOG.md ├─ 📖 CONTRIBUTING.md ├─ 📄 LICENSE diff --git a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/renderer/file/DefaultFileFormatter.java b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/renderer/file/DefaultFileFormatter.java index 272f988..b4b5d2f 100644 --- a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/renderer/file/DefaultFileFormatter.java +++ b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/renderer/file/DefaultFileFormatter.java @@ -5,7 +5,6 @@ import io.github.computerdaddyguy.jfiletreeprettyprinter.scanner.TreeEntry.MaxDepthReachEntry; import io.github.computerdaddyguy.jfiletreeprettyprinter.scanner.TreeEntry.SkippedChildrenEntry; import java.nio.file.Path; -import java.util.Collection; import java.util.List; import java.util.stream.Collectors; import org.jspecify.annotations.NullMarked; @@ -33,51 +32,12 @@ public String formatFile(FileEntry fileEntry) { @Override public String formatChildLimitReached(SkippedChildrenEntry skippedChildrenEntry) { - return "... (" + childrenAsString(skippedChildrenEntry.getSkippedChildren()) + " skipped)"; + return "..."; } @Override public String formatMaxDepthReached(MaxDepthReachEntry maxDepthReachEntry) { - return "... (max depth reached)"; - } - - private String childrenAsString(Collection notVisited) { - - var dirCount = countDirs(notVisited); - var fileCount = countFiles(notVisited, dirCount); - - var dirText = dirText(dirCount); - var fileText = fileText(fileCount); - - return fileText + (!fileText.isEmpty() && !dirText.isEmpty() ? " and " : "") + dirText; - } - - private long countDirs(Collection notVisited) { - return notVisited.stream().filter(path -> path.toFile().isDirectory()).count(); - } - - private String dirText(long dirCount) { - if (dirCount == 0) { - return ""; - } - if (dirCount == 1) { - return "1 directory"; - } - return dirCount + " directories"; - } - - private long countFiles(Collection notVisited, long dirCount) { - return notVisited.size() - dirCount; - } - - private String fileText(long fileCount) { - if (fileCount == 0) { - return ""; - } - if (fileCount == 1) { - return "1 file"; - } - return fileCount + " files"; + return "..."; } } diff --git a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java index 7dfacbb..e7d411e 100644 --- a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java +++ b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java @@ -85,26 +85,7 @@ private List handleDirectoryChildren(Path root, int depth, Path dir, // Loop has early exit? if (pathIterator.hasNext()) { - childEntries.addAll(handleLeftOverChildren(root, depth, pathIterator, filter)); - } - - return childEntries; - } - - private List handleLeftOverChildren(Path root, int depth, Iterator pathIterator, PathMatcher filter) { - var childEntries = new ArrayList(); - - var skippedChildren = new ArrayList(); - while (pathIterator.hasNext()) { - var child = pathIterator.next(); - var childEntry = handle(root, depth + 1, child, filter); - if (childEntry != null) { // Is null if no children file is retained by filter - skippedChildren.add(child); - } - } - if (!skippedChildren.isEmpty()) { - var childrenSkippedEntry = new SkippedChildrenEntry(skippedChildren); - childEntries.add(childrenSkippedEntry); + childEntries.add(new SkippedChildrenEntry()); } return childEntries; diff --git a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java index 1c0ffec..dd14b14 100644 --- a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java +++ b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java @@ -2,7 +2,6 @@ import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collection; import java.util.List; import java.util.Objects; import org.jspecify.annotations.NullMarked; @@ -62,19 +61,12 @@ public BasicFileAttributes getAttrs() { final class SkippedChildrenEntry implements TreeEntry { - final Collection skippedChildren; - - public SkippedChildrenEntry(List skippedChildren) { - this.skippedChildren = Objects.requireNonNull(skippedChildren, "skippedChildren is null"); + public SkippedChildrenEntry() { } @Override public String toString() { - return "SkippedChildrenEntry[skippedChildren: " + skippedChildren.stream().map(Path::getFileName).toList() + "]"; - } - - public Collection getSkippedChildren() { - return skippedChildren; + return "SkippedChildrenEntry[]"; } } diff --git a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitDynamicTest.java b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitDynamicTest.java index 30e1928..27ced1c 100644 --- a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitDynamicTest.java +++ b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitDynamicTest.java @@ -59,12 +59,12 @@ void nominal() { targetPath/ ├─ limit_1/ │ ├─ file1 - │ └─ ... (4 files skipped) + │ └─ ... ├─ limit_3/ │ ├─ file1 │ ├─ file2 │ ├─ file3 - │ └─ ... (2 files skipped) + │ └─ ... └─ simpleDir/ ├─ file1 ├─ file2 @@ -91,7 +91,7 @@ void limited_dir_1() { targetPath/ └─ limit_1/ ├─ file1 - └─ ... (4 files skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } @@ -114,7 +114,7 @@ void limited_dir_3() { ├─ file1 ├─ file2 ├─ file3 - └─ ... (2 files skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } diff --git a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitStaticTest.java b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitStaticTest.java index 5f99c26..66ebc5e 100644 --- a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitStaticTest.java +++ b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/ChildLimitStaticTest.java @@ -66,7 +66,7 @@ void dirWith_1_extra_file() { ├─ file1 ├─ file2 ├─ file3 - └─ ... (1 file skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } @@ -79,7 +79,7 @@ void dirWith_2_extra_files() { ├─ file1 ├─ file2 ├─ file3 - └─ ... (2 files skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } @@ -92,7 +92,7 @@ void dirWith_2_extra_files_and_1_extra_folder() { ├─ file1 ├─ file2 ├─ file3 - └─ ... (2 files and 1 directory skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } @@ -105,7 +105,7 @@ void dirWith_2_extra_files_and_2_extra_folders() { ├─ file1 ├─ file2 ├─ file3 - └─ ... (2 files and 2 directories skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } diff --git a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FileTreePrettyPrinterBuilderTest.java b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FileTreePrettyPrinterBuilderTest.java index b3502e8..e95132e 100644 --- a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FileTreePrettyPrinterBuilderTest.java +++ b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FileTreePrettyPrinterBuilderTest.java @@ -26,7 +26,7 @@ void withOptions_overrides() { targetPath/ ├─ file1 ├─ file2 - └─ ... (1 file and 3 directories skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } diff --git a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FilteringTest.java b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FilteringTest.java index da30094..5666c20 100644 --- a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FilteringTest.java +++ b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/FilteringTest.java @@ -93,8 +93,8 @@ void example_childLimit_1() { filtering/ ├─ dir_with_java_files/ │ ├─ file_B.java - │ └─ ... (1 file skipped) - └─ ... (1 file and 2 directories skipped)"""; + │ └─ ... + └─ ..."""; assertThat(result).isEqualTo(expected); } @@ -118,7 +118,7 @@ void example_childLimit_2() { │ │ ├─ file_G.java │ │ └─ file_J.java │ └─ nested_dir_with_no_java_file/ - └─ ... (1 file and 1 directory skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } @@ -143,7 +143,7 @@ void example_childLimit_3() { │ │ └─ file_J.java │ └─ nested_dir_with_no_java_file/ ├─ dir_with_no_java_file/ - └─ ... (1 file skipped)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } diff --git a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/MaxDepthTest.java b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/MaxDepthTest.java index 31aa450..36111d6 100644 --- a/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/MaxDepthTest.java +++ b/src/test/java/io/github/computerdaddyguy/jfiletreeprettyprinter/MaxDepthTest.java @@ -62,7 +62,7 @@ void withCompactDirectories() { var expected = """ targetPath/ └─ level1/level2/ - └─ ... (max depth reached)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } @@ -99,7 +99,7 @@ void nominal() { ├─ file1#2 ├─ file1#3 └─ level2/ - └─ ... (max depth reached)"""; + └─ ..."""; assertThat(result).isEqualTo(expected); } From d63bf860828823c20a5bbfb9932f0cc27a809846 Mon Sep 17 00:00:00 2001 From: Samuel SCHNEGG Date: Tue, 7 Oct 2025 22:01:23 +0200 Subject: [PATCH 2/2] Fix Sonar --- .../scanner/DefaultPathToTreeScanner.java | 2 +- .../jfiletreeprettyprinter/scanner/TreeEntry.java | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java index e7d411e..6392019 100644 --- a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java +++ b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/DefaultPathToTreeScanner.java @@ -85,7 +85,7 @@ private List handleDirectoryChildren(Path root, int depth, Path dir, // Loop has early exit? if (pathIterator.hasNext()) { - childEntries.add(new SkippedChildrenEntry()); + childEntries.add(new SkippedChildrenEntry(dir)); } return childEntries; diff --git a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java index dd14b14..4d2e408 100644 --- a/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java +++ b/src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/scanner/TreeEntry.java @@ -61,12 +61,15 @@ public BasicFileAttributes getAttrs() { final class SkippedChildrenEntry implements TreeEntry { - public SkippedChildrenEntry() { + final Path dir; + + public SkippedChildrenEntry(Path dir) { + this.dir = Objects.requireNonNull(dir, "dir is null"); } @Override public String toString() { - return "SkippedChildrenEntry[]"; + return "SkippedChildrenEntry[dir: " + dir.getFileName() + "]"; } }