From 44aaf183e741469e3e999c01ed61b52788bffcee Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Sun, 19 Jan 2025 15:50:22 +0100 Subject: [PATCH] updated version to improve the code a bit --- example.py | 3 + setup.py | 2 +- tree_structurer/__main__.py | 5 +- tree_structurer/cpp/tree_structurer.cpp | 107 +++++++++++++++++++----- tree_structurer/cpp/tree_structurer.hpp | 1 + 5 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 example.py diff --git a/example.py b/example.py new file mode 100644 index 0000000..c0e7345 --- /dev/null +++ b/example.py @@ -0,0 +1,3 @@ +import tree_structurer + +tree_structurer.get_structure() \ No newline at end of file diff --git a/setup.py b/setup.py index 2b98270..264db61 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ tree_structurer_module = Extension( setup( name='tree_structurer', - version='0.0.2', + version='0.0.4', description='A module for analyzing directory structures', ext_modules=[tree_structurer_module], packages=['tree_structurer'], diff --git a/tree_structurer/__main__.py b/tree_structurer/__main__.py index 3407a6e..cb5c6d4 100644 --- a/tree_structurer/__main__.py +++ b/tree_structurer/__main__.py @@ -14,11 +14,8 @@ def main(): try: if args.verbose: print(f"Analyzing directory: {args.path}") - - # Create tree structurer instance create_tree_structurer() - - # Get and print structure + # Get and print structure directly structure = get_structure(args.path) for line in structure: print(line) diff --git a/tree_structurer/cpp/tree_structurer.cpp b/tree_structurer/cpp/tree_structurer.cpp index 933012b..028cdb0 100644 --- a/tree_structurer/cpp/tree_structurer.cpp +++ b/tree_structurer/cpp/tree_structurer.cpp @@ -5,24 +5,74 @@ namespace fs = std::filesystem; bool TreeStructurer::should_ignore_dir(const std::string& dirname) { - return dirname[0] == '.' || - dirname[0] == '_'|| - dirname.find("build") != std::string::npos || - dirname == "venv" || - dirname == "myenv" || - dirname == "build"; + static const std::vector ignore_list = { + "build", "venv", "myenv", "dist", "node_modules", "CMakeFiles", + ".git", ".idea", ".vscode", "__pycache__" + }; + + return dirname[0] == '.' || + dirname[0] == '_' || // This will catch __pycache__ and _directories + std::find(ignore_list.begin(), ignore_list.end(), dirname) != ignore_list.end(); } bool TreeStructurer::should_ignore_file(const std::string& filename) { - return filename[0] == '.'; + static const std::vector ignore_extensions = { + ".pyc", ".pyo", ".pyd", ".so", ".dll", ".dylib", + ".o", ".obj", ".a", ".lib" + }; + + if (filename[0] == '.') return true; + + fs::path path(filename); + std::string ext = path.extension().string(); + return std::find(ignore_extensions.begin(), ignore_extensions.end(), ext) != ignore_extensions.end(); +} + +std::vector TreeStructurer::get_filtered_paths(const fs::path& start) { + std::vector paths; + + for(const auto& entry : fs::recursive_directory_iterator(start)) { + const auto& path = entry.path(); + bool should_include = true; + + for(auto it = path.begin(); it != path.end(); ++it) { + if(should_ignore_dir(it->string())) { + should_include = false; + break; + } + } + + if(should_include) { + if(fs::is_directory(path)) { + if(!should_ignore_dir(path.filename().string())) { + paths.push_back(path); + } + } else { + if(!should_ignore_file(path.filename().string())) { + paths.push_back(path); + } +} + } + } + + std::sort(paths.begin(), paths.end()); + return paths; } std::string TreeStructurer::create_indent(int level) { - return std::string(4 * level, ' '); + if (level == 0) return ""; + + std::string indent; + for (int i = 0; i < level - 1; ++i) { + indent += "│ "; + } + indent += "├─ "; + return indent; } + std::string TreeStructurer::get_relative_path(const fs::path& path, const fs::path& base) { - const fs::path rel = fs::relative(path, base); + fs::path rel = fs::relative(path, base); return rel.string(); } @@ -31,27 +81,38 @@ std::vector TreeStructurer::get_directory_structure(const std::stri fs::path start = startpath.empty() ? fs::current_path() : fs::path(startpath); try { - std::vector paths; - for(const auto& entry : fs::recursive_directory_iterator(start)) { - paths.push_back(entry.path()); - } + result.push_back(start.filename().string() + "/"); - // Sort paths for consistent output - std::sort(paths.begin(), paths.end()); + auto paths = get_filtered_paths(start); + std::vector is_last_at_level(256, false); - for(const auto& path : paths) { + for (size_t i = 0; i < paths.size(); ++i) { + const auto& path = paths[i]; std::string rel_path = get_relative_path(path, start); int level = std::count(rel_path.begin(), rel_path.end(), fs::path::preferred_separator); - if(fs::is_directory(path)) { - if(!should_ignore_dir(path.filename().string())) { - result.push_back(create_indent(level) + path.filename().string() + "/"); - } - } else { - if(!should_ignore_file(path.filename().string())) { - result.push_back(create_indent(level) + path.filename().string()); + bool is_last = (i == paths.size() - 1) || + (i < paths.size() - 1 && + std::count(get_relative_path(paths[i + 1], start).begin(), + get_relative_path(paths[i + 1], start).end(), + fs::path::preferred_separator) <= level); + + is_last_at_level[level] = is_last; + + std::string line; + for (int j = 0; j < level; ++j) { + if (j == level - 1) { + line += is_last ? "└── " : "├── "; + } else { + line += is_last_at_level[j] ? " " : "│ "; } } + + line += path.filename().string(); + if(fs::is_directory(path)) { + line += "/"; + } + result.push_back(line); } } catch (const fs::filesystem_error& e) { throw std::runtime_error("Failed to access directory: " + std::string(e.what())); diff --git a/tree_structurer/cpp/tree_structurer.hpp b/tree_structurer/cpp/tree_structurer.hpp index 102bf26..06c51be 100644 --- a/tree_structurer/cpp/tree_structurer.hpp +++ b/tree_structurer/cpp/tree_structurer.hpp @@ -13,4 +13,5 @@ private: bool should_ignore_file(const std::string& filename); std::string create_indent(int level); std::string get_relative_path(const std::filesystem::path& path, const std::filesystem::path& base); + std::vector get_filtered_paths(const std::filesystem::path& start); }; \ No newline at end of file