diff options
| author | Colin Cross <ccross@android.com> | 2012-04-21 00:33:54 -0700 |
|---|---|---|
| committer | Shawn O. Pearce <sop@google.com> | 2012-05-24 09:32:15 -0700 |
| commit | 23acdd3f1460bc1c040b319940c5e0e8a78f1040 (patch) | |
| tree | 85709c15416db6717cdff2025cc1aacc438c7ce9 /manifest_xml.py | |
| parent | 2644874d9d3e6c16299a01acddf66cd99fd43414 (diff) | |
| download | git-repo-23acdd3f1460bc1c040b319940c5e0e8a78f1040.tar.gz | |
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
Diffstat (limited to 'manifest_xml.py')
| -rw-r--r-- | manifest_xml.py | 74 |
1 files changed, 33 insertions, 41 deletions
diff --git a/manifest_xml.py b/manifest_xml.py index 2927fd1c..daf5740b 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | # See the License for the specific language governing permissions and | 13 | # See the License for the specific language governing permissions and |
| 14 | # limitations under the License. | 14 | # limitations under the License. |
| 15 | 15 | ||
| 16 | import itertools | ||
| 16 | import os | 17 | import os |
| 17 | import re | 18 | import re |
| 18 | import sys | 19 | import sys |
| @@ -281,16 +282,14 @@ class XmlManifest(object): | |||
| 281 | b = b[len(R_HEADS):] | 282 | b = b[len(R_HEADS):] |
| 282 | self.branch = b | 283 | self.branch = b |
| 283 | 284 | ||
| 284 | self._ParseManifest(True) | 285 | nodes = [] |
| 286 | nodes.append(self._ParseManifestXml(self.manifestFile)) | ||
| 285 | 287 | ||
| 286 | local = os.path.join(self.repodir, LOCAL_MANIFEST_NAME) | 288 | local = os.path.join(self.repodir, LOCAL_MANIFEST_NAME) |
| 287 | if os.path.exists(local): | 289 | if os.path.exists(local): |
| 288 | try: | 290 | nodes.append(self._ParseManifestXml(local)) |
| 289 | real = self.manifestFile | 291 | |
| 290 | self.manifestFile = local | 292 | self._ParseManifest(nodes) |
| 291 | self._ParseManifest(False) | ||
| 292 | finally: | ||
| 293 | self.manifestFile = real | ||
| 294 | 293 | ||
| 295 | if self.IsMirror: | 294 | if self.IsMirror: |
| 296 | self._AddMetaProjectMirror(self.repoProject) | 295 | self._AddMetaProjectMirror(self.repoProject) |
| @@ -298,7 +297,7 @@ class XmlManifest(object): | |||
| 298 | 297 | ||
| 299 | self._loaded = True | 298 | self._loaded = True |
| 300 | 299 | ||
| 301 | def _ParseManifestObject(self, path): | 300 | def _ParseManifestXml(self, path): |
| 302 | root = xml.dom.minidom.parse(path) | 301 | root = xml.dom.minidom.parse(path) |
| 303 | if not root or not root.childNodes: | 302 | if not root or not root.childNodes: |
| 304 | raise ManifestParseError("no root node in %s" % (path,)) | 303 | raise ManifestParseError("no root node in %s" % (path,)) |
| @@ -307,21 +306,17 @@ class XmlManifest(object): | |||
| 307 | if config.nodeName != 'manifest': | 306 | if config.nodeName != 'manifest': |
| 308 | raise ManifestParseError("no <manifest> in %s" % (path,)) | 307 | raise ManifestParseError("no <manifest> in %s" % (path,)) |
| 309 | 308 | ||
| 310 | return config | 309 | nodes = [] |
| 311 | |||
| 312 | def _ParseManifest(self, is_root_file): | ||
| 313 | config = self._ParseManifestObject(self.manifestFile) | ||
| 314 | |||
| 315 | for node in config.childNodes: | 310 | for node in config.childNodes: |
| 316 | if node.nodeName == 'include': | 311 | if node.nodeName == 'include': |
| 317 | name = self._reqatt(node, 'name') | 312 | name = self._reqatt(node, 'name') |
| 318 | fp = os.path.join(self.manifestProject.worktree, name) | 313 | fp = os.path.join(os.path.dirname(path), name) |
| 319 | if not os.path.isfile(fp): | 314 | if not os.path.isfile(fp): |
| 320 | raise ManifestParseError, \ | 315 | raise ManifestParseError, \ |
| 321 | "include %s doesn't exist or isn't a file" % \ | 316 | "include %s doesn't exist or isn't a file" % \ |
| 322 | (name,) | 317 | (name,) |
| 323 | try: | 318 | try: |
| 324 | subconfig = self._ParseManifestObject(fp) | 319 | nodes.extend(self._ParseManifestXml(fp)) |
| 325 | # should isolate this to the exact exception, but that's | 320 | # should isolate this to the exact exception, but that's |
| 326 | # tricky. actual parsing implementation may vary. | 321 | # tricky. actual parsing implementation may vary. |
| 327 | except (KeyboardInterrupt, RuntimeError, SystemExit): | 322 | except (KeyboardInterrupt, RuntimeError, SystemExit): |
| @@ -329,27 +324,12 @@ class XmlManifest(object): | |||
| 329 | except Exception, e: | 324 | except Exception, e: |
| 330 | raise ManifestParseError( | 325 | raise ManifestParseError( |
| 331 | "failed parsing included manifest %s: %s", (name, e)) | 326 | "failed parsing included manifest %s: %s", (name, e)) |
| 327 | else: | ||
| 328 | nodes.append(node) | ||
| 329 | return nodes | ||
| 332 | 330 | ||
| 333 | for sub_node in subconfig.childNodes: | 331 | def _ParseManifest(self, node_list): |
| 334 | config.appendChild(sub_node.cloneNode(True)) | 332 | for node in itertools.chain(*node_list): |
| 335 | |||
| 336 | |||
| 337 | for node in config.childNodes: | ||
| 338 | if node.nodeName == 'remove-project': | ||
| 339 | name = self._reqatt(node, 'name') | ||
| 340 | try: | ||
| 341 | del self._projects[name] | ||
| 342 | except KeyError: | ||
| 343 | raise ManifestParseError( | ||
| 344 | 'project %s not found' % | ||
| 345 | (name)) | ||
| 346 | |||
| 347 | # If the manifest removes the hooks project, treat it as if it deleted | ||
| 348 | # the repo-hooks element too. | ||
| 349 | if self._repo_hooks_project and (self._repo_hooks_project.name == name): | ||
| 350 | self._repo_hooks_project = None | ||
| 351 | |||
| 352 | for node in config.childNodes: | ||
| 353 | if node.nodeName == 'remote': | 333 | if node.nodeName == 'remote': |
| 354 | remote = self._ParseRemote(node) | 334 | remote = self._ParseRemote(node) |
| 355 | if self._remotes.get(remote.name): | 335 | if self._remotes.get(remote.name): |
| @@ -358,7 +338,7 @@ class XmlManifest(object): | |||
| 358 | (remote.name, self.manifestFile)) | 338 | (remote.name, self.manifestFile)) |
| 359 | self._remotes[remote.name] = remote | 339 | self._remotes[remote.name] = remote |
| 360 | 340 | ||
| 361 | for node in config.childNodes: | 341 | for node in itertools.chain(*node_list): |
| 362 | if node.nodeName == 'default': | 342 | if node.nodeName == 'default': |
| 363 | if self._default is not None: | 343 | if self._default is not None: |
| 364 | raise ManifestParseError( | 344 | raise ManifestParseError( |
| @@ -368,7 +348,7 @@ class XmlManifest(object): | |||
| 368 | if self._default is None: | 348 | if self._default is None: |
| 369 | self._default = _Default() | 349 | self._default = _Default() |
| 370 | 350 | ||
| 371 | for node in config.childNodes: | 351 | for node in itertools.chain(*node_list): |
| 372 | if node.nodeName == 'notice': | 352 | if node.nodeName == 'notice': |
| 373 | if self._notice is not None: | 353 | if self._notice is not None: |
| 374 | raise ManifestParseError( | 354 | raise ManifestParseError( |
| @@ -376,7 +356,7 @@ class XmlManifest(object): | |||
| 376 | (self.manifestFile)) | 356 | (self.manifestFile)) |
| 377 | self._notice = self._ParseNotice(node) | 357 | self._notice = self._ParseNotice(node) |
| 378 | 358 | ||
| 379 | for node in config.childNodes: | 359 | for node in itertools.chain(*node_list): |
| 380 | if node.nodeName == 'manifest-server': | 360 | if node.nodeName == 'manifest-server': |
| 381 | url = self._reqatt(node, 'url') | 361 | url = self._reqatt(node, 'url') |
| 382 | if self._manifest_server is not None: | 362 | if self._manifest_server is not None: |
| @@ -385,7 +365,7 @@ class XmlManifest(object): | |||
| 385 | (self.manifestFile)) | 365 | (self.manifestFile)) |
| 386 | self._manifest_server = url | 366 | self._manifest_server = url |
| 387 | 367 | ||
| 388 | for node in config.childNodes: | 368 | for node in itertools.chain(*node_list): |
| 389 | if node.nodeName == 'project': | 369 | if node.nodeName == 'project': |
| 390 | project = self._ParseProject(node) | 370 | project = self._ParseProject(node) |
| 391 | if self._projects.get(project.name): | 371 | if self._projects.get(project.name): |
| @@ -393,8 +373,6 @@ class XmlManifest(object): | |||
| 393 | 'duplicate project %s in %s' % | 373 | 'duplicate project %s in %s' % |
| 394 | (project.name, self.manifestFile)) | 374 | (project.name, self.manifestFile)) |
| 395 | self._projects[project.name] = project | 375 | self._projects[project.name] = project |
| 396 | |||
| 397 | for node in config.childNodes: | ||
| 398 | if node.nodeName == 'repo-hooks': | 376 | if node.nodeName == 'repo-hooks': |
| 399 | # Get the name of the project and the (space-separated) list of enabled. | 377 | # Get the name of the project and the (space-separated) list of enabled. |
| 400 | repo_hooks_project = self._reqatt(node, 'in-project') | 378 | repo_hooks_project = self._reqatt(node, 'in-project') |
| @@ -416,6 +394,20 @@ class XmlManifest(object): | |||
| 416 | 394 | ||
| 417 | # Store the enabled hooks in the Project object. | 395 | # Store the enabled hooks in the Project object. |
| 418 | self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks | 396 | self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks |
| 397 | if node.nodeName == 'remove-project': | ||
| 398 | name = self._reqatt(node, 'name') | ||
| 399 | try: | ||
| 400 | del self._projects[name] | ||
| 401 | except KeyError: | ||
| 402 | raise ManifestParseError( | ||
| 403 | 'project %s not found' % | ||
| 404 | (name)) | ||
| 405 | |||
| 406 | # If the manifest removes the hooks project, treat it as if it deleted | ||
| 407 | # the repo-hooks element too. | ||
| 408 | if self._repo_hooks_project and (self._repo_hooks_project.name == name): | ||
| 409 | self._repo_hooks_project = None | ||
| 410 | |||
| 419 | 411 | ||
| 420 | def _AddMetaProjectMirror(self, m): | 412 | def _AddMetaProjectMirror(self, m): |
| 421 | name = None | 413 | name = None |
