blob: 01f5e355233b0e4f36232127dfa30fc0fb118153 [file] [log] [blame]
Xo Wang49abd7e2017-03-17 18:15:10 -07001#!/usr/bin/env python
2"""Loads a "target" YAML file and overwrites its values with values from
3"override" YAML files.
4
5Override files are processed in the order given.
6
7Usage:
8 merge_settings.py <target yaml> [override yamls]
9"""
10import sys
11import yaml
12import copy
13
14def dict_merge(target, source):
15 """Deep merge for dicts.
16
17 Works like dict.update() that recursively updates any dict values present in
18 both parameters.
19
20 Args:
21 target (dict): Values to be overwritten by corresponding values from
22 `source`.
23 source (dict): Overriding values. Not changed by call.
24
25 Returns:
26 `target` with values overwritten from those in `source` at any and all
27 levels of nested dicts.
28 """
29 if not isinstance(source, dict):
30 return source
31 for k, v in source.iteritems():
32 if k in target and isinstance(target[k], dict):
33 dict_merge(target[k], v)
34 else:
35 target[k] = copy.deepcopy(v)
36 return target
37
38if len(sys.argv) < 2:
39 sys.exit('Argument required: target yaml')
40
41if len(sys.argv) == 2:
42 # No overrides to handle
43 sys.exit()
44
45target_filename = sys.argv[1]
46with open(target_filename) as target_file:
47 data = yaml.safe_load(target_file)
48 print('Loaded target YAML file ' + target_filename)
49
50for override_filename in sys.argv[2:]:
51 with open(override_filename) as override_file:
52 override = yaml.safe_load(override_file)
53 dict_merge(data, override)
54 print('Merged override YAML file ' + override_filename)
55
56with open(target_filename, 'w') as target_file:
57 yaml.dump(data, target_file)
58 print('Wrote merged target YAML file ' + target_filename)