Created
December 19, 2025 05:35
-
-
Save anjoismysign/76a86d389500f2a6959e8e1fbb514cb3 to your computer and use it in GitHub Desktop.
Java ProjectTreeGenerator (MIT License)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.IOException; | |
| import java.nio.file.Files; | |
| import java.nio.file.Path; | |
| import java.nio.file.Paths; | |
| import java.util.Comparator; | |
| import java.util.List; | |
| import java.util.function.Predicate; | |
| import java.util.stream.Collectors; | |
| import java.util.stream.Stream; | |
| public class ProjectTreeGenerator { | |
| public static final String LAST_CONNECTOR = "└── "; | |
| public static final String NOT_LAST_CONNECTOR = "├── "; | |
| public static final String LAST_CHILD_PREFIX = " "; | |
| public static final String NOT_LAST_CHILD_PREFIX = "│ "; | |
| public static String generate(String rootPathString, int maxDepth) { | |
| Path rootPath = Paths.get(rootPathString).toAbsolutePath().normalize(); | |
| // Define common exclusions: "build", "target", ".git", ".gradle", etc. | |
| Predicate<Path> defaultExclusions = path -> { | |
| String name = path.getFileName().toString(); | |
| return name.equals("build") || | |
| name.equals("target") || | |
| name.equals(".git") || | |
| name.equals(".gradle") || | |
| name.equals(".idea") || | |
| name.endsWith(".iml")|| | |
| name.endsWith(".DS_Store")|| | |
| name.endsWith(".vscode"); | |
| }; | |
| StringBuilder builder = new StringBuilder(); | |
| generateRecursive(rootPath, defaultExclusions, maxDepth, 0, "", builder); | |
| String text = builder.toString(); | |
| return text.substring(0, text.length() - 1); | |
| } | |
| private static void generateRecursive( | |
| Path currentDir, | |
| Predicate<Path> isExcluded, | |
| int maxDepth, | |
| int currentDepth, | |
| String prefix, | |
| StringBuilder result | |
| ) { | |
| if (currentDepth >= maxDepth) { | |
| return; | |
| } | |
| try (Stream<Path> stream = Files.list(currentDir)) { | |
| List<Path> entries = stream | |
| .filter(path -> !isExcluded.test(path)) // IGNORE "build" here | |
| .sorted(Comparator.comparing((Path p) -> !Files.isDirectory(p)) | |
| .thenComparing(p -> p.getFileName().toString().toLowerCase())) | |
| .collect(Collectors.toList()); | |
| for (int index = 0; index < entries.size(); index++) { | |
| Path entry = entries.get(index); | |
| boolean isLast = (index == entries.size() - 1); | |
| boolean isDirectory = Files.isDirectory(entry); | |
| String connector = isLast ? LAST_CONNECTOR : NOT_LAST_CONNECTOR; | |
| result.append(prefix).append(connector).append(entry.getFileName()).append("\n"); | |
| if (isDirectory) { | |
| String childPrefix = prefix + (isLast ? LAST_CHILD_PREFIX : NOT_LAST_CHILD_PREFIX); | |
| generateRecursive(entry, isExcluded, maxDepth, currentDepth + 1, childPrefix, result); | |
| } | |
| } | |
| } catch (IOException e) { | |
| // Silently skip directories that can't be read (system folders) | |
| } | |
| } | |
| public static void main(String[] args) { | |
| //Generating a tree from current directory with 15 maxDepth | |
| String tree = ProjectTreeGenerator.generate(".", 15); | |
| System.out.println("# Project structure"); | |
| System.out.println(tree); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment