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 f187bfaf..65cd70bc 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 fdc31778..bd1ab69b 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -164,6 +164,9 @@ class XmlManifest(object):
164 if r.revision is not None: 164 if r.revision is not None:
165 e.setAttribute('revision', r.revision) 165 e.setAttribute('revision', r.revision)
166 166
167 def _ParseGroups(self, groups):
168 return [x for x in re.split(r'[,\s]+', groups) if x]
169
167 def Save(self, fd, peg_rev=False, peg_rev_upstream=True): 170 def Save(self, fd, peg_rev=False, peg_rev_upstream=True):
168 """Write the current manifest out to the given file descriptor. 171 """Write the current manifest out to the given file descriptor.
169 """ 172 """
@@ -171,7 +174,7 @@ class XmlManifest(object):
171 174
172 groups = mp.config.GetString('manifest.groups') 175 groups = mp.config.GetString('manifest.groups')
173 if groups: 176 if groups:
174 groups = [x for x in re.split(r'[,\s]+', groups) if x] 177 groups = self._ParseGroups(groups)
175 178
176 doc = xml.dom.minidom.Document() 179 doc = xml.dom.minidom.Document()
177 root = doc.createElement('manifest') 180 root = doc.createElement('manifest')
@@ -505,6 +508,23 @@ class XmlManifest(object):
505 if node.nodeName == 'project': 508 if node.nodeName == 'project':
506 project = self._ParseProject(node) 509 project = self._ParseProject(node)
507 recursively_add_projects(project) 510 recursively_add_projects(project)
511 if node.nodeName == 'extend-project':
512 name = self._reqatt(node, 'name')
513
514 if name not in self._projects:
515 raise ManifestParseError('extend-project element specifies non-existent '
516 'project: %s' % name)
517
518 path = node.getAttribute('path')
519 groups = node.getAttribute('groups')
520 if groups:
521 groups = self._ParseGroups(groups)
522
523 for p in self._projects[name]:
524 if path and p.relpath != path:
525 continue
526 if groups:
527 p.groups.extend(groups)
508 if node.nodeName == 'repo-hooks': 528 if node.nodeName == 'repo-hooks':
509 # Get the name of the project and the (space-separated) list of enabled. 529 # Get the name of the project and the (space-separated) list of enabled.
510 repo_hooks_project = self._reqatt(node, 'in-project') 530 repo_hooks_project = self._reqatt(node, 'in-project')
@@ -745,7 +765,7 @@ class XmlManifest(object):
745 groups = '' 765 groups = ''
746 if node.hasAttribute('groups'): 766 if node.hasAttribute('groups'):
747 groups = node.getAttribute('groups') 767 groups = node.getAttribute('groups')
748 groups = [x for x in re.split(r'[,\s]+', groups) if x] 768 groups = self._ParseGroups(groups)
749 769
750 if parent is None: 770 if parent is None:
751 relpath, worktree, gitdir, objdir = self.GetProjectPaths(name, path) 771 relpath, worktree, gitdir, objdir = self.GetProjectPaths(name, path)