Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions desloppify/base/discovery/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ def collect_exclude_dirs(
if "*" not in pat:
patterns.add(pat)
patterns.update(p for p in resolved_exclusions if p and "*" not in p)
# External tools (e.g. bandit) match --exclude against absolute walked paths,
# so a relative scan_root — commonpath is often Path(".") — would make every
# exclude silently match nothing. Anchor relative roots to an absolute path
# (matching the .resolve() bandit applies to its own scan target); leave
# already-absolute roots byte-stable so callers' paths are unchanged.
if not scan_root.is_absolute():
scan_root = scan_root.resolve()
return [str(scan_root / p) for p in sorted(patterns) if p]


Expand Down
17 changes: 17 additions & 0 deletions desloppify/tests/detectors/test_external_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1010,3 +1010,20 @@ def test_deduplicates(self, tmp_path):
result = collect_exclude_dirs(tmp_path)
node_entries = [p for p in result if p.endswith("/node_modules")]
assert len(node_entries) == 1

def test_relative_scan_root_yields_absolute_paths(self):
"""A relative scan_root must still yield absolute exclude dirs.

``scan_root_from_files`` derives the root from ``os.path.commonpath``,
which is relative (often ``Path('.')``) when scanning with a relative
``--path``. bandit matches ``--exclude`` against *absolute* walked paths,
so a relative entry like ``.worktrees`` silently excludes nothing — the
bug behind ~2000 phantom B101 findings from worktree copies.
"""
with patch(
"desloppify.base.discovery.source.get_exclusions",
return_value=(".worktrees",),
):
result = collect_exclude_dirs(Path("."))
assert all(Path(p).is_absolute() for p in result), result
assert any(p.endswith("/.worktrees") for p in result), result
8 changes: 8 additions & 0 deletions desloppify/tests/lang/common/test_bash_unused_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

import textwrap

import pytest

from desloppify.languages._framework.treesitter import is_available

pytestmark = pytest.mark.skipif(
not is_available(), reason="tree-sitter-language-pack not installed"
)


def _detect(tmp_path, contents: str):
from desloppify.languages._framework.treesitter.analysis.unused_imports import (
Expand Down
5 changes: 4 additions & 1 deletion desloppify/tests/review/review_commands_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,10 @@ def test_do_run_batches_dry_run_generates_packet_and_prompts(
assert len(packet_files) == 1
blind_packet = tmp_path / ".desloppify" / "review_packet_blind.json"
assert blind_packet.exists()
prompt_files = list(runs_dir.glob("*/prompts/batch-*.md"))
# Sort: prompt files are named batch-1.md, batch-2.md; glob order is
# filesystem-dependent (differs Linux vs macOS) and the assertions
# below assume batch-1 (high_level_elegance, with historical_focus) first.
prompt_files = sorted(runs_dir.glob("*/prompts/batch-*.md"))
assert len(prompt_files) == 2
prompt_text = prompt_files[0].read_text()
assert "Blind packet:" in prompt_text
Expand Down
Loading