Update the CLI to use a safe, best-effort console emitter so logging issues cannot fail the run

This commit is contained in:
2026-05-04 13:04:36 -05:00
parent a70f481a93
commit e797e3d9ff
4 changed files with 163 additions and 9 deletions

View File

@@ -1,3 +1,6 @@
import importlib.machinery
import importlib.util
import io
import os
import shutil
import subprocess
@@ -11,6 +14,15 @@ ROOT = Path(__file__).resolve().parents[1]
LAUNCHER = ROOT / "audita"
def _load_launcher_module():
loader = importlib.machinery.SourceFileLoader("audita_launcher", str(LAUNCHER))
spec = importlib.util.spec_from_file_location("audita_launcher", LAUNCHER, loader=loader)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def test_root_launcher_exists_and_is_executable():
assert LAUNCHER.is_file()
assert os.access(LAUNCHER, os.X_OK)
@@ -73,3 +85,33 @@ def test_root_launcher_preserves_child_exit_code_and_writes_fallback_error_log(t
assert "audita: subprocess exited with status 120" in result.stderr
run_dir = next(work_dir.iterdir())
assert (run_dir / "error.log").exists()
class _BrokenWriter:
def write(self, _message):
raise OSError(9, "Bad file descriptor")
def flush(self):
raise OSError(9, "Bad file descriptor")
def test_root_launcher_falls_back_to_stdout_when_stderr_is_invalid(monkeypatch, tmp_path):
launcher = _load_launcher_module()
work_dir = tmp_path / "work"
stdout_capture = io.StringIO()
monkeypatch.setattr(launcher.shutil, "which", lambda _name: None)
monkeypatch.setattr(
launcher.sys,
"argv",
["audita", "process", "transcript.json", "--glossary", "glossary.yaml", "--work-dir", str(work_dir)],
)
monkeypatch.setattr(launcher.sys, "stderr", _BrokenWriter())
monkeypatch.setattr(launcher.sys, "stdout", stdout_capture)
exit_code = launcher.main()
assert exit_code == 1
assert "audita: error: uv is required to run this launcher" in stdout_capture.getvalue()
run_dir = next(work_dir.iterdir())
assert (run_dir / "error.log").exists()