108 lines
3.2 KiB
Python
108 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Repair installed TransformerLab plugin manifests from the pinned source manifest."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def load_json(path: Path) -> dict:
|
|
with path.open("r", encoding="utf-8") as handle:
|
|
return json.load(handle)
|
|
|
|
|
|
def write_json(path: Path, payload: dict) -> None:
|
|
with path.open("w", encoding="utf-8") as handle:
|
|
json.dump(payload, handle, indent=2, sort_keys=False)
|
|
handle.write("\n")
|
|
|
|
|
|
def candidate_manifest_paths(root: Path, plugin: str) -> list[Path]:
|
|
candidates = []
|
|
patterns = [
|
|
f"workspace/plugins/{plugin}/index.json",
|
|
f"orgs/*/workspace/plugins/{plugin}/index.json",
|
|
f"orgs/*/plugins/{plugin}/index.json",
|
|
]
|
|
for pattern in patterns:
|
|
candidates.extend(root.glob(pattern))
|
|
unique = []
|
|
seen = set()
|
|
for path in candidates:
|
|
resolved = path.resolve()
|
|
if resolved in seen:
|
|
continue
|
|
seen.add(resolved)
|
|
unique.append(path)
|
|
return unique
|
|
|
|
|
|
def repair_manifest(path: Path, required_supports: list[str], source_supports: list[str]) -> bool:
|
|
payload = load_json(path)
|
|
existing = payload.get("supports", [])
|
|
if not isinstance(existing, list):
|
|
existing = []
|
|
|
|
desired = []
|
|
seen = set()
|
|
for item in source_supports:
|
|
if isinstance(item, str) and item not in seen:
|
|
desired.append(item)
|
|
seen.add(item)
|
|
for item in required_supports:
|
|
if item not in seen:
|
|
desired.append(item)
|
|
seen.add(item)
|
|
|
|
if existing == desired:
|
|
return False
|
|
|
|
payload["supports"] = desired
|
|
write_json(path, payload)
|
|
return True
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--transformerlab-dir", required=True)
|
|
parser.add_argument("--plugin", required=True)
|
|
parser.add_argument("--required-support", action="append", default=[])
|
|
args = parser.parse_args()
|
|
|
|
root = Path(args.transformerlab_dir).expanduser().resolve()
|
|
source_manifest = root / "src" / "transformerlab" / "plugins" / args.plugin / "index.json"
|
|
if not source_manifest.exists():
|
|
print(f"missing source plugin manifest: {source_manifest}", file=sys.stderr)
|
|
return 1
|
|
|
|
source_payload = load_json(source_manifest)
|
|
source_supports = source_payload.get("supports", [])
|
|
if not isinstance(source_supports, list):
|
|
print(f"invalid supports array in {source_manifest}", file=sys.stderr)
|
|
return 1
|
|
|
|
missing_required = [item for item in args.required_support if item not in source_supports]
|
|
if missing_required:
|
|
print(
|
|
f"source plugin manifest {source_manifest} is missing required supports: {', '.join(missing_required)}",
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
|
|
updated = 0
|
|
for manifest in candidate_manifest_paths(root, args.plugin):
|
|
if repair_manifest(manifest, args.required_support, source_supports):
|
|
updated += 1
|
|
print(f"repaired {manifest}")
|
|
|
|
if updated == 0:
|
|
print(f"no installed {args.plugin} manifests needed repair")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|