Files
claude-plugin/plugins/reviews/skills/audit-code/tests/test_manifest_maintainability.py
T
mroberts 37fc3fb291 Fix audit tool bootstrap and add per-run preflight
audit-code install-tools.sh:
- Buffer the opengrep release JSON before grep -m1; curl died with (23)
  under pipefail when grep quit early.
- Use ${m}: in the PowerShell block; $m: parsed as a scope-qualified var.
- On Arch, skip paru/yay when pacman -Q shows every package installed,
  since --needed still invokes sudo.
- Add --check-only (fast, installs nothing, non-zero naming missing tools)
  and --user-only (no system package managers, no sudo).

log-run.py (both skills): put the skill dir on sys.path so running it as
a script from any cwd no longer raises ModuleNotFoundError.

audit-terraform: move deps from requirements.txt into pyproject
dependency groups and add scripts/install-tools.sh (uv sync --group tools,
then check trivy, tflint, tofu, terragrunt, gh).

Both SKILL.md files gain a 0.5 Preflight step and call scripts through
uv run --project ${SKILL_DIR}. tools_unavailable is now a map of tool to
exact install command; audit-terraform skips trivy when absent and stops
with an install hint instead of crashing when tofu/terragrunt is missing.
2026-09-22 15:21:28 -05:00

76 lines
3.6 KiB
Python

from scripts.slicing import slice_for_agent
def _manifest():
return {
"mode": "local",
"base_ref": "origin/main",
"head_ref": "HEAD",
"default_branch": "main",
"language_breakdown": {"python": 1, "javascript": 0, "typescript": 0, "csharp": 0, "skipped_files": []},
"changed_files": [{"path": "foo.py", "language": "python", "added_lines": [[10, 50]]}],
"findings": [
{"tool": "vulture", "rule_id": "vulture:90pct", "severity": "medium",
"file": "foo.py", "line": 10, "end_line": 10, "message": "unused function"},
{"tool": "radon", "rule_id": "radon:cc=12", "severity": "medium",
"file": "foo.py", "line": 20, "end_line": 40, "message": "high CCN"},
{"tool": "interrogate", "rule_id": "interrogate:missing-docstring", "severity": "low",
"file": "foo.py", "line": 5, "end_line": 5, "message": "missing docstring"},
{"tool": "lizard", "rule_id": "lizard:ccn=22", "severity": "high",
"file": "foo.py", "line": 30, "end_line": 60, "message": "high CCN"},
{"tool": "knip", "rule_id": "knip:dead-export", "severity": "medium",
"file": "src/a.ts", "line": 12, "end_line": 12, "message": "unused export"},
{"tool": "jscpd", "rule_id": "jscpd:clone-40lines", "severity": "medium",
"file": "foo.py", "line": 100, "end_line": 140, "message": "duplicate"},
{"tool": "bandit", "rule_id": "B608", "severity": "high",
"file": "foo.py", "line": 5, "end_line": 5, "message": "SQL injection"},
{"tool": "ruff-idiom", "rule_id": "C901", "severity": "medium",
"file": "foo.py", "line": 50, "end_line": 50, "message": "too complex"},
{"tool": "ruff-idiom", "rule_id": "PLR0915", "severity": "medium",
"file": "foo.py", "line": 60, "end_line": 60, "message": "too many statements"},
{"tool": "ruff-idiom", "rule_id": "SIM117", "severity": "low",
"file": "foo.py", "line": 70, "end_line": 70, "message": "combine with"},
{"tool": "ruff-idiom", "rule_id": "PLR0913", "severity": "medium",
"file": "foo.py", "line": 80, "end_line": 80, "message": "too many args"},
],
"package_diffs": {"python": {"added": [], "removed": [], "upgraded": []}},
"tool_stats": {},
"tools_unavailable": {},
"errors": [],
}
def test_maintainability_slice_includes_dedicated_tools():
sliced = slice_for_agent(_manifest(), "maintainability")
tools = {f["tool"] for f in sliced["findings"]}
assert tools >= {"vulture", "radon", "interrogate", "lizard", "knip", "jscpd"}
def test_maintainability_slice_includes_complexity_idioms():
sliced = slice_for_agent(_manifest(), "maintainability")
rules = {f["rule_id"] for f in sliced["findings"]}
assert "C901" in rules
assert "PLR0915" in rules
def test_maintainability_slice_excludes_security_and_dependency():
sliced = slice_for_agent(_manifest(), "maintainability")
tools = {f["tool"] for f in sliced["findings"]}
assert "bandit" not in tools
def test_maintainability_slice_excludes_non_complexity_idioms():
sliced = slice_for_agent(_manifest(), "maintainability")
rules = {f["rule_id"] for f in sliced["findings"]}
assert "SIM117" not in rules
assert "PLR0913" not in rules
def test_consistency_slice_excludes_complexity_idioms():
sliced = slice_for_agent(_manifest(), "consistency")
rules = {f["rule_id"] for f in sliced["findings"]}
assert "C901" not in rules
assert "PLR0915" not in rules
assert "SIM117" in rules
assert "PLR0913" in rules