validate_config_excel_sync.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. """Validate Excel↔JSON byte-equal sync (V2-M1D).
  2. Thin wrapper over build_config_from_excel: regenerate JSON from Excel and assert
  3. byte-equal with the committed runtime JSON. Equivalent to
  4. `build_config_from_excel.py --check`, exposed as a uniform validator for the
  5. config gate.
  6. """
  7. from __future__ import annotations
  8. import json
  9. import sys
  10. from pathlib import Path
  11. ROOT = Path(__file__).resolve().parents[1]
  12. if str(ROOT) not in sys.path:
  13. sys.path.insert(0, str(ROOT))
  14. from scripts.build_config_from_excel import build
  15. from scripts.check_config_json_canonical import canonical_dumps
  16. def main() -> int:
  17. findings = []
  18. for path_str, obj in build().items():
  19. path = Path(path_str)
  20. ok = canonical_dumps(obj) == path.read_text(encoding="utf-8")
  21. finding = {"level": "fail" if not ok else "info", "check_id": "excel_json_sync",
  22. "config_path": str(path.relative_to(ROOT)), "byte_equal": ok}
  23. if not ok:
  24. finding["message"] = "Excel diverges from JSON; run build_config_from_excel.py --sync-excel (JSON wins) or --write (Excel wins)"
  25. findings.append(finding)
  26. status = "fail" if any(f["level"] == "fail" for f in findings) else "pass"
  27. print(json.dumps({"status": status, "findings": findings}, ensure_ascii=False, indent=2))
  28. return 1 if status == "fail" else 0
  29. if __name__ == "__main__":
  30. sys.exit(main())