Initial commit
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Loads a "target" YAML file and overwrites its values with values from
|
||||
"override" YAML files.
|
||||
|
||||
Override files are processed in the order given.
|
||||
|
||||
Usage:
|
||||
merge_settings.py <target yaml> [override/remove yamls]
|
||||
"""
|
||||
import sys
|
||||
import yaml
|
||||
import copy
|
||||
|
||||
def dict_merge(target, source, remove):
|
||||
"""Deep merge for dicts.
|
||||
|
||||
Works like dict.update() that recursively updates/removes any dict values
|
||||
present in both parameters.
|
||||
|
||||
Args:
|
||||
target (dict): Values to be overwritten by corresponding values from
|
||||
`source`.
|
||||
source (dict): Overriding values. Not changed by call.
|
||||
remove (bool): If this is true then it removes the entry provided in
|
||||
'source' along with all entries under it from 'target'. Otherwise
|
||||
it overrides the values from 'source'
|
||||
|
||||
Returns:
|
||||
`target` with values overwritten/removed from those in `source` at any
|
||||
and all levels of nested dicts.
|
||||
"""
|
||||
if not isinstance(source, dict):
|
||||
return source
|
||||
for k, v in source.items():
|
||||
if k in target and isinstance(target[k], dict):
|
||||
dict_merge(target[k], v, remove)
|
||||
else:
|
||||
if remove is True and k in target:
|
||||
target.pop(k)
|
||||
else:
|
||||
target[k] = copy.deepcopy(v)
|
||||
return target
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
sys.exit('Argument required: target yaml')
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
# No overrides to handle
|
||||
sys.exit()
|
||||
|
||||
target_filename = sys.argv[1]
|
||||
with open(target_filename) as target_file:
|
||||
data = yaml.safe_load(target_file)
|
||||
print('Loaded target YAML file ' + target_filename)
|
||||
|
||||
for override_filename in sys.argv[2:]:
|
||||
if override_filename.endswith('.override.yml'):
|
||||
with open(override_filename) as override_file:
|
||||
override = yaml.safe_load(override_file)
|
||||
dict_merge(data, override, False)
|
||||
print('Merged override YAML file ' + override_filename)
|
||||
elif override_filename.endswith('.remove.yml'):
|
||||
with open(override_filename) as override_file:
|
||||
override = yaml.safe_load(override_file)
|
||||
dict_merge(data, override, True)
|
||||
print('Removed data from source YAML file' + override_filename)
|
||||
|
||||
with open(target_filename, 'w') as target_file:
|
||||
yaml.dump(data, target_file)
|
||||
print('Wrote merged target YAML file ' + target_filename)
|
||||
Reference in New Issue
Block a user