Files
josh 1121b44857 Organize scripts and add TWS plugins with HTTP timeouts
Vendor pinned T5 and T6 plugin sources under the new plugins layout. Add native HTTP deadlines, status and timing diagnostics, telemetry integration, and build/test tooling.
2026-10-09 11:02:20 -04:00

50 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""Restore the exact upstream dependency revisions for the vendored plugins."""
import argparse
import json
from pathlib import Path
import subprocess
ROOT = Path(__file__).resolve().parents[1]
def git(directory, *args, capture=False):
return subprocess.check_output(["git", "-C", str(directory), *args], text=True).strip() if capture else subprocess.check_call(["git", "-C", str(directory), *args])
def restore(game, check_only):
plugin = ROOT / game / "plugins" / f"tws-{game}-gsc-utils"
lock = json.loads((plugin / "upstream.json").read_text())
for dependency in lock["dependencies"]:
target = plugin / dependency["path"]
if not target.resolve().is_relative_to(plugin.resolve()):
raise RuntimeError(f"Dependency path leaves the plugin: {target}")
if not (target / ".git").exists():
if check_only:
raise RuntimeError(f"Missing dependency: {target}")
if target.exists() and any(target.iterdir()):
raise RuntimeError(f"Refusing to replace nonempty directory: {target}")
target.mkdir(parents=True, exist_ok=True)
git(target, "init", "--quiet")
git(target, "remote", "add", "origin", dependency["url"])
if git(target, "remote", "get-url", "origin", capture=True) != dependency["url"]:
raise RuntimeError(f"Unexpected dependency remote: {target}")
if git(target, "status", "--porcelain", capture=True):
raise RuntimeError(f"Dependency has local changes: {target}")
current = subprocess.run(["git", "-C", str(target), "rev-parse", "--verify", "HEAD"], capture_output=True, text=True)
if current.stdout.strip() != dependency["commit"]:
if check_only:
raise RuntimeError(f"Wrong dependency revision: {target}")
git(target, "fetch", "--depth", "1", "origin", dependency["commit"])
git(target, "checkout", "--quiet", "--detach", dependency["commit"])
print(f"OK {game}/{dependency['path']} {dependency['commit']}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("game", choices=["t5", "t6", "all"])
parser.add_argument("--check", action="store_true", help="Verify existing checkouts without fetching or changing them")
args = parser.parse_args()
for game in ("t5", "t6") if args.game == "all" else (args.game,):
restore(game, args.check)