mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
Strip every `req <NNN>`, `req-<NNN>`, `Requirement <NNN>`, `requirement-<NNN>`, and `docs/requirements/<NNN>-...md` mention from non-Markdown source files. Comments anchored to requirement numbers rot when requirements are renumbered or rewritten and conflate present-state behaviour (which the comment should describe) with the audit trail of how the code got there (which belongs in commit messages, PR descriptions, and the requirement file itself). * Document the rule in `docs/contributing/documentation.md` under "Comments". Code MUST describe the *why* in present-state language; contract enforcement lives in tests, not folklore. * Clean 254 source files across `roles/`, `tests/`, `plugins/`, `cli/`, `scripts/`, `utils/`, `group_vars/`, and the repo-root `eslint.config.js`. Pure comment / docstring / log-message edits; no behavioural change. * Add `tests/lint/repository/test_no_req_references_in_code.py` to enforce the rule going forward across `.js`, `.py`, `.yml`, `.yaml`, `.j2`, and `.sh` files. The legacy `test_no_stale_requirement_refs.py` is exempt as the only file whose purpose is to detect these very tokens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
63 lines
1.9 KiB
Python
63 lines
1.9 KiB
Python
"""Read PORT_BANDS from group_vars/all/08_networks.yml.
|
|
|
|
The canonical bands map lives there as a single key. The CLI helpers
|
|
and the lint test consult this module so the bands stay in one place.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from utils.cache.yaml import load_yaml_any
|
|
|
|
from . import PROJECT_ROOT
|
|
|
|
NETWORKS_FILE = PROJECT_ROOT / "group_vars" / "all" / "08_networks.yml"
|
|
|
|
|
|
class PortBandsError(ValueError):
|
|
"""Raised when the PORT_BANDS map cannot be loaded or used."""
|
|
|
|
|
|
def _load_root() -> dict:
|
|
if not NETWORKS_FILE.is_file():
|
|
raise PortBandsError(f"missing networks file: {NETWORKS_FILE}")
|
|
data = load_yaml_any(str(NETWORKS_FILE), default_if_missing={}) or {}
|
|
if not isinstance(data, dict):
|
|
raise PortBandsError(f"{NETWORKS_FILE} must be a YAML mapping")
|
|
return data
|
|
|
|
|
|
def load_port_bands() -> dict[str, dict[str, dict[str, int]]]:
|
|
"""Return the full ``PORT_BANDS`` map keyed by ``<scope>.<category>``."""
|
|
root = _load_root()
|
|
bands = root.get("PORT_BANDS")
|
|
if not isinstance(bands, dict):
|
|
raise PortBandsError(f"{NETWORKS_FILE} is missing the PORT_BANDS map.")
|
|
return bands
|
|
|
|
|
|
def lookup_band(scope: str, category: str) -> tuple[int, int] | None:
|
|
bands = load_port_bands()
|
|
scope_block = bands.get(scope)
|
|
if not isinstance(scope_block, dict):
|
|
return None
|
|
entry = scope_block.get(category)
|
|
if not isinstance(entry, dict):
|
|
return None
|
|
start = entry.get("start")
|
|
end = entry.get("end")
|
|
if not isinstance(start, int) or not isinstance(end, int):
|
|
return None
|
|
if start > end:
|
|
raise PortBandsError(
|
|
f"PORT_BANDS.{scope}.{category}: start ({start}) > end ({end})"
|
|
)
|
|
return start, end
|
|
|
|
|
|
def available_categories(scope: str) -> list[str]:
|
|
bands = load_port_bands()
|
|
scope_block = bands.get(scope) or {}
|
|
if not isinstance(scope_block, dict):
|
|
return []
|
|
return sorted(scope_block.keys())
|