diff options
author | Nick Brassel <[email protected]> | 2023-02-28 11:22:29 +1100 |
---|---|---|
committer | Nick Brassel <[email protected]> | 2023-02-28 11:22:29 +1100 |
commit | bacec14073b2e897d5a52caf12de5a6a1f7b4078 (patch) | |
tree | d4e3e57aac1a829a191831efd2e62c8a43217885 /lib/python/qmk/json_schema.py | |
parent | d70e9b8659a7fbbd7069fd542bd07e67e04327a1 (diff) | |
parent | b865b9e1706ad28ae4882bd2e0331e98808295fa (diff) | |
download | qmk_firmware-bacec14073b2e897d5a52caf12de5a6a1f7b4078.tar.gz qmk_firmware-bacec14073b2e897d5a52caf12de5a6a1f7b4078.zip |
Merge remote-tracking branch 'upstream/develop'0.20.0
Diffstat (limited to 'lib/python/qmk/json_schema.py')
-rw-r--r-- | lib/python/qmk/json_schema.py | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/lib/python/qmk/json_schema.py b/lib/python/qmk/json_schema.py index 934e2f841f..b00df749cc 100644 --- a/lib/python/qmk/json_schema.py +++ b/lib/python/qmk/json_schema.py @@ -1,12 +1,13 @@ """Functions that help us generate and use info.json files. """ import json +import hjson +import jsonschema from collections.abc import Mapping from functools import lru_cache +from typing import OrderedDict from pathlib import Path -import hjson -import jsonschema from milc import cli @@ -101,3 +102,37 @@ def deep_update(origdict, newdict): origdict[key] = value return origdict + + +def merge_ordered_dicts(dicts): + """Merges nested OrderedDict objects resulting from reading a hjson file. + Later input dicts overrides earlier dicts for plain values. + If any value is "!delete!", the existing value will be removed from its parent. + Arrays will be appended. If the first entry of an array is "!reset!", the contents of the array will be cleared and replaced with RHS. + Dictionaries will be recursively merged. If any entry is "!reset!", the contents of the dictionary will be cleared and replaced with RHS. + """ + result = OrderedDict() + + def add_entry(target, k, v): + if k in target and isinstance(v, (OrderedDict, dict)): + if "!reset!" in v: + target[k] = v + else: + target[k] = merge_ordered_dicts([target[k], v]) + if "!reset!" in target[k]: + del target[k]["!reset!"] + elif k in target and isinstance(v, list): + if v[0] == '!reset!': + target[k] = v[1:] + else: + target[k] = target[k] + v + elif v == "!delete!" and isinstance(target, (OrderedDict, dict)): + del target[k] + else: + target[k] = v + + for d in dicts: + for (k, v) in d.items(): + add_entry(result, k, v) + + return result |