Parse manifest and local_manifest together
Combine manifest and local_manifest into a single list of elements
before parsing. This will allow elements in the local_manifest to
affect elements in the main manifest.
Change-Id: I4d34c9260b299a76be2960b07c0c3fe1af35f33c
diff --git a/manifest_xml.py b/manifest_xml.py
index 2927fd1..daf5740 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import itertools
import os
import re
import sys
@@ -281,16 +282,14 @@
b = b[len(R_HEADS):]
self.branch = b
- self._ParseManifest(True)
+ nodes = []
+ nodes.append(self._ParseManifestXml(self.manifestFile))
local = os.path.join(self.repodir, LOCAL_MANIFEST_NAME)
if os.path.exists(local):
- try:
- real = self.manifestFile
- self.manifestFile = local
- self._ParseManifest(False)
- finally:
- self.manifestFile = real
+ nodes.append(self._ParseManifestXml(local))
+
+ self._ParseManifest(nodes)
if self.IsMirror:
self._AddMetaProjectMirror(self.repoProject)
@@ -298,7 +297,7 @@
self._loaded = True
- def _ParseManifestObject(self, path):
+ def _ParseManifestXml(self, path):
root = xml.dom.minidom.parse(path)
if not root or not root.childNodes:
raise ManifestParseError("no root node in %s" % (path,))
@@ -307,21 +306,17 @@
if config.nodeName != 'manifest':
raise ManifestParseError("no <manifest> in %s" % (path,))
- return config
-
- def _ParseManifest(self, is_root_file):
- config = self._ParseManifestObject(self.manifestFile)
-
+ nodes = []
for node in config.childNodes:
if node.nodeName == 'include':
name = self._reqatt(node, 'name')
- fp = os.path.join(self.manifestProject.worktree, name)
+ fp = os.path.join(os.path.dirname(path), 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)
+ nodes.extend(self._ParseManifestXml(fp))
# should isolate this to the exact exception, but that's
# tricky. actual parsing implementation may vary.
except (KeyboardInterrupt, RuntimeError, SystemExit):
@@ -329,27 +324,12 @@
except Exception, e:
raise ManifestParseError(
"failed parsing included manifest %s: %s", (name, e))
+ else:
+ nodes.append(node)
+ return nodes
- for sub_node in subconfig.childNodes:
- config.appendChild(sub_node.cloneNode(True))
-
-
- for node in config.childNodes:
- if node.nodeName == 'remove-project':
- name = self._reqatt(node, 'name')
- try:
- del self._projects[name]
- except KeyError:
- raise ManifestParseError(
- 'project %s not found' %
- (name))
-
- # If the manifest removes the hooks project, treat it as if it deleted
- # the repo-hooks element too.
- if self._repo_hooks_project and (self._repo_hooks_project.name == name):
- self._repo_hooks_project = None
-
- for node in config.childNodes:
+ def _ParseManifest(self, node_list):
+ for node in itertools.chain(*node_list):
if node.nodeName == 'remote':
remote = self._ParseRemote(node)
if self._remotes.get(remote.name):
@@ -358,7 +338,7 @@
(remote.name, self.manifestFile))
self._remotes[remote.name] = remote
- for node in config.childNodes:
+ for node in itertools.chain(*node_list):
if node.nodeName == 'default':
if self._default is not None:
raise ManifestParseError(
@@ -368,7 +348,7 @@
if self._default is None:
self._default = _Default()
- for node in config.childNodes:
+ for node in itertools.chain(*node_list):
if node.nodeName == 'notice':
if self._notice is not None:
raise ManifestParseError(
@@ -376,7 +356,7 @@
(self.manifestFile))
self._notice = self._ParseNotice(node)
- for node in config.childNodes:
+ for node in itertools.chain(*node_list):
if node.nodeName == 'manifest-server':
url = self._reqatt(node, 'url')
if self._manifest_server is not None:
@@ -385,7 +365,7 @@
(self.manifestFile))
self._manifest_server = url
- for node in config.childNodes:
+ for node in itertools.chain(*node_list):
if node.nodeName == 'project':
project = self._ParseProject(node)
if self._projects.get(project.name):
@@ -393,8 +373,6 @@
'duplicate project %s in %s' %
(project.name, self.manifestFile))
self._projects[project.name] = project
-
- for node in config.childNodes:
if node.nodeName == 'repo-hooks':
# Get the name of the project and the (space-separated) list of enabled.
repo_hooks_project = self._reqatt(node, 'in-project')
@@ -416,6 +394,20 @@
# Store the enabled hooks in the Project object.
self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks
+ if node.nodeName == 'remove-project':
+ name = self._reqatt(node, 'name')
+ try:
+ del self._projects[name]
+ except KeyError:
+ raise ManifestParseError(
+ 'project %s not found' %
+ (name))
+
+ # If the manifest removes the hooks project, treat it as if it deleted
+ # the repo-hooks element too.
+ if self._repo_hooks_project and (self._repo_hooks_project.name == name):
+ self._repo_hooks_project = None
+
def _AddMetaProjectMirror(self, m):
name = None