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.
81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
import json
|
|
|
|
from scripts.manifest import (
|
|
Manifest, Finding, ChangedFile, LanguageBreakdown,
|
|
PackageDiff, PackageEntry, PackageUpgrade, ToolStat,
|
|
)
|
|
|
|
|
|
def test_finding_to_dict_includes_all_fields():
|
|
f = Finding(
|
|
tool="bandit", rule_id="B608", severity="high",
|
|
file="src/api.py", line=45, end_line=45,
|
|
message="Possible SQL injection.",
|
|
cwe="CWE-89", fix_suggestion=None,
|
|
)
|
|
d = f.to_dict()
|
|
assert d["tool"] == "bandit"
|
|
assert d["rule_id"] == "B608"
|
|
assert d["cwe"] == "CWE-89"
|
|
assert "fix_suggestion" in d
|
|
|
|
|
|
def test_changed_file_serializes_ranges():
|
|
cf = ChangedFile(
|
|
path="src/api.py", language="python",
|
|
added_lines=[(12, 14), (45, 45)],
|
|
)
|
|
d = cf.to_dict()
|
|
assert d["language"] == "python"
|
|
assert d["added_lines"] == [[12, 14], [45, 45]]
|
|
|
|
|
|
def test_manifest_roundtrip():
|
|
m = Manifest(
|
|
mode="local", base_ref="origin/main", head_ref="HEAD",
|
|
default_branch="main",
|
|
language_breakdown=LanguageBreakdown(
|
|
python=2, javascript=0, typescript=0, csharp=0,
|
|
skipped_files=[],
|
|
),
|
|
changed_files=[],
|
|
findings=[],
|
|
package_diffs={
|
|
"python": PackageDiff(),
|
|
"javascript": PackageDiff(),
|
|
"csharp": PackageDiff(),
|
|
},
|
|
tool_stats={},
|
|
tools_unavailable={},
|
|
errors=[],
|
|
)
|
|
payload = json.loads(m.to_json())
|
|
assert payload["mode"] == "local"
|
|
assert payload["language_breakdown"]["python"] == 2
|
|
assert payload["findings"] == []
|
|
|
|
|
|
def test_package_diff_with_entries():
|
|
pd = PackageDiff(
|
|
added=[PackageEntry(name="pyyaml", version="6.0")],
|
|
removed=[],
|
|
upgraded=[PackageUpgrade(name="requests", from_version="2.28.0", to_version="2.31.0")],
|
|
)
|
|
d = pd.to_dict()
|
|
assert d["added"][0]["name"] == "pyyaml"
|
|
assert d["upgraded"][0]["from"] == "2.28.0"
|
|
assert d["upgraded"][0]["to"] == "2.31.0"
|
|
|
|
|
|
def test_tool_stat_records_ran_and_counts():
|
|
ts = ToolStat(ran=True, pre_filter=47, post_filter=3)
|
|
d = ts.to_dict()
|
|
assert d == {"ran": True, "pre_filter": 47, "post_filter": 3}
|
|
|
|
|
|
def test_tool_stat_records_skip_reason():
|
|
ts = ToolStat(ran=False, reason="not on PATH")
|
|
d = ts.to_dict()
|
|
assert d["ran"] is False
|
|
assert d["reason"] == "not on PATH"
|