Files
computer-playbook/utils/meta/port_bands.py
kevinveenbirkenbachandClaude Opus 4.7 c55ad69c41 refactor: drop requirement-file references from code, add doc rule + lint
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>
2026-05-10 16:25:22 +02:00

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())