#!/usr/bin/env python3 """Generate crates/horizon-command/src/vanilla_order.rs: the order of the children of each node of vanilla's command tree where Horizon's tree registers them in a different order. Brigadier keeps children in registration order, and /help (smart usage) lists them that way. python3 tools/test_command_parse_parity.py # exports .local/command-parse-parity/tree.json command_parse_fixture tree rust_tree.json # Horizon's tree in its registration order generate_command_order.py VANILLA_TREE RUST_TREE """ import argparse import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def main(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("vanilla", type=Path) parser.add_argument("rust", type=Path) parser.add_argument("--out", type=Path, default=ROOT / "crates/horizon-command/src/vanilla_order.rs") args = parser.parse_args() vanilla = json.loads(args.vanilla.read_text()) rust = json.loads(args.rust.read_text()) rows = [] def walk(v, r, path): names = list(v.get("children", {})) # GameRuleCommand registers the rules in a Reference2ObjectOpenHashMap's # (identity hash) order, which changes from run to run. if path == ["gamerule"]: return order = r.get("order", []) shared = [n for n in names if n in order] if shared != [n for n in order if n in names]: rows.append((" ".join(path), shared)) for n in names: if n in r.get("children", {}): walk(v["children"][n], r["children"][n], path + [n]) walk(vanilla, rust, []) if not rows or rows[0][0] != "": raise SystemExit("expected the root's order to differ") lines = [ "//! The order of node children in vanilla's command tree, for the nodes", "//! where Horizon's tree registers them differently (path of node names", "//! from the root, children in vanilla's order). Generated by", "//! tools/generate_command_order.py; do not edit by hand.", "", "pub const ORDER: &[(&str, &[&str])] = &[", ] for path, names in rows: joined = ", ".join(f'"{n}"' for n in names) lines.append(f' ("{path}", &[{joined}]),') lines += ["];", ""] args.out.write_text("\n".join(lines)) print(f"wrote {len(rows)} nodes to {args.out}") if __name__ == "__main__": main()