summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/manifest-format.txt22
-rw-r--r--manifest_xml.py24
2 files changed, 44 insertions, 2 deletions
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt
index 28a21bb7..d5c6a024 100644
--- a/docs/manifest-format.txt
+++ b/docs/manifest-format.txt
@@ -26,6 +26,7 @@ following DTD:
26 manifest-server?, 26 manifest-server?,
27 remove-project*, 27 remove-project*,
28 project*, 28 project*,
29 extend-project*,
29 repo-hooks?)> 30 repo-hooks?)>
30 31
31 <!ELEMENT notice (#PCDATA)> 32 <!ELEMENT notice (#PCDATA)>
@@ -67,6 +68,11 @@ following DTD:
67 <!ATTLIST annotation value CDATA #REQUIRED> 68 <!ATTLIST annotation value CDATA #REQUIRED>
68 <!ATTLIST annotation keep CDATA "true"> 69 <!ATTLIST annotation keep CDATA "true">
69 70
71 <!ELEMENT extend-project>
72 <!ATTLIST extend-project name CDATA #REQUIRED>
73 <!ATTLIST extend-project path CDATA #IMPLIED>
74 <!ATTLIST extend-project groups CDATA #IMPLIED>
75
70 <!ELEMENT remove-project (EMPTY)> 76 <!ELEMENT remove-project (EMPTY)>
71 <!ATTLIST remove-project name CDATA #REQUIRED> 77 <!ATTLIST remove-project name CDATA #REQUIRED>
72 78
@@ -252,6 +258,22 @@ rather than the `name` attribute. This attribute only applies to the
252local mirrors syncing, it will be ignored when syncing the projects in a 258local mirrors syncing, it will be ignored when syncing the projects in a
253client working directory. 259client working directory.
254 260
261Element extend-project
262----------------------
263
264Modify the attributes of the named project.
265
266This element is mostly useful in a local manifest file, to modify the
267attributes of an existing project without completely replacing the
268existing project definition. This makes the local manifest more robust
269against changes to the original manifest.
270
271Attribute `path`: If specified, limit the change to projects checked out
272at the specified path, rather than all projects with the given name.
273
274Attribute `groups`: List of additional groups to which this project
275belongs. Same syntax as the corresponding element of `project`.
276
255Element annotation 277Element annotation
256------------------ 278------------------
257 279
diff --git a/manifest_xml.py b/manifest_xml.py
index 6d70c86b..890c954d 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -168,6 +168,9 @@ class XmlManifest(object):
168 if r.revision is not None: 168 if r.revision is not None:
169 e.setAttribute('revision', r.revision) 169 e.setAttribute('revision', r.revision)
170 170
171 def _ParseGroups(self, groups):
172 return [x for x in re.split(r'[,\s]+', groups) if x]
173
171 def Save(self, fd, peg_rev=False, peg_rev_upstream=True): 174 def Save(self, fd, peg_rev=False, peg_rev_upstream=True):
172 """Write the current manifest out to the given file descriptor. 175 """Write the current manifest out to the given file descriptor.
173 """ 176 """
@@ -175,7 +178,7 @@ class XmlManifest(object):
175 178
176 groups = mp.config.GetString('manifest.groups') 179 groups = mp.config.GetString('manifest.groups')
177 if groups: 180 if groups:
178 groups = [x for x in re.split(r'[,\s]+', groups) if x] 181 groups = self._ParseGroups(groups)
179 182
180 doc = xml.dom.minidom.Document() 183 doc = xml.dom.minidom.Document()
181 root = doc.createElement('manifest') 184 root = doc.createElement('manifest')
@@ -511,6 +514,23 @@ class XmlManifest(object):
511 if node.nodeName == 'project': 514 if node.nodeName == 'project':
512 project = self._ParseProject(node) 515 project = self._ParseProject(node)
513 recursively_add_projects(project) 516 recursively_add_projects(project)
517 if node.nodeName == 'extend-project':
518 name = self._reqatt(node, 'name')
519
520 if name not in self._projects:
521 raise ManifestParseError('extend-project element specifies non-existent '
522 'project: %s' % name)
523
524 path = node.getAttribute('path')
525 groups = node.getAttribute('groups')
526 if groups:
527 groups = self._ParseGroups(groups)
528
529 for p in self._projects[name]:
530 if path and p.relpath != path:
531 continue
532 if groups:
533 p.groups.extend(groups)
514 if node.nodeName == 'repo-hooks': 534 if node.nodeName == 'repo-hooks':
515 # Get the name of the project and the (space-separated) list of enabled. 535 # Get the name of the project and the (space-separated) list of enabled.
516 repo_hooks_project = self._reqatt(node, 'in-project') 536 repo_hooks_project = self._reqatt(node, 'in-project')
@@ -751,7 +771,7 @@ class XmlManifest(object):
751 groups = '' 771 groups = ''
752 if node.hasAttribute('groups'): 772 if node.hasAttribute('groups'):
753 groups = node.getAttribute('groups') 773 groups = node.getAttribute('groups')
754 groups = [x for x in re.split(r'[,\s]+', groups) if x] 774 groups = self._ParseGroups(groups)
755 775
756 if parent is None: 776 if parent is None:
757 relpath, worktree, gitdir, objdir = self.GetProjectPaths(name, path) 777 relpath, worktree, gitdir, objdir = self.GetProjectPaths(name, path)