#!/usr/bin/env python3 """Canonical YAML normalization used by every HA import path. One function, one style, used everywhere data lands in the repo (see services/home-assistant/DESIGN.md, "Canonical format"): block collections, indent width 2, unlimited line width, sorted keys, UTF-8. """ import json import sys import yaml class _CanonicalDumper(yaml.SafeDumper): pass def _represent_none(dumper, _value): return dumper.represent_scalar("tag:yaml.org,2002:null", "") _CanonicalDumper.add_representer(type(None), _represent_none) def dump_canonical_yaml(data): """Render `data` as canonical YAML text.""" return yaml.dump( data, Dumper=_CanonicalDumper, default_flow_style=False, sort_keys=True, allow_unicode=True, width=1 << 31, indent=2, ) def normalize_yaml_text(text): """Parse YAML text then re-dump it through the canonical formatter.""" data = yaml.safe_load(text) return dump_canonical_yaml(data) def normalize_json_text(text): """Parse JSON text (e.g. a `.storage/*` file) and dump as canonical YAML.""" data = json.loads(text) return dump_canonical_yaml(data) def main(argv): if len(argv) != 3 or argv[1] not in ("yaml", "json"): print("usage: normalize.py ", file=sys.stderr) return 2 mode, path = argv[1], argv[2] with open(path, "r", encoding="utf-8") as f: text = f.read() out = normalize_yaml_text(text) if mode == "yaml" else normalize_json_text(text) sys.stdout.write(out) return 0 if __name__ == "__main__": raise SystemExit(main(sys.argv))