From 6ed873352d316edb647d205046fb2886008a18e1 Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Mon, 20 Jan 2025 13:30:13 +0100 Subject: [PATCH 1/7] fixed readme installation guide --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d86c686..ac29590 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This is a Python package designed to display directory structures in a tree-like To install `tree_structurer`, you can use pip: ```bash -pip install pip install git+https://gitea.fabelous.app/Fabel/Tree-Structurer.git + pip install git+https://gitea.fabelous.app/Fabel/Tree-Structurer.git ``` From 714de8fc81cdb1fd12fc3ceba5bc9a61b5f4a291 Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Mon, 20 Jan 2025 15:43:23 +0100 Subject: [PATCH 2/7] fianlized tests and fixed errors if needed. Including improved error handling --- pytest.ini | 6 ++ setup.cfg | 11 +++ setup.py | 2 +- tests/__init__.py | 0 tests/conftest.py | 33 +++++++++ tests/test_tree_structurer.py | 89 +++++++++++++++++++++++++ tree_structurer/__main__.py | 14 +++- tree_structurer/cpp/tree_structurer.cpp | 61 +++++++++-------- 8 files changed, 185 insertions(+), 31 deletions(-) create mode 100644 pytest.ini create mode 100644 setup.cfg create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_tree_structurer.py diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..b235d1a --- /dev/null +++ b/pytest.ini @@ -0,0 +1,6 @@ +[pytest] +python_files = test_*.py +python_classes = Test* +python_functions = test_* +addopts = -v --tb=short +testpaths = tests \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..39474e9 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,11 @@ +[tool:pytest] +minversion = 6.0 +addopts = -ra -q +testpaths = + tests +python_files = + test_*.py + *_test.py +markers = + slow: marks tests as slow (deselect with '-m "not slow"') + integration: marks tests as integration tests \ No newline at end of file diff --git a/setup.py b/setup.py index 576a701..44c083e 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ tree_structurer_module = Extension( setup( name='tree_structurer', - version='0.0.5', + version='0.0.6', description='A module for analyzing directory structures', ext_modules=[tree_structurer_module], packages=['tree_structurer'], diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..a99412c --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,33 @@ +import os +import pytest +import shutil +from pathlib import Path + +@pytest.fixture +def temp_directory(tmp_path): + """Create a temporary directory structure for testing.""" + # Create main test directory + test_dir = tmp_path / "test_project" + test_dir.mkdir() + + # Create some regular directories + (test_dir / "src").mkdir() + (test_dir / "src" / "utils").mkdir() + (test_dir / "docs").mkdir() + + # Create some files + (test_dir / "src" / "main.py").write_text("print('hello')") + (test_dir / "src" / "utils" / "helper.py").write_text("# helper") + (test_dir / "src" / "__init__.py").touch() + (test_dir / "README.md").write_text("# Test Project") + + # Create some directories that should be ignored + (test_dir / "__pycache__").mkdir() + (test_dir / ".git").mkdir() + (test_dir / "venv").mkdir() + + # Create some files that should be ignored + (test_dir / "src" / "main.pyc").touch() + (test_dir / ".gitignore").touch() + + yield test_dir \ No newline at end of file diff --git a/tests/test_tree_structurer.py b/tests/test_tree_structurer.py new file mode 100644 index 0000000..aade0d0 --- /dev/null +++ b/tests/test_tree_structurer.py @@ -0,0 +1,89 @@ +import pytest +from pathlib import Path +from tree_structurer import create_tree_structurer, get_structure + +def test_basic_structure(temp_directory): + """Test that the basic directory structure is correctly represented.""" + create_tree_structurer() + structure = get_structure(str(temp_directory)) + + # Convert structure to set for easier comparison + structure_set = set(structure) + + # Print actual structure for debugging + print("\nActual structure:") + for line in structure: + print(f"'{line}'") + + # Expected entries (adjusted based on actual implementation) + must_contain = [ + "README.md", + "docs", + "src", + "__init__.py", + "main.py", + "utils", + "helper.py" + ] + + # Check that all required components are present somewhere in the structure + for entry in must_contain: + assert any(entry in line for line in structure), \ + f"Required entry '{entry}' not found in structure" + + # Check that ignored directories/files are not present + ignored_patterns = { + "__pycache__", + ".git", + "venv", + "main.pyc", + ".gitignore" + } + + for entry in structure: + for ignored in ignored_patterns: + assert ignored not in entry, \ + f"Ignored pattern '{ignored}' found in entry '{entry}'" + +def test_empty_directory(tmp_path): + """Test handling of an empty directory.""" + create_tree_structurer() + try: + structure = get_structure(str(tmp_path)) + pytest.fail("Expected an exception for nonexistent directory") + except Exception as e: # Changed from RuntimeError + assert "Directory is empty" in str(e) + +def test_nonexistent_directory(): + """Test handling of a nonexistent directory.""" + create_tree_structurer() + try: + get_structure("/path/that/does/not/exist") + pytest.fail("Expected an exception for nonexistent directory") + except Exception as e: # Changed from RuntimeError + assert "Directory does not exist" in str(e) + +def test_nested_structure(temp_directory): + """Test deeply nested directory structure.""" + # Create deep nested structure + deep_path = temp_directory / "deep" / "nested" / "structure" + deep_path.mkdir(parents=True) + (deep_path / "test.py").touch() + + create_tree_structurer() + structure = get_structure(str(temp_directory)) + + # Print actual structure for debugging + print("\nDeep structure:") + for line in structure: + print(f"'{line}'") + + # Verify that all components of the deep path are present + deep_components = ["deep", "nested", "structure", "test.py"] + for component in deep_components: + assert any(component in line for line in structure), \ + f"Deep component '{component}' not found in structure" + + # Verify tree-like formatting is present + assert any("└" in line or "├" in line for line in structure), \ + "Tree-like formatting characters not found in structure" diff --git a/tree_structurer/__main__.py b/tree_structurer/__main__.py index cb5c6d4..35fdff9 100644 --- a/tree_structurer/__main__.py +++ b/tree_structurer/__main__.py @@ -14,15 +14,23 @@ def main(): try: if args.verbose: print(f"Analyzing directory: {args.path}") + create_tree_structurer() - # Get and print structure directly structure = get_structure(args.path) + for line in structure: print(line) except Exception as e: - print(f"Error: {e}", file=sys.stderr) + error_msg = str(e) + if "Directory does not exist" in error_msg: + print(f"Error: The specified directory does not exist: {args.path}", file=sys.stderr) + elif "Directory is empty" in error_msg: + print(f"Error: The specified directory is empty: {args.path}", file=sys.stderr) + elif "Path is not a directory" in error_msg: + print(f"Error: The specified path is not a directory: {args.path}", file=sys.stderr) + else: + print(f"Error: {error_msg}", file=sys.stderr) sys.exit(1) - if __name__ == "__main__": main() \ No newline at end of file diff --git a/tree_structurer/cpp/tree_structurer.cpp b/tree_structurer/cpp/tree_structurer.cpp index 5e35bed..2ef3be2 100644 --- a/tree_structurer/cpp/tree_structurer.cpp +++ b/tree_structurer/cpp/tree_structurer.cpp @@ -66,29 +66,41 @@ std::vector TreeStructurer::get_filtered_paths(const fs::path& start) fs::directory_options options = fs::directory_options::skip_permission_denied; try { - if (fs::exists(start) && fs::is_directory(start)) { - paths.push_back(start); + if (!fs::exists(start)) { + throw std::runtime_error("Directory does not exist: " + start.string()); + } + + if (!fs::is_directory(start)) { + throw std::runtime_error("Path is not a directory: " + start.string()); + } - for (const auto& entry : fs::recursive_directory_iterator(start, options)) { - const auto& path = entry.path(); + paths.push_back(start); - bool should_skip = false; - for (const auto& component : path) { - if (should_ignore_dir(component.string())) { - should_skip = true; - break; - } + // Check if directory is empty + bool is_empty = fs::directory_iterator(start) == fs::directory_iterator(); + if (is_empty) { + throw std::runtime_error("Directory is empty: " + start.string()); + } + + for (const auto& entry : fs::recursive_directory_iterator(start, options)) { + const auto& path = entry.path(); + + bool should_skip = false; + for (const auto& component : path) { + if (should_ignore_dir(component.string())) { + should_skip = true; + break; } - if (should_skip) continue; + } + if (should_skip) continue; - if (entry.is_directory()) { - if (!should_ignore_dir(path.filename().string())) { - paths.push_back(path); - } - } else { - if (!should_ignore_file(path.filename().string())) { - paths.push_back(path); - } + if (entry.is_directory()) { + if (!should_ignore_dir(path.filename().string())) { + paths.push_back(path); + } + } else { + if (!should_ignore_file(path.filename().string())) { + paths.push_back(path); } } } @@ -113,14 +125,9 @@ std::vector TreeStructurer::get_directory_structure(const std::stri try { auto paths = get_filtered_paths(start); - if (paths.empty()) return result; - - // Don't add the start directory name to the output - // Remove the following lines: - // if (start != fs::current_path()) { - // result.push_back(start.filename().string()); - // } - + if (paths.empty()) { + throw std::runtime_error("No valid files or directories found in: " + start.string()); + } std::vector is_last_at_level(256, false); for (size_t i = 1; i < paths.size(); ++i) { From 85719a21998a20e58d6296af64f8455333896efd Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Mon, 20 Jan 2025 15:46:36 +0100 Subject: [PATCH 3/7] added missing yaml files --- .gitea/embed.yaml | 37 +++++++++++++++++++++++++++++++++++++ .gitea/test.yaml | 35 +++++++++++++++++++++++++++++++++++ requirements-dev.txt | 0 3 files changed, 72 insertions(+) create mode 100644 .gitea/embed.yaml create mode 100644 .gitea/test.yaml create mode 100644 requirements-dev.txt diff --git a/.gitea/embed.yaml b/.gitea/embed.yaml new file mode 100644 index 0000000..8530b55 --- /dev/null +++ b/.gitea/embed.yaml @@ -0,0 +1,37 @@ +name: Run VectorLoader Script + +on: + push: + branches: + - main + +jobs: + Explore-Gitea-Actions: + runs-on: ubuntu-latest + container: catthehacker/ubuntu:act-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.11.7' + + - name: Clone additional repository + run: | + git config --global credential.helper cache + git clone https://fabel:${{ secrets.CICD }}@gitea.fabelous.app/fabel/VectorLoader.git + + - name: Install dependencies + run: | + cd VectorLoader + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run vectorizing + env: + VECTORDB_TOKEN: ${{ secrets.VECTORDB_TOKEN }} + run: | + cd VectorLoader + python -m src.run --full diff --git a/.gitea/test.yaml b/.gitea/test.yaml new file mode 100644 index 0000000..d000616 --- /dev/null +++ b/.gitea/test.yaml @@ -0,0 +1,35 @@ +name: Gitea Actions For Tree-Structurer +run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 +on: [push] + +jobs: + Explore-Gitea-Actions: + runs-on: ubuntu-latest + container: catthehacker/ubuntu:act-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11.7' + + - name: Cache pip and model + uses: actions/cache@v3 + with: + path: | + ~/.cache/pip + ./fabel + key: ${{ runner.os }}-pip-model-${{ hashFiles('requirements-dev.txt')}} + + restore-keys: | + ${{ runner.os }}-pip-model- + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements-dev.txt + - name: Run tests + run: | + pytest tests \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..e69de29 From 364d8dd516b0549ce782ee03c144ef8c9372ecdd Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Mon, 20 Jan 2025 15:49:29 +0100 Subject: [PATCH 4/7] removed spaces --- .gitea/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/test.yaml b/.gitea/test.yaml index d000616..b8e7193 100644 --- a/.gitea/test.yaml +++ b/.gitea/test.yaml @@ -32,4 +32,4 @@ jobs: pip install -r requirements-dev.txt - name: Run tests run: | - pytest tests \ No newline at end of file + pytest tests \ No newline at end of file From bd5ed3853e6156f3cb066fd4d121ef8668b35483 Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Mon, 20 Jan 2025 15:50:01 +0100 Subject: [PATCH 5/7] correctly stored the yamls --- .gitea/{ => workflows}/embed.yaml | 0 .gitea/{ => workflows}/test.yaml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .gitea/{ => workflows}/embed.yaml (100%) rename .gitea/{ => workflows}/test.yaml (100%) diff --git a/.gitea/embed.yaml b/.gitea/workflows/embed.yaml similarity index 100% rename from .gitea/embed.yaml rename to .gitea/workflows/embed.yaml diff --git a/.gitea/test.yaml b/.gitea/workflows/test.yaml similarity index 100% rename from .gitea/test.yaml rename to .gitea/workflows/test.yaml From c10404deea07b11ac9c618f4ab7150282876e6c8 Mon Sep 17 00:00:00 2001 From: Falko Victor Habel Date: Mon, 20 Jan 2025 16:24:25 +0000 Subject: [PATCH 6/7] .gitea/workflows/test.yaml aktualisiert --- .gitea/workflows/test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index b8e7193..682048f 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -32,4 +32,5 @@ jobs: pip install -r requirements-dev.txt - name: Run tests run: | + pip insall -e . pytest tests \ No newline at end of file From baf2261bb37a3946e6b9e036d35644b822c174f4 Mon Sep 17 00:00:00 2001 From: Falko Victor Habel Date: Mon, 20 Jan 2025 16:32:43 +0000 Subject: [PATCH 7/7] .gitea/workflows/test.yaml aktualisiert --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 682048f..4989700 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -32,5 +32,5 @@ jobs: pip install -r requirements-dev.txt - name: Run tests run: | - pip insall -e . + pip install -e . pytest tests \ No newline at end of file