mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
pre-push(17.6): install, Docker wrapper and first-run docs
`ousast pre-push install|uninstall [REPO] [--force] [--docker]` ships in the wheel with the hook as package data; it honours core.hooksPath, refuses an existing hook unless --force (which chains it as pre-push.before-ousast), and uninstall restores the chained hook. ops/ousast-docker is a hook-callable script: the repository read-only and the artifact directory at their own paths, stdin passed through, no network, --memory 3g, the GHCR 2.0.1 image by default, advisory exit unless blocking. Help text for every pre-push flag; a first-run guide, settings, skip-reason glossary, CI recipe and full --help in docs/scanning.md; README tiers 1 and 2 pull the published image. The image was not rebuilt: 1.1 GB free, below the 4 GB threshold. Requirements 7.4, 9.6. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
66357ffea1
commit
591818d5fc
@@ -39,6 +39,19 @@ def test_audit_reasons_become_one_plain_line_each():
|
||||
assert sum("could not be established" in line for line in lines) == 1
|
||||
|
||||
|
||||
def test_every_glossary_reason_is_documented_for_users():
|
||||
"""17.6: the skip-reason glossary in docs/scanning.md names every reason the terminal explains."""
|
||||
from pathlib import Path
|
||||
|
||||
from openultrasast.push.explain import _NOVELTY_REASONS, _RESOLUTION, GLOSSARY
|
||||
|
||||
docs = (Path(__file__).resolve().parents[1] / "docs" / "scanning.md").read_text()
|
||||
missing = [key for key in GLOSSARY if key not in docs]
|
||||
missing += [f"resolution:{key}" for key in _RESOLUTION if f"`resolution:{key}`" not in docs]
|
||||
assert not missing, missing
|
||||
assert "base_incomplete" in docs and _NOVELTY_REASONS
|
||||
|
||||
|
||||
def test_unknown_reason_is_still_printed():
|
||||
assert explain(("some_future_reason",)) == ["some future reason (see the details file)"]
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
"""`ousast pre-push install|uninstall` and the hook-callable Docker wrapper (task 17.6, Req 7.4, 9.6)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from test_push_runner import history
|
||||
|
||||
from openultrasast.cli import main
|
||||
from openultrasast.push.install import install, packaged, uninstall
|
||||
|
||||
OPS = Path(__file__).resolve().parents[1] / "ops"
|
||||
|
||||
|
||||
def repo(tmp_path):
|
||||
root, base, head, git = history(tmp_path)
|
||||
git("config", "core.hooksPath", ".custom-hooks")
|
||||
remote = tmp_path / "remote.git"
|
||||
subprocess.run(["git", "init", "--bare", str(remote)], check=True, capture_output=True)
|
||||
git("remote", "add", "origin", str(remote))
|
||||
return root, git
|
||||
|
||||
|
||||
def test_packaged_hook_and_wrapper_are_the_ops_scripts():
|
||||
assert packaged("pre-push") == (OPS / "pre-push").read_bytes()
|
||||
assert packaged("ousast-docker") == (OPS / "ousast-docker").read_bytes()
|
||||
|
||||
|
||||
def test_install_uninstall_through_the_cli_honours_hooks_path(tmp_path, capsys):
|
||||
root, git = repo(tmp_path)
|
||||
assert main(["pre-push", "install", str(root)]) == 0
|
||||
hook = root / ".custom-hooks" / "pre-push"
|
||||
assert hook.read_bytes() == packaged("pre-push") and os.access(hook, os.X_OK)
|
||||
assert git("config", "core.hooksPath") == ".custom-hooks"
|
||||
assert main(["pre-push", "install", str(root)]) == 1 # already installed: refused without --force
|
||||
assert "already installed" in capsys.readouterr().err
|
||||
assert main(["pre-push", "install", str(root), "--force"]) == 0
|
||||
assert main(["pre-push", "uninstall", str(root)]) == 0
|
||||
assert not hook.exists()
|
||||
|
||||
|
||||
def test_existing_hook_is_refused_then_chained_and_restored(tmp_path):
|
||||
root, git = repo(tmp_path)
|
||||
hooks = root / ".custom-hooks"
|
||||
hooks.mkdir()
|
||||
log = tmp_path / "prior-input"
|
||||
original = f'#!/bin/sh\ncat > "{log}"\nexit 0\n'.encode()
|
||||
(hooks / "pre-push").write_bytes(original)
|
||||
(hooks / "pre-push").chmod(0o755)
|
||||
code, lines = install(root)
|
||||
assert code == 1 and "existing pre-push hook" in lines[0] and (hooks / "pre-push").read_bytes() == original
|
||||
code, lines = install(root, force=True)
|
||||
assert code == 0 and (hooks / "pre-push.before-ousast").read_bytes() == original
|
||||
env = {**os.environ, "OUSAST_COMMAND": "ousast-not-installed-anywhere", "OUSAST_ARTIFACT_DIR": str(tmp_path / "a")}
|
||||
pushed = subprocess.run(["git", "-C", str(root), "push", "origin", "HEAD:refs/heads/main"], env=env, capture_output=True)
|
||||
assert pushed.returncode == 0 and "refs/heads/main" in log.read_text()
|
||||
code, _ = uninstall(root)
|
||||
assert code == 0 and (hooks / "pre-push").read_bytes() == original
|
||||
assert not (hooks / "pre-push.before-ousast").exists()
|
||||
code, lines = uninstall(root)
|
||||
assert code == 1 and "not written by OpenUltraSAST" in lines[0]
|
||||
|
||||
|
||||
def fake_docker(tmp_path, *, inspect=0, run=0):
|
||||
bin_dir = tmp_path / "bin"
|
||||
bin_dir.mkdir()
|
||||
record = tmp_path / "docker-args"
|
||||
stdin = tmp_path / "docker-stdin"
|
||||
script = f'#!/bin/sh\nif [ "$1" = image ]; then exit {inspect}; fi\nprintf "%s\\n" "$@" > "{record}"\ncat > "{stdin}"\nexit {run}\n'
|
||||
(bin_dir / "docker").write_text(script)
|
||||
(bin_dir / "docker").chmod(0o755)
|
||||
return bin_dir, record, stdin
|
||||
|
||||
|
||||
def test_docker_install_routes_the_hook_through_the_wrapper_with_stdin_and_mounts(tmp_path):
|
||||
root, git = repo(tmp_path)
|
||||
assert install(root, docker=True)[0] == 0
|
||||
bin_dir, record, stdin = fake_docker(tmp_path)
|
||||
artifacts = tmp_path / "artifacts"
|
||||
env = {**os.environ, "PATH": f"{bin_dir}{os.pathsep}{os.environ['PATH']}", "OUSAST_ARTIFACT_DIR": str(artifacts)}
|
||||
env.pop("OUSAST_COMMAND", None)
|
||||
pushed = subprocess.run(["git", "-C", str(root), "push", "origin", "HEAD:refs/heads/main"], env=env, capture_output=True)
|
||||
assert pushed.returncode == 0, pushed.stderr
|
||||
args = record.read_text().splitlines()
|
||||
real = str(root.resolve())
|
||||
assert args[:2] == ["run", "--rm"] and "-i" in args and "--network" in args and "none" in args
|
||||
assert f"{real}:{real}:ro" in args and str(artifacts.resolve()) + ":" + str(artifacts.resolve()) in args
|
||||
assert args[args.index("-w") + 1] == real
|
||||
assert "ghcr.io/norandom/openultrasast:2.0.1" in args and "pre-push" in args and "--remote" in args
|
||||
assert stdin.read_text().startswith("HEAD ") and "refs/heads/main" in stdin.read_text()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("inspect", "run", "needle"), [(1, 0, "is not present"), (0, 125, "could not start")])
|
||||
def test_wrapper_failures_never_block(tmp_path, inspect, run, needle):
|
||||
bin_dir, _, _ = fake_docker(tmp_path, inspect=inspect, run=run)
|
||||
env = {**os.environ, "PATH": f"{bin_dir}{os.pathsep}{os.environ['PATH']}", "OUSAST_ARTIFACT_DIR": str(tmp_path / "artifacts")}
|
||||
result = subprocess.run(
|
||||
[str(OPS / "ousast-docker"), "pre-push", ".", "--artifact", str(tmp_path / "x" / "r.json")],
|
||||
env=env,
|
||||
cwd=tmp_path,
|
||||
input=b"",
|
||||
capture_output=True,
|
||||
)
|
||||
assert result.returncode == 0 and needle.encode() in result.stdout
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("mode", "status", "expected"), [("blocking", 1, 1), ("advisory", 1, 0), ("advisory", 2, 0)])
|
||||
def test_only_explicit_blocking_passes_a_nonzero_exit_through(tmp_path, mode, status, expected):
|
||||
bin_dir, _, _ = fake_docker(tmp_path, run=status)
|
||||
env = {
|
||||
**os.environ,
|
||||
"PATH": f"{bin_dir}{os.pathsep}{os.environ['PATH']}",
|
||||
"OUSAST_ARTIFACT_DIR": str(tmp_path / "artifacts"),
|
||||
"OUSAST_PUSH_MODE": mode,
|
||||
}
|
||||
result = subprocess.run([str(OPS / "ousast-docker"), "pre-push", "."], env=env, cwd=tmp_path, input=b"", capture_output=True)
|
||||
assert result.returncode == expected
|
||||
|
||||
|
||||
def test_hook_passes_optional_settings_only_when_set():
|
||||
text = (OPS / "pre-push").read_text()
|
||||
assert '--engine "$OUSAST_PUSH_ENGINE"' in text and 'if [ -n "${OUSAST_PUSH_ENGINE:-}" ]' in text
|
||||
Reference in New Issue
Block a user