summaryrefslogtreecommitdiff
path: root/lib/python/qmk/json_schema.py
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2023-01-01 19:16:38 +0000
committerGitHub <noreply@github.com>2023-01-01 19:16:38 +0000
commit24adecd9227931ebaec16115e05055e0b580d351 (patch)
tree1fad07a60c0751225ea29d16122cf24276371b54 /lib/python/qmk/json_schema.py
parent8c09170fff067fcc10cd05b9c176a561fc9f1334 (diff)
Implement XAP style merge semantics for DD keycodes (#19397)
Diffstat (limited to 'lib/python/qmk/json_schema.py')
-rw-r--r--lib/python/qmk/json_schema.py36
1 files changed, 34 insertions, 2 deletions
diff --git a/lib/python/qmk/json_schema.py b/lib/python/qmk/json_schema.py
index 934e2f841f..c886a0d868 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,34 @@ 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.
+ 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
+ else:
+ target[k] = v
+
+ for d in dicts:
+ for (k, v) in d.items():
+ add_entry(result, k, v)
+
+ return result