Refine groups functionality
Every project is in group "default". "-default" does not remove
it from this project. All group names specified in the manifest
are positive names as opposed to a mix of negative and positive.
Specified groups are resolved in order. If init is supplied with
--groups="group1,-group2", the following describes the project
selection when syncing:
* all projects in "group1" will be added, and
* all projects in "group2" will be removed.
Change-Id: I1df3dcdb64bbd4cd80d675f9b2d3becbf721f661
diff --git a/command.py b/command.py
index 724e4c5..2ee0a43 100644
--- a/command.py
+++ b/command.py
@@ -58,7 +58,7 @@
"""Perform the action, after option parsing is complete.
"""
raise NotImplementedError
-
+
def GetProjects(self, args, missing_ok=False):
"""A list of projects that match the arguments.
"""
@@ -68,8 +68,9 @@
mp = self.manifest.manifestProject
groups = mp.config.GetString('manifest.groups')
- if groups:
- groups = re.split('[,\s]+', groups)
+ if groups is None:
+ groups = 'default'
+ groups = [x for x in re.split('[,\s]+', groups) if x]
if not args:
for project in all.values():
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt
index e5f5ee1..764e41e 100644
--- a/docs/manifest-format.txt
+++ b/docs/manifest-format.txt
@@ -165,8 +165,8 @@
the default element is used.
Attribute `groups`: List of groups to which this project belongs,
-whitespace or comma separated. All projects are part of the group
-"default" unless "-default" is specified in the list of groups.
+whitespace or comma separated. All projects belong to the group
+"default".
Element annotation
------------------
diff --git a/manifest_xml.py b/manifest_xml.py
index 9b804da..5ffc49e 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -122,8 +122,9 @@
mp = self.manifestProject
groups = mp.config.GetString('manifest.groups')
- if groups:
- groups = re.split('[,\s]+', groups)
+ if groups is None:
+ groups = 'default'
+ groups = [x for x in re.split(r'[,\s]+', groups) if x]
doc = xml.dom.minidom.Document()
root = doc.createElement('manifest')
@@ -200,8 +201,9 @@
ce.setAttribute('dest', c.dest)
e.appendChild(ce)
- if p.groups:
- e.setAttribute('groups', ','.join(p.groups))
+ egroups = [g for g in p.groups if g != 'default']
+ if egroups:
+ e.setAttribute('groups', ','.join(egroups))
for a in p.annotations:
if a.keep == "true":
@@ -524,11 +526,12 @@
else:
rebase = rebase.lower() in ("yes", "true", "1")
- groups = node.getAttribute('groups')
- if groups:
- groups = re.split('[,\s]+', groups)
- else:
- groups = None
+ groups = ''
+ if node.hasAttribute('groups'):
+ groups = node.getAttribute('groups')
+ groups = [x for x in re.split('[,\s]+', groups) if x]
+ if 'default' not in groups:
+ groups.append('default')
if self.IsMirror:
relpath = None
diff --git a/project.py b/project.py
index e297926..2b74000 100644
--- a/project.py
+++ b/project.py
@@ -657,41 +657,21 @@
"""Returns true if the manifest groups specified at init should cause
this project to be synced.
Prefixing a manifest group with "-" inverts the meaning of a group.
- All projects are implicitly labelled with "default" unless they are
- explicitly labelled "-default".
- If any non-inverted manifest groups are specified, the default label
- is ignored.
- Specifying only inverted groups implies "default".
+ All projects are implicitly labelled with "default".
+
+ labels are resolved in order. In the example case of
+ project_groups: "default,group1,group2"
+ manifest_groups: "-group1,group2"
+ the project will be matched.
"""
- project_groups = self.groups
- if not manifest_groups:
- return not project_groups or not "-default" in project_groups
+ matched = False
+ for group in manifest_groups:
+ if group.startswith('-') and group[1:] in self.groups:
+ matched = False
+ elif group in self.groups:
+ matched = True
- if not project_groups:
- project_groups = ["default"]
- elif not ("default" in project_groups or "-default" in project_groups):
- project_groups.append("default")
-
- plus_groups = [x for x in manifest_groups if not x.startswith("-")]
- minus_groups = [x[1:] for x in manifest_groups if x.startswith("-")]
-
- if not plus_groups:
- plus_groups.append("default")
-
- for group in minus_groups:
- if group in project_groups:
- # project was excluded by -group
- return False
-
- for group in plus_groups:
- if group in project_groups:
- # project was included by group
- return True
-
- # groups were specified that did not include this project
- if plus_groups:
- return False
- return True
+ return matched
## Status Display ##
diff --git a/repo b/repo
index 75fe9ec..0aabc0d 100755
--- a/repo
+++ b/repo
@@ -28,7 +28,7 @@
del magic
# increment this whenever we make important changes to this script
-VERSION = (1, 15)
+VERSION = (1, 16)
# increment this if the MAINTAINER_KEYS block is modified
KEYRING_VERSION = (1,0)
@@ -126,7 +126,7 @@
dest='depth',
help='create a shallow clone with given depth; see git clone')
group.add_option('-g', '--groups',
- dest='groups', default="",
+ dest='groups', default='default',
help='restrict manifest projects to ones with a specified group',
metavar='GROUP')
diff --git a/subcmds/init.py b/subcmds/init.py
index 6cf39d1..d1c497c 100644
--- a/subcmds/init.py
+++ b/subcmds/init.py
@@ -14,6 +14,7 @@
# limitations under the License.
import os
+import re
import shutil
import sys
@@ -87,7 +88,7 @@
dest='depth',
help='create a shallow clone with given depth; see git clone')
g.add_option('-g', '--groups',
- dest='groups', default="",
+ dest='groups', default='default',
help='restrict manifest projects to ones with a specified group',
metavar='GROUP')
@@ -139,7 +140,12 @@
r.ResetFetch()
r.Save()
- m.config.SetString('manifest.groups', opt.groups)
+ groups = re.split('[,\s]+', opt.groups)
+ groups = [x for x in groups if x]
+ groupstr = ','.join(groups)
+ if groupstr == 'default':
+ groupstr = None
+ m.config.SetString('manifest.groups', groupstr)
if opt.reference:
m.config.SetString('repo.reference', opt.reference)