Files
proxmox/scripts/verify/build-unified-extended-from-csv.py

83 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""
Write reports/inventory/DEPLOYED_CONTRACTS_UNIFIED_EXTENDED.md from
reports/inventory/deployed-contracts-by-network.csv.
The Markdown rows match the pipe format parsed by inventory_onchain.parse_table().
Re-run this if the CSV (repo evidence inventory) changes.
"""
from __future__ import annotations
import csv
import re
import sys
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
CSV_IN = ROOT / "reports/inventory/deployed-contracts-by-network.csv"
OUT = ROOT / "reports/inventory/DEPLOYED_CONTRACTS_UNIFIED_EXTENDED.md"
SUMMARY_LINE_PREFIX = "- Current deduped closure state:"
PIPE = re.compile(r"\|")
def esc(s: str) -> str:
s = s.replace(" | ", "").strip()
s = PIPE.sub("/", s)
return s or ""
def main() -> int:
if not CSV_IN.is_file():
print("Missing", CSV_IN, file=sys.stderr)
return 1
with CSV_IN.open(newline="", encoding="utf-8") as f:
r = csv.DictReader(f)
if not r.fieldnames:
print("Empty CSV", file=sys.stderr)
return 1
rows = list(r)
if not rows:
print("No data rows in", CSV_IN, file=sys.stderr)
return 1
now = datetime.now(timezone.utc).replace(microsecond=0)
out_lines: list[str] = [
"# DEPLOYED_CONTRACTS_UNIFIED (extended, repo evidence)",
"",
f"**Generated (UTC):** {now.isoformat().replace('+00:00', 'Z')}",
f"**Source table:** [`deployed-contracts-by-network.csv`]({CSV_IN.name}) (same contract set as the network report).",
"",
f"{SUMMARY_LINE_PREFIX} **pending** — run `build-inventory-completion-matrix.py` after the on-chain snapshot exists.",
"",
"Pipe rows below are the canonical set consumed by `inventory_onchain.parse_table()`.",
"",
"| # | Network | Ch | Name | Address | Status / provenance |",
"|--:|---|---:|---|---|",
]
for i, row in enumerate(rows, start=1):
network = esc(row.get("network", ""))
chain = esc(str(row.get("chain_id", "")).strip())
name = esc(row.get("contract_name", ""))
raw_addr = (row.get("address") or "").strip()
if not re.match(r"^0x[a-fA-F0-9]{40}$", raw_addr):
print("Bad address on CSV row", i, raw_addr, file=sys.stderr)
return 1
addr = "`" + "0x" + raw_addr[2:].lower() + "`"
cat = esc(row.get("category", ""))
stat = esc(row.get("status", ""))
notes = esc(row.get("notes", ""))
source = esc(row.get("source", ""))
tail = f"repo | {source}{cat}, {stat}; {notes}" if notes else f"repo | {source}{cat}, {stat}"
out_lines.append(f"| {i} | {network} | {chain} | {name} | {addr} | {tail} |")
OUT.parent.mkdir(parents=True, exist_ok=True)
OUT.write_text("\n".join(out_lines) + "\n", encoding="utf-8")
print(OUT, len(rows), "data rows", len(OUT.read_text(encoding="utf-8")), "bytes")
return 0
if __name__ == "__main__":
raise SystemExit(main())