"""Generate current command names from a local PearlSR checkout; no network I/O.""" import argparse import pathlib import re import subprocess parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("upstream", type=pathlib.Path) args = parser.parse_args() checkout = args.upstream.resolve() revision = subprocess.check_output( ["git", "-C", str(checkout), "rev-parse", "HEAD"], text=True ).strip() source = (checkout / "protocol/src/root.zig").read_text(encoding="utf-8") enum = source.split("pub const CmdID = enum(u16) {", 1)[1].split("};", 1)[0] commands = re.findall(r"\bCmd(\w+)\s*=\s*(\d+)\s*,", enum) if not commands or len({name for name, _ in commands}) != len(commands): raise SystemExit("Missing or duplicate upstream command names") if len({int(value) for _, value in commands}) != len(commands): raise SystemExit("Duplicate upstream command IDs") lines = [ "// Code generated by tools/sync_protocol_commands.py. DO NOT EDIT.", "// Source: https://git.xeondev.com/HonkaiSlopRail/pearl-sr protocol/src/root.zig", "// Revision: " + revision, "package proto", "", 'const CommandSourceRevision = "' + revision + '"', "", "var upstreamCmdIDByName = map[string]uint16{", ] lines += [f'\t"{name}": {value},' for name, value in commands] lines += ["}", "", "func init() {", "\tfor name, id := range upstreamCmdIDByName {", "\t\tif previous, ok := CmdIDByName[name]; ok && previous != id {", '\t\t\tpanic("command ID conflict between schema and upstream: " + name)', "\t\t}", "\t\tCmdIDByName[name] = id", "\t\tNameByCmdID[id] = name", "\t}", "}", ""] root = pathlib.Path(__file__).resolve().parents[1] base_source = (root / "protocol/proto/cmdid.go").read_text(encoding="utf-8") base_commands = {n: int(v) for n, v in re.findall(r'^\s*"(\w+)":\s*(\d+),', base_source, re.M)} conflicts = [n for n, v in commands if n in base_commands and base_commands[n] != int(v)] if conflicts: raise SystemExit("Update the base schema command IDs first: " + ", ".join(conflicts)) target = root / "protocol/proto/upstream_cmdids.go" target.write_text("\n".join(lines), encoding="utf-8") subprocess.run(["gofmt", "-w", str(target)], check=True) print(f"Generated {len(commands)} commands from {revision}")