diff options
| -rw-r--r-- | docs/manifest-format.txt | 13 | ||||
| -rw-r--r-- | manifest_xml.py | 39 |
2 files changed, 44 insertions, 8 deletions
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt index 53789651..9f4585b8 100644 --- a/docs/manifest-format.txt +++ b/docs/manifest-format.txt | |||
| @@ -63,6 +63,9 @@ following DTD: | |||
| 63 | <!ELEMENT repo-hooks (EMPTY)> | 63 | <!ELEMENT repo-hooks (EMPTY)> |
| 64 | <!ATTLIST repo-hooks in-project CDATA #REQUIRED> | 64 | <!ATTLIST repo-hooks in-project CDATA #REQUIRED> |
| 65 | <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED> | 65 | <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED> |
| 66 | |||
| 67 | <!ELEMENT include (EMPTY)> | ||
| 68 | <!ATTLIST include name CDATA #REQUIRED> | ||
| 66 | ]> | 69 | ]> |
| 67 | 70 | ||
| 68 | A description of the elements and their attributes follows. | 71 | A description of the elements and their attributes follows. |
| @@ -192,6 +195,16 @@ This element is mostly useful in the local_manifest.xml, where | |||
| 192 | the user can remove a project, and possibly replace it with their | 195 | the user can remove a project, and possibly replace it with their |
| 193 | own definition. | 196 | own definition. |
| 194 | 197 | ||
| 198 | Element include | ||
| 199 | --------------- | ||
| 200 | |||
| 201 | This element provides the capability of including another manifest | ||
| 202 | file into the originating manifest. Normal rules apply for the | ||
| 203 | target manifest to include- it must be a usable manifest on it's own. | ||
| 204 | |||
| 205 | Attribute `name`; the manifest to include, specified relative to | ||
| 206 | the manifest repositories root. | ||
| 207 | |||
| 195 | 208 | ||
| 196 | Local Manifest | 209 | Local Manifest |
| 197 | ============== | 210 | ============== |
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): | |||
| 298 | 298 | ||
| 299 | self._loaded = True | 299 | self._loaded = True |
| 300 | 300 | ||
| 301 | def _ParseManifest(self, is_root_file): | 301 | def _ParseManifestObject(self, path): |
| 302 | root = xml.dom.minidom.parse(self.manifestFile) | 302 | root = xml.dom.minidom.parse(path) |
| 303 | if not root or not root.childNodes: | 303 | if not root or not root.childNodes: |
| 304 | raise ManifestParseError( | 304 | raise ManifestParseError("no root node in %s" % (path,)) |
| 305 | "no root node in %s" % | ||
| 306 | self.manifestFile) | ||
| 307 | 305 | ||
| 308 | config = root.childNodes[0] | 306 | config = root.childNodes[0] |
| 309 | if config.nodeName != 'manifest': | 307 | if config.nodeName != 'manifest': |
| 310 | raise ManifestParseError( | 308 | raise ManifestParseError("no <manifest> in %s" % (path,)) |
| 311 | "no <manifest> in %s" % | 309 | |
| 312 | self.manifestFile) | 310 | return config |
| 311 | |||
| 312 | def _ParseManifest(self, is_root_file): | ||
| 313 | config = self._ParseManifestObject(self.manifestFile) | ||
| 314 | |||
| 315 | for node in config.childNodes: | ||
| 316 | if node.nodeName == 'include': | ||
| 317 | name = self._reqatt(node, 'name') | ||
| 318 | fp = os.path.join(self.manifestProject.worktree, name) | ||
| 319 | if not os.path.isfile(fp): | ||
| 320 | raise ManifestParseError, \ | ||
| 321 | "include %s doesn't exist or isn't a file" % \ | ||
| 322 | (name,) | ||
| 323 | try: | ||
| 324 | subconfig = self._ParseManifestObject(fp) | ||
| 325 | # should isolate this to the exact exception, but that's | ||
| 326 | # tricky. actual parsing implementation may vary. | ||
| 327 | except (KeyboardInterrupt, RuntimeError, SystemExit): | ||
| 328 | raise | ||
| 329 | except Exception, e: | ||
| 330 | raise ManifestParseError( | ||
| 331 | "failed parsing included manifest %s: %s", (name, e)) | ||
| 332 | |||
| 333 | for sub_node in subconfig.childNodes: | ||
| 334 | config.appendChild(sub_node.cloneNode(True)) | ||
| 335 | |||
| 313 | 336 | ||
| 314 | for node in config.childNodes: | 337 | for node in config.childNodes: |
| 315 | if node.nodeName == 'remove-project': | 338 | if node.nodeName == 'remove-project': |
