From 2644874d9d3e6c16299a01acddf66cd99fd43414 Mon Sep 17 00:00:00 2001 From: Brian Harring Date: Thu, 28 Apr 2011 05:04:41 -0700 Subject: ManifestXml: add include support Having the ability to include other manifests is a very practical feature to ease the managment of manifest. It allows to divide a manifest into separate files, and create different environment depending on what we want to release You can have unlimited recursion of include, the manifest configs will simply be concatenated as if it was in a single file. command "repo manifest" will create a single manifest, and not recreate the manifest hierarchy for example: Our developement manifest will look like: Our release manifest will look like: And it is also easy to create and maintain feature branch with a manifest that looks like: Signed-off-by: Brian Harring Signed-off-by: Pierre Tardy Change-Id: I833a30d303039e485888768e6b81561b7665e89d --- manifest_xml.py | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'manifest_xml.py') diff --git a/manifest_xml.py b/manifest_xml.py index ca65e33f..2927fd1c 100644 --- a/manifest_xml.py +++ b/manifest_xml.py @@ -298,18 +298,41 @@ class XmlManifest(object): self._loaded = True - def _ParseManifest(self, is_root_file): - root = xml.dom.minidom.parse(self.manifestFile) + def _ParseManifestObject(self, path): + root = xml.dom.minidom.parse(path) if not root or not root.childNodes: - raise ManifestParseError( - "no root node in %s" % - self.manifestFile) + raise ManifestParseError("no root node in %s" % (path,)) config = root.childNodes[0] if config.nodeName != 'manifest': - raise ManifestParseError( - "no in %s" % - self.manifestFile) + raise ManifestParseError("no in %s" % (path,)) + + return config + + def _ParseManifest(self, is_root_file): + config = self._ParseManifestObject(self.manifestFile) + + for node in config.childNodes: + if node.nodeName == 'include': + name = self._reqatt(node, 'name') + fp = os.path.join(self.manifestProject.worktree, name) + if not os.path.isfile(fp): + raise ManifestParseError, \ + "include %s doesn't exist or isn't a file" % \ + (name,) + try: + subconfig = self._ParseManifestObject(fp) + # should isolate this to the exact exception, but that's + # tricky. actual parsing implementation may vary. + except (KeyboardInterrupt, RuntimeError, SystemExit): + raise + except Exception, e: + raise ManifestParseError( + "failed parsing included manifest %s: %s", (name, e)) + + for sub_node in subconfig.childNodes: + config.appendChild(sub_node.cloneNode(True)) + for node in config.childNodes: if node.nodeName == 'remove-project': -- cgit v1.2.3-54-g00ecf