summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaman Tenneti <rtenneti@google.com>2021-01-07 16:50:45 -0800
committerRaman Tenneti <rtenneti@google.com>2021-01-08 19:49:52 +0000
commit1bb4fb222d831ed384d6fdef7402d36c19e91b2e (patch)
treeb915dfcb1352d29ce1fdd9b364d591be3e3ee289
parentb64bec6acc0e2a835f427d8424af89dfcddaf08f (diff)
downloadgit-repo-1bb4fb222d831ed384d6fdef7402d36c19e91b2e.tar.gz
manifest_xml: initial support for <superproject>
At most one superproject may be specified. It will be used to specify the URL of superproject. It would have 3 attributes: remote, name, and default. Only "name" is required while the others have reasonable defaults. <remote name="superproject-url" review="<url>" /> <superproject remote="superproject-url" name="platform/superproject"/> TODO: This CL only implements the parsing logic and further work will be in followup CLs. Tested the code with the following commands. $ ./run_tests tests/test_manifest_xml.py $ ./run_tests -v Bug: https://crbug.com/gerrit/13709 Tested-by: Raman Tenneti <rtenneti@google.com> Change-Id: I5b4bba02c8b59601c754cf6b5e4d07a1e16ce167 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/292982 Reviewed-by: Mike Frysinger <vapier@google.com>
-rw-r--r--docs/manifest-format.md27
-rw-r--r--manifest_xml.py37
-rw-r--r--tests/test_manifest_xml.py59
3 files changed, 123 insertions, 0 deletions
diff --git a/docs/manifest-format.md b/docs/manifest-format.md
index ca385ba3..8e5e2874 100644
--- a/docs/manifest-format.md
+++ b/docs/manifest-format.md
@@ -29,6 +29,7 @@ following DTD:
29 project*, 29 project*,
30 extend-project*, 30 extend-project*,
31 repo-hooks?, 31 repo-hooks?,
32 superproject?,
32 include*)> 33 include*)>
33 34
34 <!ELEMENT notice (#PCDATA)> 35 <!ELEMENT notice (#PCDATA)>
@@ -98,6 +99,10 @@ following DTD:
98 <!ATTLIST repo-hooks in-project CDATA #REQUIRED> 99 <!ATTLIST repo-hooks in-project CDATA #REQUIRED>
99 <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED> 100 <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED>
100 101
102 <!ELEMENT superproject (EMPTY)>
103 <!ATTLIST superproject name CDATA #REQUIRED>
104 <!ATTLIST superproject remote IDREF #IMPLIED>
105
101 <!ELEMENT include EMPTY> 106 <!ELEMENT include EMPTY>
102 <!ATTLIST include name CDATA #REQUIRED> 107 <!ATTLIST include name CDATA #REQUIRED>
103 <!ATTLIST include groups CDATA #IMPLIED> 108 <!ATTLIST include groups CDATA #IMPLIED>
@@ -377,6 +382,28 @@ defined `project` element.
377 382
378Attribute `enabled-list`: List of hooks to use, whitespace or comma separated. 383Attribute `enabled-list`: List of hooks to use, whitespace or comma separated.
379 384
385### Element superproject
386
387***
388 *Note*: This is currently a WIP.
389***
390
391NB: See the [git superprojects documentation](
392https://en.wikibooks.org/wiki/Git/Submodules_and_Superprojects) for background
393information.
394
395This element is used to specify the URL of the superproject. It has "name" and
396"remote" as atrributes. Only "name" is required while the others have
397reasonable defaults. At most one superproject may be specified.
398Attempting to redefine it will fail to parse.
399
400Attribute `name`: A unique name for the superproject. This attribute has the
401same meaning as project's name attribute. See the
402[element project](#element-project) for more information.
403
404Attribute `remote`: Name of a previously defined remote element.
405If not supplied the remote given by the default element is used.
406
380### Element include 407### Element include
381 408
382This element provides the capability of including another manifest 409This element provides the capability of including another manifest
diff --git a/manifest_xml.py b/manifest_xml.py
index 9b7a81b3..eb8a98cc 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -463,6 +463,19 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
463 ' '.join(self._repo_hooks_project.enabled_repo_hooks)) 463 ' '.join(self._repo_hooks_project.enabled_repo_hooks))
464 root.appendChild(e) 464 root.appendChild(e)
465 465
466 if self._superproject:
467 root.appendChild(doc.createTextNode(''))
468 e = doc.createElement('superproject')
469 e.setAttribute('name', self._superproject['name'])
470 remoteName = None
471 if d.remote:
472 remoteName = d.remote.name
473 remote = self._superproject.get('remote')
474 if not d.remote or remote.orig_name != remoteName:
475 remoteName = remote.orig_name
476 e.setAttribute('remote', remoteName)
477 root.appendChild(e)
478
466 return doc 479 return doc
467 480
468 def ToDict(self, **kwargs): 481 def ToDict(self, **kwargs):
@@ -473,6 +486,7 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
473 'default', 486 'default',
474 'manifest-server', 487 'manifest-server',
475 'repo-hooks', 488 'repo-hooks',
489 'superproject',
476 } 490 }
477 # Elements that may be repeated. 491 # Elements that may be repeated.
478 MULTI_ELEMENTS = { 492 MULTI_ELEMENTS = {
@@ -545,6 +559,11 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
545 return self._repo_hooks_project 559 return self._repo_hooks_project
546 560
547 @property 561 @property
562 def superproject(self):
563 self._Load()
564 return self._superproject
565
566 @property
548 def notice(self): 567 def notice(self):
549 self._Load() 568 self._Load()
550 return self._notice 569 return self._notice
@@ -591,6 +610,7 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
591 self._remotes = {} 610 self._remotes = {}
592 self._default = None 611 self._default = None
593 self._repo_hooks_project = None 612 self._repo_hooks_project = None
613 self._superproject = {}
594 self._notice = None 614 self._notice = None
595 self.branch = None 615 self.branch = None
596 self._manifest_server = None 616 self._manifest_server = None
@@ -793,6 +813,23 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
793 813
794 # Store the enabled hooks in the Project object. 814 # Store the enabled hooks in the Project object.
795 self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks 815 self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks
816 if node.nodeName == 'superproject':
817 name = self._reqatt(node, 'name')
818 # There can only be one superproject.
819 if self._superproject.get('name'):
820 raise ManifestParseError(
821 'duplicate superproject in %s' %
822 (self.manifestFile))
823 self._superproject['name'] = name
824 remote_name = node.getAttribute('remote')
825 if not remote_name:
826 remote = self._default.remote
827 else:
828 remote = self._get_remote(node)
829 if remote is None:
830 raise ManifestParseError("no remote for superproject %s within %s" %
831 (name, self.manifestFile))
832 self._superproject['remote'] = remote.ToRemoteSpec(name)
796 if node.nodeName == 'remove-project': 833 if node.nodeName == 'remove-project':
797 name = self._reqatt(node, 'name') 834 name = self._reqatt(node, 'name')
798 835
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py
index d53ea568..e4adf3c9 100644
--- a/tests/test_manifest_xml.py
+++ b/tests/test_manifest_xml.py
@@ -221,6 +221,65 @@ class XmlManifestTests(unittest.TestCase):
221 self.assertEqual(manifest.repo_hooks_project.name, 'repohooks') 221 self.assertEqual(manifest.repo_hooks_project.name, 'repohooks')
222 self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b']) 222 self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b'])
223 223
224 def test_superproject(self):
225 """Check superproject settings."""
226 manifest = self.getXmlManifest("""
227<manifest>
228 <remote name="test-remote" fetch="http://localhost" />
229 <default remote="test-remote" revision="refs/heads/main" />
230 <superproject name="superproject"/>
231</manifest>
232""")
233 self.assertEqual(manifest.superproject['name'], 'superproject')
234 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
235 self.assertEqual(
236 manifest.ToXml().toxml(),
237 '<?xml version="1.0" ?><manifest>' +
238 '<remote name="test-remote" fetch="http://localhost"/>' +
239 '<default remote="test-remote" revision="refs/heads/main"/>' +
240 '<superproject name="superproject"/>' +
241 '</manifest>')
242
243 def test_superproject_with_remote(self):
244 """Check superproject settings."""
245 manifest = self.getXmlManifest("""
246<manifest>
247 <remote name="default-remote" fetch="http://localhost" />
248 <remote name="test-remote" fetch="http://localhost" />
249 <default remote="default-remote" revision="refs/heads/main" />
250 <superproject name="superproject" remote="test-remote"/>
251</manifest>
252""")
253 self.assertEqual(manifest.superproject['name'], 'superproject')
254 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
255 self.assertEqual(
256 manifest.ToXml().toxml(),
257 '<?xml version="1.0" ?><manifest>' +
258 '<remote name="default-remote" fetch="http://localhost"/>' +
259 '<remote name="test-remote" fetch="http://localhost"/>' +
260 '<default remote="default-remote" revision="refs/heads/main"/>' +
261 '<superproject name="superproject" remote="test-remote"/>' +
262 '</manifest>')
263
264 def test_superproject_with_defalut_remote(self):
265 """Check superproject settings."""
266 manifest = self.getXmlManifest("""
267<manifest>
268 <remote name="default-remote" fetch="http://localhost" />
269 <default remote="default-remote" revision="refs/heads/main" />
270 <superproject name="superproject" remote="default-remote"/>
271</manifest>
272""")
273 self.assertEqual(manifest.superproject['name'], 'superproject')
274 self.assertEqual(manifest.superproject['remote'].name, 'default-remote')
275 self.assertEqual(
276 manifest.ToXml().toxml(),
277 '<?xml version="1.0" ?><manifest>' +
278 '<remote name="default-remote" fetch="http://localhost"/>' +
279 '<default remote="default-remote" revision="refs/heads/main"/>' +
280 '<superproject name="superproject"/>' +
281 '</manifest>')
282
224 def test_project_group(self): 283 def test_project_group(self):
225 """Check project group settings.""" 284 """Check project group settings."""
226 manifest = self.getXmlManifest(""" 285 manifest = self.getXmlManifest("""