Merge dictionaries when extending CI builds

When one CI build YAML spec extended another, the `reproduce_ci_env.py`
script was overwritting local configuration with the configuration being
extended. This change merges all configuration together (which appears
to be how the GitLab CI works).
This commit is contained in:
Kenneth Moreland 2021-10-05 13:11:44 -06:00
parent ae3c7c096b
commit 28b800d21d

@ -57,6 +57,21 @@ def load_ci_file(ci_file_path):
ci_state.update(yaml.safe_load(open(include_path)))
return ci_state
# Recursively updates the target dictionary with the source dictionary.
# By recursive, I mean that if source contains a sub-dictionary that
# target also contains, the target sub-dictionary is updated rather than
# replaced. Likewise for sub-sub-dictionaries and so on. This code is
# taken from StackOverflow:
# https://stackoverflow.com/questions/3232943/update-value-of-a-nested-dictionary-of-varying-depth
def recursive_dictionary_update(target, source):
import collections.abc
for key, value in source.items():
if isinstance(value, collections.abc.Mapping):
target[key] = recursive_dictionary_update(target.get(key, {}), value)
else:
target[key] = value
return target
def flattened_entry_copy(ci_state, name):
import copy
entry = copy.deepcopy(ci_state[name])
@ -64,13 +79,11 @@ def flattened_entry_copy(ci_state, name):
#Flatten 'extends' entries, only presume the first level of inheritance is
#important
if 'extends' in entry:
to_merge = []
if not isinstance(entry['extends'], list):
entry['extends'] = [ entry['extends'] ]
for e in entry['extends']:
entry.update(ci_state[e])
recursive_dictionary_update(entry, ci_state[e])
del entry['extends']
return entry