diff options
Diffstat (limited to 'manifest_xml.py')
| -rw-r--r-- | manifest_xml.py | 94 |
1 files changed, 91 insertions, 3 deletions
diff --git a/manifest_xml.py b/manifest_xml.py index 35318d0a..1d02f9d4 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
| @@ -66,8 +66,8 @@ class XmlManifest(Manifest): | |||
| 66 | 66 | ||
| 67 | self._Unload() | 67 | self._Unload() |
| 68 | 68 | ||
| 69 | def Link(self, name): | 69 | def Override(self, name): |
| 70 | """Update the repo metadata to use a different manifest. | 70 | """Use a different manifest, just for the current instantiation. |
| 71 | """ | 71 | """ |
| 72 | path = os.path.join(self.manifestProject.worktree, name) | 72 | path = os.path.join(self.manifestProject.worktree, name) |
| 73 | if not os.path.isfile(path): | 73 | if not os.path.isfile(path): |
| @@ -81,6 +81,11 @@ class XmlManifest(Manifest): | |||
| 81 | finally: | 81 | finally: |
| 82 | self._manifestFile = old | 82 | self._manifestFile = old |
| 83 | 83 | ||
| 84 | def Link(self, name): | ||
| 85 | """Update the repo metadata to use a different manifest. | ||
| 86 | """ | ||
| 87 | self.Override(name) | ||
| 88 | |||
| 84 | try: | 89 | try: |
| 85 | if os.path.exists(self._manifestFile): | 90 | if os.path.exists(self._manifestFile): |
| 86 | os.remove(self._manifestFile) | 91 | os.remove(self._manifestFile) |
| @@ -103,6 +108,15 @@ class XmlManifest(Manifest): | |||
| 103 | root = doc.createElement('manifest') | 108 | root = doc.createElement('manifest') |
| 104 | doc.appendChild(root) | 109 | doc.appendChild(root) |
| 105 | 110 | ||
| 111 | # Save out the notice. There's a little bit of work here to give it the | ||
| 112 | # right whitespace, which assumes that the notice is automatically indented | ||
| 113 | # by 4 by minidom. | ||
| 114 | if self.notice: | ||
| 115 | notice_element = root.appendChild(doc.createElement('notice')) | ||
| 116 | notice_lines = self.notice.splitlines() | ||
| 117 | indented_notice = ('\n'.join(" "*4 + line for line in notice_lines))[4:] | ||
| 118 | notice_element.appendChild(doc.createTextNode(indented_notice)) | ||
| 119 | |||
| 106 | d = self.default | 120 | d = self.default |
| 107 | sort_remotes = list(self.remotes.keys()) | 121 | sort_remotes = list(self.remotes.keys()) |
| 108 | sort_remotes.sort() | 122 | sort_remotes.sort() |
| @@ -124,6 +138,12 @@ class XmlManifest(Manifest): | |||
| 124 | root.appendChild(e) | 138 | root.appendChild(e) |
| 125 | root.appendChild(doc.createTextNode('')) | 139 | root.appendChild(doc.createTextNode('')) |
| 126 | 140 | ||
| 141 | if self._manifest_server: | ||
| 142 | e = doc.createElement('manifest-server') | ||
| 143 | e.setAttribute('url', self._manifest_server) | ||
| 144 | root.appendChild(e) | ||
| 145 | root.appendChild(doc.createTextNode('')) | ||
| 146 | |||
| 127 | sort_projects = list(self.projects.keys()) | 147 | sort_projects = list(self.projects.keys()) |
| 128 | sort_projects.sort() | 148 | sort_projects.sort() |
| 129 | 149 | ||
| @@ -169,6 +189,16 @@ class XmlManifest(Manifest): | |||
| 169 | self._Load() | 189 | self._Load() |
| 170 | return self._default | 190 | return self._default |
| 171 | 191 | ||
| 192 | @property | ||
| 193 | def notice(self): | ||
| 194 | self._Load() | ||
| 195 | return self._notice | ||
| 196 | |||
| 197 | @property | ||
| 198 | def manifest_server(self): | ||
| 199 | self._Load() | ||
| 200 | return self._manifest_server | ||
| 201 | |||
| 172 | def InitBranch(self): | 202 | def InitBranch(self): |
| 173 | m = self.manifestProject | 203 | m = self.manifestProject |
| 174 | if m.CurrentBranch is None: | 204 | if m.CurrentBranch is None: |
| @@ -184,7 +214,9 @@ class XmlManifest(Manifest): | |||
| 184 | self._projects = {} | 214 | self._projects = {} |
| 185 | self._remotes = {} | 215 | self._remotes = {} |
| 186 | self._default = None | 216 | self._default = None |
| 217 | self._notice = None | ||
| 187 | self.branch = None | 218 | self.branch = None |
| 219 | self._manifest_server = None | ||
| 188 | 220 | ||
| 189 | def _Load(self): | 221 | def _Load(self): |
| 190 | if not self._loaded: | 222 | if not self._loaded: |
| @@ -257,6 +289,23 @@ class XmlManifest(Manifest): | |||
| 257 | self._default = _Default() | 289 | self._default = _Default() |
| 258 | 290 | ||
| 259 | for node in config.childNodes: | 291 | for node in config.childNodes: |
| 292 | if node.nodeName == 'notice': | ||
| 293 | if self._notice is not None: | ||
| 294 | raise ManifestParseError, \ | ||
| 295 | 'duplicate notice in %s' % \ | ||
| 296 | (self.manifestFile) | ||
| 297 | self._notice = self._ParseNotice(node) | ||
| 298 | |||
| 299 | for node in config.childNodes: | ||
| 300 | if node.nodeName == 'manifest-server': | ||
| 301 | url = self._reqatt(node, 'url') | ||
| 302 | if self._manifest_server is not None: | ||
| 303 | raise ManifestParseError, \ | ||
| 304 | 'duplicate manifest-server in %s' % \ | ||
| 305 | (self.manifestFile) | ||
| 306 | self._manifest_server = url | ||
| 307 | |||
| 308 | for node in config.childNodes: | ||
| 260 | if node.nodeName == 'project': | 309 | if node.nodeName == 'project': |
| 261 | project = self._ParseProject(node) | 310 | project = self._ParseProject(node) |
| 262 | if self._projects.get(project.name): | 311 | if self._projects.get(project.name): |
| @@ -322,10 +371,49 @@ class XmlManifest(Manifest): | |||
| 322 | d.revisionExpr = None | 371 | d.revisionExpr = None |
| 323 | return d | 372 | return d |
| 324 | 373 | ||
| 374 | def _ParseNotice(self, node): | ||
| 375 | """ | ||
| 376 | reads a <notice> element from the manifest file | ||
| 377 | |||
| 378 | The <notice> element is distinct from other tags in the XML in that the | ||
| 379 | data is conveyed between the start and end tag (it's not an empty-element | ||
| 380 | tag). | ||
| 381 | |||
| 382 | The white space (carriage returns, indentation) for the notice element is | ||
| 383 | relevant and is parsed in a way that is based on how python docstrings work. | ||
| 384 | In fact, the code is remarkably similar to here: | ||
| 385 | http://www.python.org/dev/peps/pep-0257/ | ||
| 386 | """ | ||
| 387 | # Get the data out of the node... | ||
| 388 | notice = node.childNodes[0].data | ||
| 389 | |||
| 390 | # Figure out minimum indentation, skipping the first line (the same line | ||
| 391 | # as the <notice> tag)... | ||
| 392 | minIndent = sys.maxint | ||
| 393 | lines = notice.splitlines() | ||
| 394 | for line in lines[1:]: | ||
| 395 | lstrippedLine = line.lstrip() | ||
| 396 | if lstrippedLine: | ||
| 397 | indent = len(line) - len(lstrippedLine) | ||
| 398 | minIndent = min(indent, minIndent) | ||
| 399 | |||
| 400 | # Strip leading / trailing blank lines and also indentation. | ||
| 401 | cleanLines = [lines[0].strip()] | ||
| 402 | for line in lines[1:]: | ||
| 403 | cleanLines.append(line[minIndent:].rstrip()) | ||
| 404 | |||
| 405 | # Clear completely blank lines from front and back... | ||
| 406 | while cleanLines and not cleanLines[0]: | ||
| 407 | del cleanLines[0] | ||
| 408 | while cleanLines and not cleanLines[-1]: | ||
| 409 | del cleanLines[-1] | ||
| 410 | |||
| 411 | return '\n'.join(cleanLines) | ||
| 412 | |||
| 325 | def _ParseProject(self, node): | 413 | def _ParseProject(self, node): |
| 326 | """ | 414 | """ |
| 327 | reads a <project> element from the manifest file | 415 | reads a <project> element from the manifest file |
| 328 | """ | 416 | """ |
| 329 | name = self._reqatt(node, 'name') | 417 | name = self._reqatt(node, 'name') |
| 330 | 418 | ||
| 331 | remote = self._get_remote(node) | 419 | remote = self._get_remote(node) |
