aboutsummaryrefslogtreecommitdiff
path: root/utils/seeded-builds
diff options
context:
space:
mode:
authorPaul Sokolovsky <paul.sokolovsky@linaro.org>2012-01-09 19:04:02 +0200
committerPaul Sokolovsky <paul.sokolovsky@linaro.org>2012-01-09 19:04:02 +0200
commit104d2ced202d4f7a8853b39edfb89260d106f7af (patch)
tree22bd0b71f67daa336204f85182a55d4955c3538b /utils/seeded-builds
parentc32ceeff46a0f45b3e6001b45f7d9f1c7e07a34a (diff)
Add utility to merge (as in "set union") several manifests into one.
Diffstat (limited to 'utils/seeded-builds')
-rwxr-xr-xutils/seeded-builds/manifest-union114
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)