Coverage for scripts / live_release_validation / cli_args.py: 100.00%
24 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-09-14 22:07 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-09-14 22:07 +0000
1"""Argument helpers shared by the validation harness CLIs.
3Used by ``scripts.live_release_validation.__main__`` and
4``scripts.example_job_validation.__main__``. Lives outside ``__main__`` so
5the sibling harness never imports another package's entrypoint module.
6"""
8from __future__ import annotations
10import argparse
11import os
12import subprocess
13from pathlib import Path
16def repository_root(value: str | None) -> Path:
17 """Resolve and sanity-check the GCO checkout root."""
18 if value:
19 root = Path(value).expanduser().resolve()
20 else:
21 result = subprocess.run(
22 ["git", "rev-parse", "--show-toplevel"],
23 capture_output=True,
24 text=True,
25 check=False,
26 )
27 if result.returncode != 0:
28 raise ValueError("Run from a Git checkout or pass --repo-root")
29 root = Path(result.stdout.strip()).resolve()
30 if not (root / ".git").exists() or not (root / "cdk.json").is_file():
31 raise ValueError(f"Not a GCO repository root: {root}")
32 return root
35def split_csv_names(value: str) -> tuple[str, ...]:
36 """Parse a comma-separated name list, deduplicated, order-preserving."""
37 names = tuple(dict.fromkeys(item.strip() for item in value.split(",") if item.strip()))
38 if not names:
39 raise argparse.ArgumentTypeError("expected at least one name")
40 return names
43def path_from_root(root: Path, value: str | None, default: Path) -> Path:
44 """Resolve an optional path argument against the repository root."""
45 path = Path(value).expanduser() if value else default
46 candidate = path if path.is_absolute() else root / path
47 return Path(os.path.abspath(os.fspath(candidate)))