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 inspect
import sys import sys
from copy import copy from copy import copy
from collections import namedtuple from collections import namedtuple, Mapping
from tools.targets.LPC import patch from tools.targets.LPC import patch
from tools.paths import TOOLS_BOOTLOADERS from tools.paths import TOOLS_BOOTLOADERS
from tools.utils import json_file_to_dict 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 # Current/new location of the 'targets.json' file
__targets_json_location = None __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 @staticmethod
@cached @cached
def get_json_target_data(): 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 # If extra_targets.json exists in working directory load it over the top
extra = os.path.join('.', 'extra_targets.json') extra = os.path.join('.', 'extra_targets.json')
if os.path.exists(extra): if os.path.exists(extra):
targets.update(json_file_to_dict(extra)) Target._merge_dict(targets, json_file_to_dict(extra))
return targets return targets