def merge(self, src, dst): if src is None: return dst # merge global environment variables self.merge_env(src, dst) # merge env-specific environment variables self.merge_env(src, dst, self.env) # merge sections for name in list(src.keys()): if name not in dst: if isstr(src[name]): src[name] = PARENT_RE.sub('', src[name]) elif isinstance(src[name], dict): for subname in src[name]: value = src[name][subname] if isstr(value): src[name][subname] = PARENT_RE.sub('', value) dst[name] = src[name] elif isstr(src[name]): if not isstr(dst[name]): raise ConfigError('unable to merge "%s" into "str"' % type(dst[name]).__name__) dst[name] = PARENT_RE.sub(raw(dst[name]), src[name]) elif isinstance(src[name], dict): dst_is_dict = isinstance(dst[name], dict) for subname in src[name]: if isstr(dst[name]): src[name][subname] = PARENT_RE.sub(raw(dst[name]), src[name][subname]) elif dst_is_dict: if subname in dst[name]: src[name][subname] = PARENT_RE.sub( raw(dst[name][subname]), src[name][subname], ) del dst[name][subname] else: src[name][subname] = PARENT_RE.sub( '', src[name][subname], ) if dst_is_dict: src[name].update(dst[name]) dst[name] = src[name] del src[name] dst.update(src)
def evaluate(data): changed = False for _ in range(5): changed = False for n1, v1 in data.items(): if not isstr(v1): continue n = re.escape(n1) r = re.compile(r'\{\{\s*' + n + r'\s*\}\}', re.MULTILINE) for n2, v2 in data.items(): if not isstr(v2): continue data[n2] = r.sub(raw(data[n1]), data[n2]).rstrip('\n') changed |= v2 != data[n2] if not changed: break if changed: raise ConfigError('.rock.yml circular reference')