refactor(tooling): T-1286 — generate, pr and dev become reach domains
Twelve scripts retired, three domains registered. `reach` now covers nine. generate: `generate-brands` and `generate-corporations` were the second and third copies of the same 24-line build-if-missing-then-exec bash `tooling/atlas` carried, so they collapsed into `core.process.cargo_binary` rather than being ported. `import_economics` shelled out to the first of those, so it now calls that helper — `generated_brands.toml` comes back byte-identical, and the stamp registry swaps the retired wrapper for `core/process.py`. pr: `watchlist-diff` derives its watched set from `generator_sources.py` instead of restating it, so it cannot drift from the stamp check. dev: the environment scripts split decision from performing, per D-263's guarded-exec rule. `godot_plan()` and `worktree_plan()` decide what would happen; `install_godot()`, `install_rust()` and `setup_worktree()` do it. `tooling/test_environment.py` pins the version pin, both override precedences, the already-current skip, the platform refusal and both worktree refusals — none of them performed. `make setup` now installs reach first, since the targets that install rust and godot are reach verbs. Two live bugs found while porting: - The clerk read its decision index from `decisions/README.md`, a path that stopped existing when the DQR tree moved to `governance/`. Every clerk agent has been grepping blind; its prompt pointed at the same dead directory. - The conformance exec-check matched any `x.system()` regardless of receiver, so `platform.system()` read as `os.system()`. Narrowed and re-proved against a real mutant. `process.run` gains `input=`, `timeout=` and a `ProcessTimeout` subclass so a killed run stays distinguishable from a verdict. The pre-push hook no longer merges the clerk's stderr into its stdout — under streaming the last merged line is a JSONL event, which would read as an unrecognised verdict and block. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
"""The `reach dev` environment decisions, exercised without performing them (T-1286).
|
||||
|
||||
`install-godot`, `install-rust` and `worktree-setup` were the three scripts the
|
||||
CLI port stood to gain least from and risked most on. Nothing about them can be
|
||||
checked by running them: a passing test would download a 60 MB archive, mutate
|
||||
`~/bin`, or leave a git worktree behind. So the port split each one into a pure
|
||||
decision (`godot_plan`, `worktree_plan`) and a thin performing half, and this
|
||||
file pins the decisions.
|
||||
|
||||
That split is the whole claim of the port, which is why it gets a test rather
|
||||
than a manual `--plan` run: an installer that cannot be tested has to be
|
||||
trusted instead, and trusting an installer is how a working environment becomes
|
||||
an unreproducible one.
|
||||
|
||||
Run: python3 tooling/test_environment.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
|
||||
from tooling.core.errors import ReachError # noqa: E402
|
||||
from tooling.domains.dev import environment # noqa: E402
|
||||
|
||||
|
||||
def test_plan_names_the_pinned_version(failures: list[str]) -> None:
|
||||
"""The default plan targets DEFAULT_GODOT_VERSION and builds a real URL."""
|
||||
plan = environment.godot_plan()
|
||||
if plan.wanted != environment.DEFAULT_GODOT_VERSION:
|
||||
failures.append(
|
||||
f"godot_plan() wanted {plan.wanted}, expected the pinned "
|
||||
f"{environment.DEFAULT_GODOT_VERSION}"
|
||||
)
|
||||
if plan.wanted not in plan.url or plan.filename not in plan.url:
|
||||
failures.append(f"the URL does not carry version and filename: {plan.url}")
|
||||
if not plan.url.startswith("https://"):
|
||||
failures.append(f"the download URL is not https: {plan.url}")
|
||||
|
||||
|
||||
def test_explicit_version_overrides_the_pin(failures: list[str]) -> None:
|
||||
plan = environment.godot_plan("4.9")
|
||||
if plan.wanted != "4.9" or "4.9-stable" not in plan.url:
|
||||
failures.append(f"an explicit version did not reach the URL: {plan.url}")
|
||||
|
||||
|
||||
def test_env_var_overrides_the_pin(failures: list[str]) -> None:
|
||||
"""GODOT_VERSION is how make setup passes the version through."""
|
||||
before = os.environ.get("GODOT_VERSION")
|
||||
os.environ["GODOT_VERSION"] = "4.7"
|
||||
try:
|
||||
if environment.godot_plan().wanted != "4.7":
|
||||
failures.append("GODOT_VERSION was ignored by godot_plan()")
|
||||
# An explicit argument still wins over the environment.
|
||||
if environment.godot_plan("4.8").wanted != "4.8":
|
||||
failures.append("an explicit version lost to GODOT_VERSION")
|
||||
finally:
|
||||
if before is None:
|
||||
del os.environ["GODOT_VERSION"]
|
||||
else:
|
||||
os.environ["GODOT_VERSION"] = before
|
||||
|
||||
|
||||
def test_already_current_is_decided_not_performed(failures: list[str]) -> None:
|
||||
"""already_current compares installed against wanted — the skip decision."""
|
||||
real = environment.godot_plan()
|
||||
same = type(real)(
|
||||
wanted="4.6", installed="4.6", platform_tag=real.platform_tag,
|
||||
url=real.url, filename=real.filename,
|
||||
)
|
||||
differs = type(real)(
|
||||
wanted="4.6", installed="4.5", platform_tag=real.platform_tag,
|
||||
url=real.url, filename=real.filename,
|
||||
)
|
||||
absent = type(real)(
|
||||
wanted="4.6", installed=None, platform_tag=real.platform_tag,
|
||||
url=real.url, filename=real.filename,
|
||||
)
|
||||
if not same.already_current:
|
||||
failures.append("a matching installed version was not treated as current")
|
||||
if differs.already_current:
|
||||
failures.append("a mismatched version was treated as current — install skipped")
|
||||
if absent.already_current:
|
||||
failures.append("a missing install was treated as current — install skipped")
|
||||
|
||||
|
||||
def test_unsupported_platform_names_a_remedy(failures: list[str]) -> None:
|
||||
"""An unknown platform must fail loudly, not build a URL that 404s."""
|
||||
saved = dict(environment.PLATFORMS)
|
||||
environment.PLATFORMS.clear()
|
||||
try:
|
||||
environment.godot_plan()
|
||||
failures.append("an unsupported platform produced a plan instead of an error")
|
||||
except ReachError as exc:
|
||||
if not exc.fix:
|
||||
failures.append("the unsupported-platform error carries no fix")
|
||||
finally:
|
||||
environment.PLATFORMS.update(saved)
|
||||
|
||||
|
||||
def test_worktree_plan_targets_the_convention(failures: list[str]) -> None:
|
||||
"""D-221: worktrees live at <root>/.worktrees/<branch>."""
|
||||
target = environment.worktree_plan("some-unused-branch-name")
|
||||
expected = environment.config.repo_root() / ".worktrees" / "some-unused-branch-name"
|
||||
if target != expected:
|
||||
failures.append(f"worktree_plan gave {target}, expected {expected}")
|
||||
|
||||
|
||||
def test_worktree_plan_refuses_an_existing_tree(failures: list[str]) -> None:
|
||||
"""Silently reusing a directory is how two branches share one tree."""
|
||||
root = environment.config.repo_root()
|
||||
with tempfile.TemporaryDirectory(dir=root / ".worktrees") as existing:
|
||||
name = Path(existing).name
|
||||
try:
|
||||
environment.worktree_plan(name)
|
||||
failures.append("worktree_plan accepted a branch whose directory exists")
|
||||
except ReachError as exc:
|
||||
if not exc.fix:
|
||||
failures.append("the existing-worktree error carries no fix")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
# .worktrees/ must exist for the collision test to place a directory in it.
|
||||
(environment.config.repo_root() / ".worktrees").mkdir(exist_ok=True)
|
||||
|
||||
failures: list[str] = []
|
||||
test_plan_names_the_pinned_version(failures)
|
||||
test_explicit_version_overrides_the_pin(failures)
|
||||
test_env_var_overrides_the_pin(failures)
|
||||
test_already_current_is_decided_not_performed(failures)
|
||||
test_unsupported_platform_names_a_remedy(failures)
|
||||
test_worktree_plan_targets_the_convention(failures)
|
||||
test_worktree_plan_refuses_an_existing_tree(failures)
|
||||
|
||||
if failures:
|
||||
print("test_environment: FAIL", file=sys.stderr)
|
||||
for failure in failures:
|
||||
print(f" - {failure}", file=sys.stderr)
|
||||
return 1
|
||||
print(
|
||||
"test_environment: OK — version pin, overrides, skip decision, "
|
||||
"platform refusal and worktree placement, none of them performed"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user