prodir/tree_structurer/cpp/tree_structurer.cpp

61 lines
2.1 KiB
C++

#include "tree_structurer.hpp"
#include <algorithm>
#include <filesystem>
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";
}
bool TreeStructurer::should_ignore_file(const std::string& filename) {
return filename[0] == '.';
}
std::string TreeStructurer::create_indent(int level) {
return std::string(4 * level, ' ');
}
std::string TreeStructurer::get_relative_path(const fs::path& path, const fs::path& base) {
const fs::path rel = fs::relative(path, base);
return rel.string();
}
std::vector<std::string> TreeStructurer::get_directory_structure(const std::string& startpath) {
std::vector<std::string> result;
fs::path start = startpath.empty() ? fs::current_path() : fs::path(startpath);
try {
std::vector<fs::path> paths;
for(const auto& entry : fs::recursive_directory_iterator(start)) {
paths.push_back(entry.path());
}
// Sort paths for consistent output
std::sort(paths.begin(), paths.end());
for(const auto& path : paths) {
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());
}
}
}
} catch (const fs::filesystem_error& e) {
throw std::runtime_error("Failed to access directory: " + std::string(e.what()));
}
return result;
}