"""Tests for scripts/install-tools.sh --check-only, run against a copy with stubbed binaries.""" from __future__ import annotations import os import shutil import subprocess from pathlib import Path _SCRIPT = Path(__file__).resolve().parent.parent / "scripts" / "install-tools.sh" _NATIVE_TOOLS = ("trivy", "tflint", "tofu", "terragrunt", "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 _check_only(script: Path, bin_dir: Path) -> subprocess.CompletedProcess: # Only the commands the script itself needs, so real trivy/tofu on this host can't leak in. core = bin_dir.parent / "core" core.mkdir(exist_ok=True) for tool in ("bash", "dirname"): (core / tool).symlink_to(shutil.which(tool)) bin_dir.mkdir(exist_ok=True) return subprocess.run( ["bash", str(script), "--check-only"], capture_output=True, text=True, timeout=60, check=False, env={**os.environ, "PATH": f"{bin_dir}:{core}"}, ) def test_check_only_on_empty_venv_fails_and_names_missing(tmp_path: Path) -> None: script = _skill_copy(tmp_path) r = _check_only(script, tmp_path / "bin") assert r.returncode != 0 for name in ("python-hcl2", "trivy", "tflint", "tofu", "terragrunt"): assert name in r.stdout, 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) _stub(script.parent.parent / ".venv" / "bin", "python") bin_dir = tmp_path / "bin" for tool in _NATIVE_TOOLS: _stub(bin_dir, tool) r = _check_only(script, bin_dir) assert r.returncode == 0, r.stdout + r.stderr