Add extend-project tag to support adding groups to an existing project

Currently, if a local manifest wants to add groups to an existing
project, it must use remove-project and then re-add the project with
the new groups.  This makes the local manifest more fragile, requiring
updates to the local manifest if the original manifest changes.

Add a new extend-project tag, which supports adding groups to an
existing project.

Change-Id: Ib4d1352efd722a65dd263d02644b9ea5ab6ed400
This commit is contained in:
Josh Triplett 2014-06-12 14:57:29 -07:00
parent e9f75b1782
commit 884a387eca
2 changed files with 44 additions and 2 deletions

View File

@ -26,6 +26,7 @@ following DTD:
manifest-server?, manifest-server?,
remove-project*, remove-project*,
project*, project*,
extend-project*,
repo-hooks?)> repo-hooks?)>
<!ELEMENT notice (#PCDATA)> <!ELEMENT notice (#PCDATA)>
@ -67,6 +68,11 @@ following DTD:
<!ATTLIST annotation value CDATA #REQUIRED> <!ATTLIST annotation value CDATA #REQUIRED>
<!ATTLIST annotation keep CDATA "true"> <!ATTLIST annotation keep CDATA "true">
<!ELEMENT extend-project>
<!ATTLIST extend-project name CDATA #REQUIRED>
<!ATTLIST extend-project path CDATA #IMPLIED>
<!ATTLIST extend-project groups CDATA #IMPLIED>
<!ELEMENT remove-project (EMPTY)> <!ELEMENT remove-project (EMPTY)>
<!ATTLIST remove-project name CDATA #REQUIRED> <!ATTLIST remove-project name CDATA #REQUIRED>
@ -252,6 +258,22 @@ rather than the `name` attribute. This attribute only applies to the
local mirrors syncing, it will be ignored when syncing the projects in a local mirrors syncing, it will be ignored when syncing the projects in a
client working directory. client working directory.
Element extend-project
----------------------
Modify the attributes of the named project.
This element is mostly useful in a local manifest file, to modify the
attributes of an existing project without completely replacing the
existing project definition. This makes the local manifest more robust
against changes to the original manifest.
Attribute `path`: If specified, limit the change to projects checked out
at the specified path, rather than all projects with the given name.
Attribute `groups`: List of additional groups to which this project
belongs. Same syntax as the corresponding element of `project`.
Element annotation Element annotation
------------------ ------------------

View File

@ -164,6 +164,9 @@ class XmlManifest(object):
if r.revision is not None: if r.revision is not None:
e.setAttribute('revision', r.revision) e.setAttribute('revision', r.revision)
def _ParseGroups(self, groups):
return [x for x in re.split(r'[,\s]+', groups) if x]
def Save(self, fd, peg_rev=False, peg_rev_upstream=True): def Save(self, fd, peg_rev=False, peg_rev_upstream=True):
"""Write the current manifest out to the given file descriptor. """Write the current manifest out to the given file descriptor.
""" """
@ -171,7 +174,7 @@ class XmlManifest(object):
groups = mp.config.GetString('manifest.groups') groups = mp.config.GetString('manifest.groups')
if groups: if groups:
groups = [x for x in re.split(r'[,\s]+', groups) if x] groups = self._ParseGroups(groups)
doc = xml.dom.minidom.Document() doc = xml.dom.minidom.Document()
root = doc.createElement('manifest') root = doc.createElement('manifest')
@ -505,6 +508,23 @@ class XmlManifest(object):
if node.nodeName == 'project': if node.nodeName == 'project':
project = self._ParseProject(node) project = self._ParseProject(node)
recursively_add_projects(project) recursively_add_projects(project)
if node.nodeName == 'extend-project':
name = self._reqatt(node, 'name')
if name not in self._projects:
raise ManifestParseError('extend-project element specifies non-existent '
'project: %s' % name)
path = node.getAttribute('path')
groups = node.getAttribute('groups')
if groups:
groups = self._ParseGroups(groups)
for p in self._projects[name]:
if path and p.relpath != path:
continue
if groups:
p.groups.extend(groups)
if node.nodeName == 'repo-hooks': if node.nodeName == 'repo-hooks':
# Get the name of the project and the (space-separated) list of enabled. # Get the name of the project and the (space-separated) list of enabled.
repo_hooks_project = self._reqatt(node, 'in-project') repo_hooks_project = self._reqatt(node, 'in-project')
@ -745,7 +765,7 @@ class XmlManifest(object):
groups = '' groups = ''
if node.hasAttribute('groups'): if node.hasAttribute('groups'):
groups = node.getAttribute('groups') groups = node.getAttribute('groups')
groups = [x for x in re.split(r'[,\s]+', groups) if x] groups = self._ParseGroups(groups)
if parent is None: if parent is None:
relpath, worktree, gitdir, objdir = self.GetProjectPaths(name, path) relpath, worktree, gitdir, objdir = self.GetProjectPaths(name, path)