From 58c52fa2e7a2e1787f542ecbd570f29844c75f2f Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 4 Apr 2017 11:26:02 +1000 Subject: [PATCH] Recursively merge extra_targets into targets Recursively merge any target configs in extra_targets.json rather than completely replacing keys at the top level --- tools/targets/__init__.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tools/targets/__init__.py b/tools/targets/__init__.py index e133db8986..cdd114aa25 100644 --- a/tools/targets/__init__.py +++ b/tools/targets/__init__.py @@ -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