Files
swarm-house/bin/check_adrs.py
eSlider b4de3ed076
CI & Release / Verify documentation (push) Skipped
CI & Release / Verify simulator (push) Skipped
CI & Release / Trivy scan (push) Skipped
CI & Release / Semantic Release (push) Skipped
CI & Release / Verify documentation (pull_request) Successful in 5s
CI & Release / Verify simulator (pull_request) Failing after 10s
CI & Release / Trivy scan (pull_request) Skipped
CI & Release / Semantic Release (pull_request) Skipped
refactor: move scripts/ to bin/
Relocate check_docs, check_adrs, and docs_rules; update CI, tests, and docs.
2026-07-10 10:59:22 +01:00

76 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Reject modifications to accepted Architecture Decision Records."""
from __future__ import annotations
import argparse
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
ADR_PREFIX = "docs/adr/ADR-"
def _git(*args: str) -> str:
return subprocess.check_output(
["git", *args],
cwd=ROOT,
text=True,
stderr=subprocess.DEVNULL,
).strip()
def _exists_on(base: str, path: str) -> bool:
try:
_git("cat-file", "-e", f"{base}:{path}")
return True
except subprocess.CalledProcessError:
return False
def find_modified_adrs(base: str) -> list[str]:
try:
diff_out = _git("diff", "--name-only", f"{base}...HEAD", "--", "docs/adr/")
except subprocess.CalledProcessError:
return []
modified: list[str] = []
for rel in diff_out.splitlines():
if not rel.startswith(ADR_PREFIX) or not rel.endswith(".md"):
continue
if _exists_on(base, rel):
modified.append(rel)
return sorted(modified)
def run_check(base: str = "origin/main") -> int:
modified = find_modified_adrs(base)
if modified:
print("Immutable ADR violation — accepted records cannot be edited:")
for path in modified:
print(f" error: {path}")
print(
"\nReversal or refinement → new ADR-NNNN file. "
"Never edit an existing ADR-*.md."
)
return 1
print(f"ADR immutability OK (base {base})")
return 0
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--base",
default="origin/main",
help="Git ref to compare against (default: origin/main)",
)
args = parser.parse_args()
sys.exit(run_check(base=args.base))
if __name__ == "__main__":
main()