"""Tests for scripts/install-tools.sh, run against a copy with stubbed binaries.""" from __future__ import annotations import os import re import shutil import subprocess from pathlib import Path import pytest _SCRIPT = Path(__file__).resolve().parent.parent / "scripts" / "install-tools.sh" _VENV_TOOLS = ("bandit", "ruff", "mypy", "pip-audit", "vulture", "radon", "interrogate", "lizard", "opengrep") _NATIVE_TOOLS = ("gitleaks", "osv-scanner", "gh") def _skill_copy(tmp_path: Path) -> Path: skill = tmp_path / "skill" (skill / "scripts").mkdir(parents=True) shutil.copy(_SCRIPT, skill / "scripts" / "install-tools.sh") return skill / "scripts" / "install-tools.sh" def _stub(bin_dir: Path, name: str, body: str) -> None: bin_dir.mkdir(parents=True, exist_ok=True) path = bin_dir / name path.write_text("#!/usr/bin/env bash\n" + body) path.chmod(0o755) def _run(cmd: str, bin_dir: Path, **env: str) -> subprocess.CompletedProcess: return subprocess.run( ["bash", "-c", cmd], capture_output=True, text=True, timeout=60, check=False, env={**os.environ, "PATH": f"{bin_dir}:/usr/bin:/bin", **env}, ) def test_opengrep_tag_lookup_survives_large_release_body(tmp_path: Path) -> None: script = _skill_copy(tmp_path) bin_dir = tmp_path / "bin" log = tmp_path / "curl.log" _stub(bin_dir, "curl", r''' for ((i = 1; i <= $#; i++)); do if [[ "${!i}" == "-o" ]]; then j=$((i + 1)); echo "$*" >> "$CURL_LOG"; echo bin > "${!j}"; exit 0 fi done printf '{\n "tag_name": "v9.9.9",\n "body": "' head -c 2000000 /dev/zero | tr '\0' x printf '"\n}\n' ''') r = _run(f"source {script} && install_opengrep", bin_dir, CURL_LOG=str(log)) assert r.returncode == 0, r.stderr assert (script.parent.parent / ".venv" / "bin" / "opengrep").is_file() assert "/releases/download/v9.9.9/" in log.read_text() @pytest.mark.skipif(shutil.which("pwsh") is None, reason="pwsh not installed") def test_powershell_module_block_parses() -> None: block = re.search(r"pwsh -NoProfile -NonInteractive -Command '(.*?)'", _SCRIPT.read_text(), re.DOTALL) assert block, "embedded pwsh -Command block not found" check = ( "$errs = $null; " "[System.Management.Automation.Language.Parser]::ParseInput($env:PS_BLOCK, [ref]$null, [ref]$errs) | Out-Null; " "$errs | ForEach-Object { $_.Message }; exit $errs.Count" ) r = subprocess.run( ["pwsh", "-NoProfile", "-NonInteractive", "-Command", check], capture_output=True, text=True, timeout=60, check=False, env={**os.environ, "PS_BLOCK": block.group(1)}, ) assert r.returncode == 0, r.stdout + r.stderr def _arch_stubs(bin_dir: Path, installed: set[str]) -> None: _stub(bin_dir, "pacman", f''' [[ "$1" == "-Q" ]] || {{ echo "pacman $*" >> "$CALLS"; exit 1; }} case "$2" in {"|".join(installed) or "__none__"}) exit 0 ;; *) exit 1 ;; esac ''') _stub(bin_dir, "paru", 'echo "paru $*" >> "$CALLS"\n') _stub(bin_dir, "sudo", 'echo "sudo $*" >> "$CALLS"; exit 1\n') def test_arch_skips_helper_when_everything_installed(tmp_path: Path) -> None: script = _skill_copy(tmp_path) bin_dir = tmp_path / "bin" calls = tmp_path / "calls.log" _arch_stubs(bin_dir, {"gitleaks", "github-cli", "osv-scanner"}) r = _run(f"source {script} && install_native_arch", bin_dir, CALLS=str(calls)) assert r.returncode == 0, r.stderr assert not calls.exists(), calls.read_text() def test_arch_helper_installs_only_missing_packages(tmp_path: Path) -> None: script = _skill_copy(tmp_path) bin_dir = tmp_path / "bin" calls = tmp_path / "calls.log" _arch_stubs(bin_dir, {"gitleaks", "github-cli"}) r = _run(f"source {script} && install_native_arch", bin_dir, CALLS=str(calls)) assert r.returncode == 0, r.stderr assert calls.read_text().splitlines() == ["paru -S --needed --noconfirm osv-scanner"] def test_check_only_on_empty_venv_fails_and_names_missing_tools(tmp_path: Path) -> None: script = _skill_copy(tmp_path) bin_dir = tmp_path / "bin" for tool in _NATIVE_TOOLS: _stub(bin_dir, tool, "") r = _run(f"bash {script} --check-only", bin_dir) assert r.returncode != 0 assert "lizard" in r.stdout assert "opengrep" in r.stdout assert not (script.parent.parent / ".venv").exists(), "--check-only must not install anything" def test_check_only_passes_when_everything_present(tmp_path: Path) -> None: script = _skill_copy(tmp_path) venv_bin = script.parent.parent / ".venv" / "bin" for tool in _VENV_TOOLS: _stub(venv_bin, tool, "") bin_dir = tmp_path / "bin" for tool in _NATIVE_TOOLS: _stub(bin_dir, tool, "") r = _run(f"bash {script} --check-only", bin_dir) assert r.returncode == 0, r.stdout + r.stderr