summaryrefslogtreecommitdiffstats
path: root/lib/python/qmk/json_schema.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python/qmk/json_schema.py')
-rw-r--r--lib/python/qmk/json_schema.py39
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