def _do_promote_automatic(cfg_src, cfg_tgt, args): # Promote ALL entries; simply, isn't it... ;-) final_cfg = merge_conf_dicts(cfg_tgt, cfg_src) return ({}, final_cfg)
def run(self, args): if args.explode_default: # Is this the SAME as exploding the defaults AFTER the merge?; # I think NOT. Needs testing cfgs = [explode_default_stanza(conf.data) for conf in args.conf] else: cfgs = [conf.data for conf in args.conf] # Merge all config files: default_cfg = merge_conf_dicts(*cfgs) del cfgs local_cfg = args.target.data orig_cfg = dict(args.target.data) if args.explode_default: # Make a skeleton default dict; at the highest level, that ensure that all default default_stanza = default_cfg.get(GLOBAL_STANZA, default_cfg.get("default")) skeleton_default = dict([(k, {}) for k in args.target.data]) skeleton_default = explode_default_stanza(skeleton_default, default_stanza) default_cfg = merge_conf_dicts(skeleton_default, default_cfg) local_cfg = explode_default_stanza(local_cfg) local_cfg = explode_default_stanza(local_cfg, default_stanza) minz_cfg = dict(local_cfg) # This may be a bit too simplistic. Weird interplay may exit between if [default] stanza # and ocal [Upstream] stanza line up, but [Upstream] in our default file does not. # XXX: Add a unit test! diffs = compare_cfgs(default_cfg, local_cfg, allow_level0=False) for op in diffs: if op.tag == DIFF_OP_DELETE: # This is normal. Don't expect all default content to be mirrored into local continue elif op.tag == DIFF_OP_EQUAL: if isinstance(op.location, DiffStanza): del minz_cfg[op.location.stanza] else: # Todo: Only preserve keys for stanzas where at least 1 key has been modified if match_bwlist(op.location.key, args.preserve_key): ''' self.stderr.write("Skipping key [PRESERVED] [{0}] key={1} value={2!r}\n" "".format(op.location.stanza, op.location.key, op.a)) ''' continue # pragma: no cover (peephole optimization) del minz_cfg[op.location.stanza][op.location.key] # If that was the last remaining key in the stanza, delete the entire stanza if not _drop_stanza_comments(minz_cfg[op.location.stanza]): del minz_cfg[op.location.stanza] elif op.tag == DIFF_OP_INSERT: ''' self.stderr.write("Keeping local change: <{0}> {1!r}\n-{2!r}\n+{3!r}\n\n\n".format( op.tag, op.location, op.b, op.a)) ''' continue elif op.tag == DIFF_OP_REPLACE: ''' self.stderr.write("Keep change: <{0}> {1!r}\n-{2!r}\n+{3!r}\n\n\n".format( op.tag, op.location, op.b, op.a)) ''' continue if args.dry_run: if args.explode_default: rc = show_diff(self.stdout, compare_cfgs(orig_cfg, minz_cfg), headers=(args.target.name, args.target.name + "-new")) else: rc = show_diff(self.stdout, compare_cfgs(local_cfg, default_cfg), headers=(args.target.name, args.target.name + "-new")) return rc if args.output: args.output.dump(minz_cfg) else: args.target.dump(minz_cfg) '''
def merge(*cfg_txts, **parse_args): dicts = [parse_string(txt, **parse_args) for txt in cfg_txts] return merge_conf_dicts(*dicts)