mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 11:49:28 +00:00
Wire HarnessX as an optional, SHA-pinned extra with a lazy capability guard, keeping the core install zero-dependency. - pyproject: add [project.optional-dependencies] harnessx pinned to commit 274c512 (Darwin-Agent/HarnessX). Core dependencies stays []. uv_build emits `Requires-Dist: harnessx @ git+...@<sha> ; extra == 'harnessx'` + `Provides-Extra: harnessx` (verified via uv build); release ships to GitHub Releases, not PyPI, so the direct-reference is fine. - harness_ext.py: the capability seam. has_harnessx() probes via find_spec (never imports harnessx); require_harnessx() imports lazily on demand and raises HarnessXUnavailableError with install guidance when absent. Every Phase 3+ HarnessX path routes through here so heavy imports stay cold by default. - uv.lock refreshed: the universal lock now resolves the harnessx tree (149 pkgs) but `uv sync --group dev` installs only 57 — harnessx is NOT importable in the default/CI venv (verified), so CI stays lean and never re-locks. - Tests: core deps empty; the extra is a 40-hex SHA-pinned git URL; importing openultrasast.cli does not import harnessx; has_harnessx probes without importing; require_harnessx raises with guidance when absent. 98 tests pass; ruff + mypy clean; detection gate 93.6%/0% intact. Spec task 5 (5.1 + 5.2) checked off; next is task 6 (build_sast hunter sub-harness). Co-Authored-By: Claude Opus 4.8 <[email protected]>
47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
"""HarnessX optional-extra packaging + capability guard (Phase 3 task 5.2)."""
|
|
|
|
import re
|
|
import sys
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from openultrasast.harness_ext import HARNESSX_EXTRA, HarnessXUnavailableError, has_harnessx, require_harnessx
|
|
|
|
PYPROJECT = tomllib.loads(Path("pyproject.toml").read_text())
|
|
|
|
|
|
def test_core_dependencies_stay_empty() -> None:
|
|
assert PYPROJECT["project"]["dependencies"] == []
|
|
|
|
|
|
def test_harnessx_is_a_sha_pinned_optional_extra() -> None:
|
|
extras = PYPROJECT["project"]["optional-dependencies"]["harnessx"]
|
|
assert len(extras) == 1
|
|
assert re.fullmatch(
|
|
r"harnessx @ git\+https://github\.com/Darwin-Agent/HarnessX\.git@[0-9a-f]{40}",
|
|
extras[0],
|
|
), extras[0]
|
|
|
|
|
|
def test_importing_openultrasast_does_not_import_harnessx() -> None:
|
|
# The big modules (cli, harness_ext) must not eagerly import the heavy extra.
|
|
import openultrasast.cli # noqa: F401
|
|
import openultrasast.harness_ext # noqa: F401
|
|
|
|
assert "harnessx" not in sys.modules
|
|
|
|
|
|
def test_has_harnessx_probes_without_importing() -> None:
|
|
available = has_harnessx()
|
|
assert isinstance(available, bool)
|
|
assert "harnessx" not in sys.modules # find_spec must not import the module
|
|
|
|
|
|
def test_require_harnessx_raises_with_install_guidance_when_absent() -> None:
|
|
if has_harnessx():
|
|
pytest.skip("HarnessX extra is installed in this environment")
|
|
with pytest.raises(HarnessXUnavailableError, match=re.escape(HARNESSX_EXTRA)):
|
|
require_harnessx()
|