diff --git a/services/api/COMMUNITY_EXPORT_MANIFEST.json b/services/api/COMMUNITY_EXPORT_MANIFEST.json index 7f7081f..72dabc1 100644 --- a/services/api/COMMUNITY_EXPORT_MANIFEST.json +++ b/services/api/COMMUNITY_EXPORT_MANIFEST.json @@ -115,10 +115,10 @@ "sha256": "7918b810601db56cf0fcd7028aada0259b86aea62bbe0fabcd99abee9287f85f" }, { - "bytes": 13588, + "bytes": 13605, "mode": "0644", "path": "scripts/audit_community_export.py", - "sha256": "49dac3a6d4d4bc55d8da2e63a30117fcffee3f7d38d098f06c54b0ee2c352cb6" + "sha256": "ac8ccfba8771b9c20da2e77946a76c1c3754792c0dd7701367f31cc5a7f5f445" }, { "bytes": 9906, @@ -1753,10 +1753,10 @@ "sha256": "9c39d2dde3e3e73d27ebbc465ac41a38bb84bbde626a418c60dd29a8324dca0a" }, { - "bytes": 3007, + "bytes": 3766, "mode": "0644", "path": "tests/test_export_manifest.py", - "sha256": "5b6d8522a1f1131406150a5f0f354eb7a580951785080b0367898d4d71df4770" + "sha256": "301c79b130743012d1b8be313aed21f03c037b968102cf16a0963b239f406cd5" }, { "bytes": 2730, diff --git a/services/api/scripts/audit_community_export.py b/services/api/scripts/audit_community_export.py index d1bb77e..e62a461 100644 --- a/services/api/scripts/audit_community_export.py +++ b/services/api/scripts/audit_community_export.py @@ -103,7 +103,7 @@ "/repository-", ) MANIFEST_NAME = "COMMUNITY_EXPORT_MANIFEST.json" -IGNORED_DIRS = {".mypy_cache", ".pytest_cache", ".ruff_cache", "__pycache__", "data"} +IGNORED_DIRS = {".mypy_cache", ".pytest_cache", ".ruff_cache", ".venv", "__pycache__", "data", "venv"} def sha256(path: Path) -> str: diff --git a/services/api/tests/test_export_manifest.py b/services/api/tests/test_export_manifest.py index 7029f6c..0dda7cc 100644 --- a/services/api/tests/test_export_manifest.py +++ b/services/api/tests/test_export_manifest.py @@ -86,3 +86,23 @@ def test_refreshing_keeps_the_export_identity(tmp_path: Path) -> None: assert payload["source_commit"] == AUDIT.EXPECTED_SOURCE_COMMIT assert payload["format"] == 1 + + +def test_local_virtualenv_directories_are_ignored(tmp_path: Path) -> None: + _tree(tmp_path, "before\n") + baseline = [path.relative_to(tmp_path) for path in AUDIT.included_files(tmp_path)] + + for dirname in (".venv", "venv"): + bindir = tmp_path / dirname / "bin" + bindir.mkdir(parents=True) + (bindir / "python").symlink_to("/usr/bin/python3") + + assert [path.relative_to(tmp_path) for path in AUDIT.included_files(tmp_path)] == baseline + + +def test_symlink_outside_ignored_directories_is_rejected(tmp_path: Path) -> None: + _tree(tmp_path, "before\n") + (tmp_path / "linked.txt").symlink_to(tmp_path / "kept.txt") + + with pytest.raises(RuntimeError, match=r"^symlink:linked\.txt$"): + AUDIT.included_files(tmp_path)