develop #24

Merged
Fabel merged 2 commits from develop into main 2025-06-06 19:37:44 +00:00
5 changed files with 98 additions and 50 deletions

View File

@ -93,20 +93,20 @@ my_project/
```plaintext ```plaintext
Analyzing directory: .\my_project\ Analyzing directory: .\my_project\
data/ ├── data/
└── sample_data.csv └── sample_data.csv
docs/ ├── docs/
└── README.md └── README.md
requirements.txt ├── requirements.txt
setup.py ├── setup.py
src/ ├── src/
├── __init__.py ├── __init__.py
├── main.py ├── main.py
└── utils.py └── utils.py
tests/ └── tests/
├── __init__.py ├── __init__.py
├── test_main.py ├── test_main.py
└── test_utils.py └── test_utils.py
``` ```
#### Commands #### Commands

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "prodir" name = "prodir"
version = "1.0.2" version = "1.1.0"
description = "A module for analyzing and creating directory structures" description = "A module for analyzing and creating directory structures"
scripts = {prodir = "prodir.__main__:main"} scripts = {prodir = "prodir.__main__:main"}
dependencies = [] dependencies = []

View File

@ -20,7 +20,7 @@ tree_structurer_module = Extension(
setup( setup(
name='prodir', name='prodir',
version='1.0.2', version='1.1.0',
description='A module for analyzing directory structures', description='A module for analyzing directory structures',
ext_modules=[tree_structurer_module], ext_modules=[tree_structurer_module],
packages=find_packages(where="src"), packages=find_packages(where="src"),

View File

@ -124,24 +124,24 @@ std::vector<fs::path> TreeStructurer::get_filtered_paths(const fs::path& start)
std::vector<std::string> TreeStructurer::get_directory_structure(const std::string& startpath) { std::vector<std::string> TreeStructurer::get_directory_structure(const std::string& startpath) {
std::vector<std::string> result; std::vector<std::string> result;
std::string normalized_path = startpath; std::string normalized_path = startpath;
if (normalized_path.size() >= 2 && if (normalized_path.size() >= 2 &&
(normalized_path.substr(0, 2) == ".\\" || normalized_path.substr(0, 2) == "./")) { (normalized_path.substr(0, 2) == ".\\" || normalized_path.substr(0, 2) == "./")) {
normalized_path = normalized_path.substr(2); normalized_path = normalized_path.substr(2);
} }
fs::path start = normalized_path.empty() ? fs::current_path() : fs::path(normalized_path); fs::path start = normalized_path.empty() ? fs::current_path() : fs::path(normalized_path);
try { try {
if (!fs::exists(start)) { if (!fs::exists(start)) {
throw std::runtime_error("Directory does not exist: " + start.string()); throw std::runtime_error("Directory does not exist: " + start.string());
} }
if (!fs::is_directory(start)) { if (!fs::is_directory(start)) {
throw std::runtime_error("Path is not a directory: " + start.string()); throw std::runtime_error("Path is not a directory: " + start.string());
} }
std::vector<fs::path> paths = get_filtered_paths(start); std::vector<fs::path> paths = get_filtered_paths(start);
std::vector<bool> is_last_per_level; std::vector<bool> is_last_per_level;
// Skip the first path as it's the root // Skip the first path as it's the root
for (size_t i = 1; i < paths.size(); ++i) { for (size_t i = 1; i < paths.size(); ++i) {
fs::path relative = fs::relative(paths[i], start); fs::path relative = fs::relative(paths[i], start);
@ -149,45 +149,93 @@ std::vector<std::string> TreeStructurer::get_directory_structure(const std::stri
for (const auto& comp : relative) { for (const auto& comp : relative) {
components.push_back(comp.string()); components.push_back(comp.string());
} }
// Calculate the current level // Calculate the current level
size_t level = components.size() - 1; size_t level = components.size() - 1;
// Adjust is_last_per_level vector size // Adjust is_last_per_level vector size
while (is_last_per_level.size() <= level) { while (is_last_per_level.size() <= level) {
is_last_per_level.push_back(false); is_last_per_level.push_back(false);
} }
// Determine if this is the last item at its level
bool is_last = (i == paths.size() - 1) ||
(i + 1 < paths.size() &&
fs::relative(paths[i + 1], start).begin()->string() != components[0]);
is_last_per_level[level] = is_last;
// Build the line prefix // Build the line prefix
std::string line; std::string line;
for (size_t j = 0; j < level; ++j) { for (size_t j = 0; j <= level; ++j) {
if (j == level - 1) { if (j == level) {
line += is_last ? "└── " : "├── "; // This is the connector for the current item
bool is_last_sibling = true;
// Look ahead to find next sibling at the same level
for (size_t k = i + 1; k < paths.size(); ++k) {
fs::path next_relative = fs::relative(paths[k], start);
std::vector<std::string> next_components;
for (const auto& comp : next_relative) {
next_components.push_back(comp.string());
}
// Check if it's a sibling (same parent, same level)
if (next_components.size() == components.size()) {
bool same_parent = true;
for (size_t l = 0; l < level; ++l) {
if (l >= next_components.size() || components[l] != next_components[l]) {
same_parent = false;
break;
}
}
if (same_parent) {
is_last_sibling = false;
break;
}
}
}
line += is_last_sibling ? "└── " : "├── ";
} else { } else {
line += is_last_per_level[j] ? " " : ""; // This is a vertical line for parent levels
bool needs_vertical_line = false;
// Check if there are future items that share this ancestor
for (size_t k = i + 1; k < paths.size(); ++k) {
fs::path next_relative = fs::relative(paths[k], start);
std::vector<std::string> next_components;
for (const auto& comp : next_relative) {
next_components.push_back(comp.string());
}
// If next item shares the same path up to level j
if (next_components.size() > j) {
bool shares_ancestor = true;
for (size_t l = 0; l <= j; ++l) {
if (l >= next_components.size() || l >= components.size() ||
components[l] != next_components[l]) {
shares_ancestor = false;
break;
}
}
if (shares_ancestor) {
needs_vertical_line = true;
break;
}
}
}
line += needs_vertical_line ? "" : " ";
} }
} }
// Add the file/directory name // Add the file/directory name
line += components.back(); line += components.back();
if (fs::is_directory(paths[i])) { if (fs::is_directory(paths[i])) {
line += "/"; line += "/";
} }
result.push_back(line); result.push_back(line);
} }
} catch (const fs::filesystem_error& e) { } catch (const fs::filesystem_error& e) {
throw std::runtime_error("Failed to access directory: " + std::string(e.what())); throw std::runtime_error("Failed to access directory: " + std::string(e.what()));
} }
return result; return result;
} }

View File

@ -138,17 +138,17 @@ project/
# Define expected structure with proper tree markers # Define expected structure with proper tree markers
expected_structure = [ expected_structure = [
"LICENSE", "├── LICENSE",
"README.md", "├── README.md",
"config/", "├── config/",
"└── config.yaml", " └── config.yaml",
"pyproject.toml", "├── pyproject.toml",
"setup.py", "├── setup.py",
"src/", "└── src/",
"├── __init__.py", "├── __init__.py",
"├── main.py", "├── main.py",
"├── module1.py", "├── module1.py",
"└── module2.py" " └── module2.py"
] ]
# Get actual structure # Get actual structure