summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/manifest-format.txt18
-rw-r--r--manifest_xml.py20
-rw-r--r--project.py9
-rw-r--r--subcmds/forall.py7
4 files changed, 53 insertions, 1 deletions
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt
index a7bb1561..e5f5ee18 100644
--- a/docs/manifest-format.txt
+++ b/docs/manifest-format.txt
@@ -43,12 +43,17 @@ following DTD:
43 <!ELEMENT manifest-server (EMPTY)> 43 <!ELEMENT manifest-server (EMPTY)>
44 <!ATTLIST url CDATA #REQUIRED> 44 <!ATTLIST url CDATA #REQUIRED>
45 45
46 <!ELEMENT project (EMPTY)> 46 <!ELEMENT project (annotation?)>
47 <!ATTLIST project name CDATA #REQUIRED> 47 <!ATTLIST project name CDATA #REQUIRED>
48 <!ATTLIST project path CDATA #IMPLIED> 48 <!ATTLIST project path CDATA #IMPLIED>
49 <!ATTLIST project remote IDREF #IMPLIED> 49 <!ATTLIST project remote IDREF #IMPLIED>
50 <!ATTLIST project revision CDATA #IMPLIED> 50 <!ATTLIST project revision CDATA #IMPLIED>
51 <!ATTLIST project groups CDATA #IMPLIED> 51 <!ATTLIST project groups CDATA #IMPLIED>
52
53 <!ELEMENT annotation (EMPTY)>
54 <!ATTLIST annotation name CDATA #REQUIRED>
55 <!ATTLIST annotation value CDATA #REQUIRED>
56 <!ATTLIST annotation keep CDATA "true">
52 57
53 <!ELEMENT remove-project (EMPTY)> 58 <!ELEMENT remove-project (EMPTY)>
54 <!ATTLIST remove-project name CDATA #REQUIRED> 59 <!ATTLIST remove-project name CDATA #REQUIRED>
@@ -163,6 +168,17 @@ Attribute `groups`: List of groups to which this project belongs,
163whitespace or comma separated. All projects are part of the group 168whitespace or comma separated. All projects are part of the group
164"default" unless "-default" is specified in the list of groups. 169"default" unless "-default" is specified in the list of groups.
165 170
171Element annotation
172------------------
173
174Zero or more annotation elements may be specified as children of a
175project element. Each element describes a name-value pair that will be
176exported into each project's environment during a 'forall' command,
177prefixed with REPO__. In addition, there is an optional attribute
178"keep" which accepts the case insensitive values "true" (default) or
179"false". This attribute determines whether or not the annotation will
180be kept when exported with the manifest subcommand.
181
166Element remove-project 182Element remove-project
167---------------------- 183----------------------
168 184
diff --git a/manifest_xml.py b/manifest_xml.py
index a250382f..9b804da9 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -203,6 +203,13 @@ class XmlManifest(object):
203 if p.groups: 203 if p.groups:
204 e.setAttribute('groups', ','.join(p.groups)) 204 e.setAttribute('groups', ','.join(p.groups))
205 205
206 for a in p.annotations:
207 if a.keep == "true":
208 ae = doc.createElement('annotation')
209 ae.setAttribute('name', a.name)
210 ae.setAttribute('value', a.value)
211 e.appendChild(ae)
212
206 if self._repo_hooks_project: 213 if self._repo_hooks_project:
207 root.appendChild(doc.createTextNode('')) 214 root.appendChild(doc.createTextNode(''))
208 e = doc.createElement('repo-hooks') 215 e = doc.createElement('repo-hooks')
@@ -545,6 +552,8 @@ class XmlManifest(object):
545 for n in node.childNodes: 552 for n in node.childNodes:
546 if n.nodeName == 'copyfile': 553 if n.nodeName == 'copyfile':
547 self._ParseCopyFile(project, n) 554 self._ParseCopyFile(project, n)
555 if n.nodeName == 'annotation':
556 self._ParseAnnotation(project, n)
548 557
549 return project 558 return project
550 559
@@ -556,6 +565,17 @@ class XmlManifest(object):
556 # dest is relative to the top of the tree 565 # dest is relative to the top of the tree
557 project.AddCopyFile(src, dest, os.path.join(self.topdir, dest)) 566 project.AddCopyFile(src, dest, os.path.join(self.topdir, dest))
558 567
568 def _ParseAnnotation(self, project, node):
569 name = self._reqatt(node, 'name')
570 value = self._reqatt(node, 'value')
571 try:
572 keep = self._reqatt(node, 'keep').lower()
573 except ManifestParseError:
574 keep = "true"
575 if keep != "true" and keep != "false":
576 raise ManifestParseError, "optional \"keep\" attribute must be \"true\" or \"false\""
577 project.AddAnnotation(name, value, keep)
578
559 def _get_remote(self, node): 579 def _get_remote(self, node):
560 name = node.getAttribute('remote') 580 name = node.getAttribute('remote')
561 if not name: 581 if not name:
diff --git a/project.py b/project.py
index 49fef2f7..e297926d 100644
--- a/project.py
+++ b/project.py
@@ -213,6 +213,11 @@ class DiffColoring(Coloring):
213 Coloring.__init__(self, config, 'diff') 213 Coloring.__init__(self, config, 'diff')
214 self.project = self.printer('header', attr = 'bold') 214 self.project = self.printer('header', attr = 'bold')
215 215
216class _Annotation:
217 def __init__(self, name, value, keep):
218 self.name = name
219 self.value = value
220 self.keep = keep
216 221
217class _CopyFile: 222class _CopyFile:
218 def __init__(self, src, dest, abssrc, absdest): 223 def __init__(self, src, dest, abssrc, absdest):
@@ -529,6 +534,7 @@ class Project(object):
529 534
530 self.snapshots = {} 535 self.snapshots = {}
531 self.copyfiles = [] 536 self.copyfiles = []
537 self.annotations = []
532 self.config = GitConfig.ForRepository( 538 self.config = GitConfig.ForRepository(
533 gitdir = self.gitdir, 539 gitdir = self.gitdir,
534 defaults = self.manifest.globalConfig) 540 defaults = self.manifest.globalConfig)
@@ -1175,6 +1181,9 @@ class Project(object):
1175 abssrc = os.path.join(self.worktree, src) 1181 abssrc = os.path.join(self.worktree, src)
1176 self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest)) 1182 self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest))
1177 1183
1184 def AddAnnotation(self, name, value, keep):
1185 self.annotations.append(_Annotation(name, value, keep))
1186
1178 def DownloadPatchSet(self, change_id, patch_id): 1187 def DownloadPatchSet(self, change_id, patch_id):
1179 """Download a single patch set of a single change to FETCH_HEAD. 1188 """Download a single patch set of a single change to FETCH_HEAD.
1180 """ 1189 """
diff --git a/subcmds/forall.py b/subcmds/forall.py
index d3e70ae1..9436f4e5 100644
--- a/subcmds/forall.py
+++ b/subcmds/forall.py
@@ -82,6 +82,11 @@ revision to a locally executed git command, use REPO_LREV.
82REPO_RREV is the name of the revision from the manifest, exactly 82REPO_RREV is the name of the revision from the manifest, exactly
83as written in the manifest. 83as written in the manifest.
84 84
85REPO__* are any extra environment variables, specified by the
86"annotation" element under any project element. This can be useful
87for differentiating trees based on user-specific criteria, or simply
88annotating tree details.
89
85shell positional arguments ($1, $2, .., $#) are set to any arguments 90shell positional arguments ($1, $2, .., $#) are set to any arguments
86following <command>. 91following <command>.
87 92
@@ -162,6 +167,8 @@ terminal and are not redirected.
162 setenv('REPO_REMOTE', project.remote.name) 167 setenv('REPO_REMOTE', project.remote.name)
163 setenv('REPO_LREV', project.GetRevisionId()) 168 setenv('REPO_LREV', project.GetRevisionId())
164 setenv('REPO_RREV', project.revisionExpr) 169 setenv('REPO_RREV', project.revisionExpr)
170 for a in project.annotations:
171 setenv("REPO__%s" % (a.name), a.value)
165 172
166 if mirror: 173 if mirror:
167 setenv('GIT_DIR', project.gitdir) 174 setenv('GIT_DIR', project.gitdir)