Files
computer-playbook/cli/meta/roles/applications/new_in_branch.py
kevinveenbirkenbachandClaude Opus 4.8 0771c55103 refactor(ci): route new-role and failure-report reads through the cached reader
report_failures.decisive_excerpt and new_in_branch._declares_application_id
now read via utils.cache.files.read_text instead of Path.read_text, and the
new_in_branch test constructs its vars path from ROLE_FILE_VARS_MAIN. Clears
the uncached-read and role-file-spot lint gates; behaviour is unchanged
(same UTF-8 decode, same exceptions, same resolved path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:01:32 +02:00

67 lines
1.8 KiB
Python

"""Print application roles new on this branch (absent under roles/ at a ref, default origin/main); empty when the ref is unresolvable."""
from __future__ import annotations
import re
import subprocess
import sys
from pathlib import Path
from utils.cache.files import read_text
from utils.roles.mapping import ROLE_FILE_VARS_MAIN
_APPLICATION_ID_RE = re.compile(r"(?m)^application_id:[ \t]*(?!#)(\S.*)$")
def roles_present_in_ref(roles_dir: Path, ref: str) -> set[str] | None:
try:
out = subprocess.run(
[
"git",
"-C",
str(roles_dir.parent),
"ls-tree",
"-d",
"--name-only",
f"{ref}:roles",
],
capture_output=True,
text=True,
check=True,
)
except (OSError, subprocess.CalledProcessError):
return None
return {line.strip() for line in out.stdout.splitlines() if line.strip()}
def _declares_application_id(role_dir: Path) -> bool:
vars_file = role_dir / ROLE_FILE_VARS_MAIN
try:
return bool(_APPLICATION_ID_RE.search(read_text(str(vars_file))))
except OSError:
return False
def new_application_roles(roles_dir: Path, ref: str = "origin/main") -> list[str]:
present = roles_present_in_ref(roles_dir, ref)
if present is None:
return []
return sorted(
role_dir.name
for role_dir in roles_dir.iterdir()
if role_dir.is_dir()
and role_dir.name not in present
and _declares_application_id(role_dir)
)
def main(argv: list[str] | None = None) -> int:
args = sys.argv[1:] if argv is None else argv
ref = args[0] if args else "origin/main"
print(" ".join(new_application_roles(Path("roles"), ref)))
return 0
if __name__ == "__main__":
raise SystemExit(main())