"""Portable source selection and independently maintained workbook expectations. Ordinary tests may omit external input. Setting ROUND87_REQUIRED=1 makes input mandatory; a configured but missing/changed file always fails. CLI tools pass required=True and never fall back to another workbook. """ from __future__ import annotations import hashlib import json import os from pathlib import Path DEFAULT_EXPECTATIONS = Path(__file__).resolve().parent / "fixtures" / "planning-workbook-acceptance.json" def load_expectations(path: str | Path | None = None) -> dict: selected = Path(path or os.environ.get("ROUND87_EXPECTATIONS") or DEFAULT_EXPECTATIONS) data = json.loads(selected.read_text(encoding="utf-8")) if data.get("schemaVersion") != 1 or not isinstance(data.get("sourceSha256"), str): raise ValueError("Invalid workbook acceptance manifest") return data def resolve_source(source: str | Path | None = None, *, required: bool | None = None, expectations: dict | None = None) -> Path | None: selected = source or os.environ.get("ROUND87_SOURCE") required = required if required is not None else os.environ.get("ROUND87_REQUIRED") == "1" if not selected: if required: raise ValueError("Set ROUND87_SOURCE or pass --source for the designated workbook") return None path = Path(selected).expanduser().resolve(strict=True) if not path.is_file(): raise ValueError("Workbook source must be a file") expected = expectations if expectations is not None else load_expectations() if hashlib.sha256(path.read_bytes()).hexdigest() != expected["sourceSha256"]: raise ValueError("The designated workbook does not match the independently reviewed SHA-256") return path def source_for_test() -> Path: source = resolve_source() if source is None: import pytest pytest.skip("External workbook not configured; set ROUND87_SOURCE (ROUND87_REQUIRED=1 for acceptance)") return source