Files
ComfyUI-OpenClaw/scripts/compatibility_matrix_refresh.py
T

130 lines
3.5 KiB
Python

"""
R90 compatibility matrix refresh workflow.
Implements a repeatable `collect -> diff -> validate -> publish` flow and emits
machine-readable evidence for date-stamped refresh operations.
"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
def _repo_root() -> Path:
return Path(__file__).resolve().parents[1]
def _ensure_repo_on_path() -> None:
root = str(_repo_root())
if root not in sys.path:
sys.path.insert(0, root)
def main() -> int:
_ensure_repo_on_path()
from services.compatibility_matrix_governance import (
normalize_observed_anchors,
run_refresh_workflow,
)
parser = argparse.ArgumentParser(
description=(
"Run compatibility matrix refresh workflow (collect/diff/validate/publish) "
"and emit machine-readable evidence."
)
)
parser.add_argument(
"--matrix-path",
default=str(_repo_root() / "docs" / "release" / "compatibility_matrix.md"),
help="Path to compatibility matrix markdown file",
)
parser.add_argument(
"--anchor-comfyui",
default=None,
help="Observed ComfyUI anchor/version (optional)",
)
parser.add_argument(
"--anchor-frontend",
default=None,
help="Observed ComfyUI frontend anchor/version (optional)",
)
parser.add_argument(
"--anchor-desktop",
default=None,
help="Observed legacy ComfyUI Desktop anchor/version (optional)",
)
parser.add_argument(
"--anchor-comfy-desktop",
default=None,
help="Observed current Comfy-Desktop anchor/version (optional)",
)
parser.add_argument(
"--updated-by",
default="script",
help="Evidence updated_by marker",
)
parser.add_argument(
"--apply",
action="store_true",
help="Apply/publish metadata updates to the matrix file (default: dry-run)",
)
parser.add_argument(
"--strict",
action="store_true",
help="Exit non-zero when validation fails or drift is detected",
)
parser.add_argument(
"--output",
default=None,
help="Optional path to write JSON evidence bundle",
)
parser.add_argument(
"--pretty",
action="store_true",
help="Pretty-print JSON output",
)
args = parser.parse_args()
observed = normalize_observed_anchors(
comfyui=args.anchor_comfyui,
comfyui_frontend=args.anchor_frontend,
desktop=args.anchor_desktop,
comfy_desktop=args.anchor_comfy_desktop,
)
result = run_refresh_workflow(
matrix_path=args.matrix_path,
observed_anchors=observed,
apply=args.apply,
updated_by=args.updated_by,
)
payload = result.to_dict()
if args.output:
Path(args.output).parent.mkdir(parents=True, exist_ok=True)
Path(args.output).write_text(
json.dumps(payload, indent=2 if args.pretty else None, ensure_ascii=False),
encoding="utf-8",
)
if args.pretty:
print(json.dumps(payload, indent=2, ensure_ascii=False))
else:
print(json.dumps(payload, separators=(",", ":"), ensure_ascii=False))
if not args.strict:
return 0
validate_after = payload["stages"]["validate"]["after"]
drift_before = payload["stages"]["diff"]["drift"]
if (not validate_after.get("ok")) or (not drift_before.get("ok")):
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())