Recursively merge extra_targets into targets

Recursively merge any target configs in extra_targets.json rather than completely replacing keys at the top level
pull/4103/head
Andrew Leech 2017-04-04 11:26:02 +10:00
parent e6e3d08ea6
commit 58c52fa2e7
1 changed files with 19 additions and 2 deletions

View File

@ -22,7 +22,7 @@ import shutil
import inspect
import sys
from copy import copy
from collections import namedtuple
from collections import namedtuple, Mapping
from tools.targets.LPC import patch
from tools.paths import TOOLS_BOOTLOADERS
from tools.utils import json_file_to_dict
@ -125,6 +125,23 @@ class Target(namedtuple("Target", "name json_data resolution_order resolution_or
# Current/new location of the 'targets.json' file
__targets_json_location = None
@staticmethod
def _merge_dict(dct, merge_dct):
""" Recursive dict merge. Inspired by `dict.update()` however instead of
updating only top-level keys, dict_merge recurses down into dicts nested
to an arbitrary depth, updating keys.
The provided ``merge_dct`` is merged into ``dct`` in place.
:param dct: dict onto which the merge is executed
:param merge_dct: dct merged into dct
:return: None
"""
for k, v in merge_dct.iteritems():
if (k in dct and isinstance(dct[k], dict)
and isinstance(merge_dct[k], Mapping)):
Target._merge_dict(dct[k], merge_dct[k])
else:
dct[k] = merge_dct[k]
@staticmethod
@cached
def get_json_target_data():
@ -135,7 +152,7 @@ class Target(namedtuple("Target", "name json_data resolution_order resolution_or
# If extra_targets.json exists in working directory load it over the top
extra = os.path.join('.', 'extra_targets.json')
if os.path.exists(extra):
targets.update(json_file_to_dict(extra))
Target._merge_dict(targets, json_file_to_dict(extra))
return targets