summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/manifest-format.md8
-rw-r--r--manifest_xml.py21
-rw-r--r--tests/test_manifest_xml.py39
3 files changed, 64 insertions, 4 deletions
diff --git a/docs/manifest-format.md b/docs/manifest-format.md
index bcdf5a8e..edcb28cb 100644
--- a/docs/manifest-format.md
+++ b/docs/manifest-format.md
@@ -125,8 +125,9 @@ following DTD:
125 <!ATTLIST contactinfo bugurl CDATA #REQUIRED> 125 <!ATTLIST contactinfo bugurl CDATA #REQUIRED>
126 126
127 <!ELEMENT include EMPTY> 127 <!ELEMENT include EMPTY>
128 <!ATTLIST include name CDATA #REQUIRED> 128 <!ATTLIST include name CDATA #REQUIRED>
129 <!ATTLIST include groups CDATA #IMPLIED> 129 <!ATTLIST include groups CDATA #IMPLIED>
130 <!ATTLIST include revision CDATA #IMPLIED>
130]> 131]>
131``` 132```
132 133
@@ -553,6 +554,9 @@ in the included manifest belong. This appends and recurses, meaning
553all projects in included manifests carry all parent include groups. 554all projects in included manifests carry all parent include groups.
554Same syntax as the corresponding element of `project`. 555Same syntax as the corresponding element of `project`.
555 556
557Attribute `revision`: Name of a Git branch (e.g. `main` or `refs/heads/main`)
558default to which all projects in the included manifest belong.
559
556## Local Manifests {#local-manifests} 560## Local Manifests {#local-manifests}
557 561
558Additional remotes and projects may be added through local manifest 562Additional remotes and projects may be added through local manifest
diff --git a/manifest_xml.py b/manifest_xml.py
index 9603906f..14b03a30 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -1233,7 +1233,12 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
1233 ) 1233 )
1234 1234
1235 def _ParseManifestXml( 1235 def _ParseManifestXml(
1236 self, path, include_root, parent_groups="", restrict_includes=True 1236 self,
1237 path,
1238 include_root,
1239 parent_groups="",
1240 restrict_includes=True,
1241 parent_node=None,
1237 ): 1242 ):
1238 """Parse a manifest XML and return the computed nodes. 1243 """Parse a manifest XML and return the computed nodes.
1239 1244
@@ -1243,6 +1248,8 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
1243 parent_groups: The groups to apply to this projects. 1248 parent_groups: The groups to apply to this projects.
1244 restrict_includes: Whether to constrain the "name" attribute of 1249 restrict_includes: Whether to constrain the "name" attribute of
1245 includes. 1250 includes.
1251 parent_node: The parent include node, to apply attribute to this
1252 projects.
1246 1253
1247 Returns: 1254 Returns:
1248 List of XML nodes. 1255 List of XML nodes.
@@ -1288,7 +1295,9 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
1288 ) 1295 )
1289 try: 1296 try:
1290 nodes.extend( 1297 nodes.extend(
1291 self._ParseManifestXml(fp, include_root, include_groups) 1298 self._ParseManifestXml(
1299 fp, include_root, include_groups, parent_node=node
1300 )
1292 ) 1301 )
1293 # should isolate this to the exact exception, but that's 1302 # should isolate this to the exact exception, but that's
1294 # tricky. actual parsing implementation may vary. 1303 # tricky. actual parsing implementation may vary.
@@ -1311,6 +1320,14 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
1311 node.getAttribute("groups") + "," + nodeGroups 1320 node.getAttribute("groups") + "," + nodeGroups
1312 ) 1321 )
1313 node.setAttribute("groups", nodeGroups) 1322 node.setAttribute("groups", nodeGroups)
1323 if (
1324 parent_node
1325 and node.nodeName == "project"
1326 and not node.hasAttribute("revision")
1327 ):
1328 node.setAttribute(
1329 "revision", parent_node.getAttribute("revision")
1330 )
1314 nodes.append(node) 1331 nodes.append(node)
1315 return nodes 1332 return nodes
1316 1333
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py
index 648acde8..ef511055 100644
--- a/tests/test_manifest_xml.py
+++ b/tests/test_manifest_xml.py
@@ -389,6 +389,45 @@ class XmlManifestTests(ManifestParseTestCase):
389class IncludeElementTests(ManifestParseTestCase): 389class IncludeElementTests(ManifestParseTestCase):
390 """Tests for <include>.""" 390 """Tests for <include>."""
391 391
392 def test_revision_default(self):
393 """Check handling of revision attribute."""
394 root_m = os.path.join(self.manifest_dir, "root.xml")
395 with open(root_m, "w") as fp:
396 fp.write(
397 """
398<manifest>
399 <remote name="test-remote" fetch="http://localhost" />
400 <default remote="test-remote" revision="refs/heads/main" />
401 <include name="stable.xml" revision="stable-branch" />
402 <project name="root-name1" path="root-path1" />
403 <project name="root-name2" path="root-path2" />
404</manifest>
405"""
406 )
407 with open(os.path.join(self.manifest_dir, "stable.xml"), "w") as fp:
408 fp.write(
409 """
410<manifest>
411 <project name="stable-name1" path="stable-path1" />
412 <project name="stable-name2" path="stable-path2" revision="stable-branch2" />
413</manifest>
414"""
415 )
416 include_m = manifest_xml.XmlManifest(self.repodir, root_m)
417 for proj in include_m.projects:
418 if proj.name == "root-name1":
419 # Check include revision not set on root level proj.
420 self.assertNotEqual("stable-branch", proj.revisionExpr)
421 if proj.name == "root-name2":
422 # Check root proj revision not removed.
423 self.assertEqual("refs/heads/main", proj.revisionExpr)
424 if proj.name == "stable-name1":
425 # Check stable proj has inherited revision include node.
426 self.assertEqual("stable-branch", proj.revisionExpr)
427 if proj.name == "stable-name2":
428 # Check stable proj revision can override include node.
429 self.assertEqual("stable-branch2", proj.revisionExpr)
430
392 def test_group_levels(self): 431 def test_group_levels(self):
393 root_m = os.path.join(self.manifest_dir, "root.xml") 432 root_m = os.path.join(self.manifest_dir, "root.xml")
394 with open(root_m, "w") as fp: 433 with open(root_m, "w") as fp: