From 857d8b315f0bdf61d830b02334158287c813029d Mon Sep 17 00:00:00 2001 From: Lars Bogner Date: Thu, 2 Jul 2026 11:13:35 +0200 Subject: [PATCH] Show VERSIONS.md reason extracts in dwarf status Parses the gen/schema log lines apply_bump() writes to VERSIONS.md and prints a truncated reason under each gen/schemaN row, so `dwarf status` answers "why does this version exist" without opening the changelog. Co-Authored-By: Claude Sonnet 5 --- scripts/bump_dataset_version.py | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/scripts/bump_dataset_version.py b/scripts/bump_dataset_version.py index 5b7afd1..633ce4b 100644 --- a/scripts/bump_dataset_version.py +++ b/scripts/bump_dataset_version.py @@ -26,6 +26,17 @@ from pathlib import Path GEN_RE = re.compile(r"^gen(\d+)$") SCHEMA_RE = re.compile(r"^schema(\d+)$") +# Match the log lines written by apply_bump()/plan_bump_gen()/plan_bump_schema(): +# - `gen2` (kind=steps) — 2026-01-01 — reason text (by) +# - `gen2`/`schema2` (kind=steps) — 2026-01-01 — reason text (by) +VERSIONS_SCHEMA_LINE_RE = re.compile( + r"^- `(?Pgen\d+)`/`(?Pschema\d+)` \(kind=(?P[\w-]+)\)" + r" — \d{4}-\d{2}-\d{2} — (?P.+)$" +) +VERSIONS_GEN_LINE_RE = re.compile( + r"^- `(?Pgen\d+)` \(kind=(?P[\w-]+)\) — \d{4}-\d{2}-\d{2} — (?P.+)$" +) + # One color per tree level in `dwarf status` output, so the eye can jump # straight to e.g. "all the schema rows" or "all the totals". _LEVEL_COLORS = { @@ -34,6 +45,7 @@ _LEVEL_COLORS = { "bucket": "\033[34m", # blue — raw/processed subtotals "schema": "\033[32m", # green — schemaN rows "root": "\033[1;35m", # bold magenta — derived/, pools/, grand total + "reason": "\033[2m", # dim — VERSIONS.md reason extract under gen/schema rows } _RESET = "\033[0m" @@ -232,6 +244,35 @@ def _referenced_parquet_count( return total, referenced +def _parse_versions( + versions_path: Path, +) -> tuple[dict[tuple[str, str], str], dict[tuple[str, str, str], str]]: + """Read VERSIONS.md and return (gen_reasons, schema_reasons) keyed by + (kind, gen_tag) and (kind, gen_tag, schema_tag) respectively. Later entries + for the same key win, since VERSIONS.md is append-only and chronological.""" + gen_reasons: dict[tuple[str, str], str] = {} + schema_reasons: dict[tuple[str, str, str], str] = {} + if not versions_path.is_file(): + return gen_reasons, schema_reasons + for line in versions_path.read_text().splitlines(): + line = line.strip() + m = VERSIONS_SCHEMA_LINE_RE.match(line) + if m: + schema_reasons[(m["kind"], m["gen"], m["schema"])] = m["reason"] + continue + m = VERSIONS_GEN_LINE_RE.match(line) + if m: + gen_reasons[(m["kind"], m["gen"])] = m["reason"] + return gen_reasons, schema_reasons + + +def _truncate(text: str, width: int = 72) -> str: + text = text.strip() + if len(text) <= width: + return text + return text[: width - 1].rstrip() + "…" + + def _human_size(n: int) -> str: size = float(n) for unit in ("B", "KB", "MB", "GB", "TB"): @@ -268,12 +309,17 @@ def _row( return _colorize(row, level) if level else row +def _reason_line(reason: str, indent: int) -> str: + return _colorize(" " * indent + "↳ " + _truncate(reason), "reason") + + def print_status(root: Path) -> None: raw_root = root / "raw" if not raw_root.is_dir(): print(f"no raw/ tree found under {root}") return manifest_referenced = _manifest_referenced_files(root / "pools") + gen_reasons, schema_reasons = _parse_versions(root / "VERSIONS.md") grand_total = 0 grand_files = 0 for kind_dir in sorted(p for p in raw_root.iterdir() if p.is_dir()): @@ -316,6 +362,9 @@ def print_status(root: Path) -> None: kind_files += gen_files print(_row(gen_tag, gen_total, indent=1, level="gen", count=gen_files)) + gen_reason = gen_reasons.get((kind, gen_tag)) + if gen_reason: + print(_reason_line(gen_reason, indent=2)) print( _row( "raw", raw_size, indent=2, level="bucket", @@ -337,6 +386,9 @@ def print_status(root: Path) -> None: count=s_total, referenced=s_referenced, ) ) + schema_reason = schema_reasons.get((kind, gen_tag, f"schema{s}")) + if schema_reason: + print(_reason_line(schema_reason, indent=4)) else: print(_colorize(" (none)", "schema")) print(_row(f"{kind} total", kind_total, indent=1, level="gen", count=kind_files))