diff options
author | Paul Sokolovsky <paul.sokolovsky@linaro.org> | 2012-01-09 19:04:02 +0200 |
---|---|---|
committer | Paul Sokolovsky <paul.sokolovsky@linaro.org> | 2012-01-09 19:04:02 +0200 |
commit | 104d2ced202d4f7a8853b39edfb89260d106f7af (patch) | |
tree | 22bd0b71f67daa336204f85182a55d4955c3538b /utils/seeded-builds | |
parent | c32ceeff46a0f45b3e6001b45f7d9f1c7e07a34a (diff) |
Add utility to merge (as in "set union") several manifests into one.
Diffstat (limited to 'utils/seeded-builds')
-rwxr-xr-x | utils/seeded-builds/manifest-union | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/utils/seeded-builds/manifest-union b/utils/seeded-builds/manifest-union new file mode 100755 index 0000000..8966212 --- /dev/null +++ b/utils/seeded-builds/manifest-union @@ -0,0 +1,114 @@ +#!/usr/bin/env python +import sys +import optparse +from xml.dom import minidom + + +class Manifest: + + def __init__(self): + self.remote_map = {} + self.project_map = {} + self.default_node = None + + @staticmethod + def compare_attr_wise(node1, node2): + if node1.attributes.length != node2.attributes.length: + return False + for i in xrange(node1.attributes.length): + a1 = node1.attributes.item(i) + if a1.value != node2.attributes[a1.name].value: + return False + return True + + def add_default(self, default_node): + if self.default_node: + if not self.compare_attr_wise(default_node, self.default_node): + raise ValueError("default collision: %s vs %s" % (default_node.toxml(), self.default_node.toxml())) + return + self.default_node = default_node + + def add_remote(self, remote_node): + name = remote_node.getAttribute("name") + if name in self.remote_map: + if not self.compare_attr_wise(remote_node, self.remote_map[name]): + raise ValueError("remote collision: %s vs %s" % (remote_node.toxml(), self.remote_map[name].toxml())) + return False + self.remote_map[name] = remote_node + return True + + def add_project(self, project_node): + remote = project_node.getAttribute("remote") + name = project_node.getAttribute("name") + revision = project_node.getAttribute("revision") + path = project_node.getAttribute("path") + key = (remote, name, revision, path) + if key in self.project_map: + return False + self.project_map[key] = project_node + return True + + def get_default(self): + return self.default_node + + def get_remotes(self): + return self.remote_map.values() + + def get_projects(self): + return self.project_map.values() + + +def union(manifest_files): + manifest = Manifest() + first = True + for f in manifest_files: + print >>sys.stderr, "Processing: %s" % f + dom = minidom.parse(f) + default = dom.getElementsByTagName("default") + assert len(default) == 1 + manifest.add_default(default[0]) + for r in dom.getElementsByTagName("remote"): + manifest.add_remote(r) + for p in dom.getElementsByTagName("project"): + added = manifest.add_project(p) + if not first and added: + print >>sys.stderr, "Added new project: %s" % p.toxml() + + first = False + + return manifest + + +def dump(manifest, out): + out.write("""\ +<?xml version="1.0" encoding="UTF-8"?> +<manifest> + +""") + for r in manifest.get_remotes(): + out.write(r.toxml()) + out.write("\n") + out.write("\n") + + out.write(manifest.get_default().toxml()) + out.write("\n\n") + + for p in manifest.get_projects(): + out.write(p.toxml()) + out.write("\n") + out.write("""\ + +</manifest> +""") + +optparser = optparse.OptionParser(usage="%prog -o <union.xml> <manifest.xml>...") +optparser.add_option("-o", metavar="FILE", help="Output file") +options, args = optparser.parse_args(sys.argv[1:]) +if len(args) < 1: + optparser.error("Wrong number of arguments") + +m = union(args) +out = sys.stdout +if options.o: + out = open(options.o, "w") +dump(m, out) |