From 1bb4fb222d831ed384d6fdef7402d36c19e91b2e Mon Sep 17 00:00:00 2001 From: Raman Tenneti Date: Thu, 7 Jan 2021 16:50:45 -0800 Subject: [PATCH] manifest_xml: initial support for 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. 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 Change-Id: I5b4bba02c8b59601c754cf6b5e4d07a1e16ce167 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/292982 Reviewed-by: Mike Frysinger --- docs/manifest-format.md | 27 +++++++++++++++++ manifest_xml.py | 37 ++++++++++++++++++++++++ tests/test_manifest_xml.py | 59 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) 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: project*, extend-project*, repo-hooks?, + superproject?, include*)> @@ -98,6 +99,10 @@ following DTD: + + + + @@ -377,6 +382,28 @@ defined `project` element. Attribute `enabled-list`: List of hooks to use, whitespace or comma separated. +### Element superproject + +*** + *Note*: This is currently a WIP. +*** + +NB: See the [git superprojects documentation]( +https://en.wikibooks.org/wiki/Git/Submodules_and_Superprojects) for background +information. + +This element is used to specify the URL of the superproject. It has "name" and +"remote" as atrributes. Only "name" is required while the others have +reasonable defaults. At most one superproject may be specified. +Attempting to redefine it will fail to parse. + +Attribute `name`: A unique name for the superproject. This attribute has the +same meaning as project's name attribute. See the +[element project](#element-project) for more information. + +Attribute `remote`: Name of a previously defined remote element. +If not supplied the remote given by the default element is used. + ### Element include This 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 ' '.join(self._repo_hooks_project.enabled_repo_hooks)) root.appendChild(e) + if self._superproject: + root.appendChild(doc.createTextNode('')) + e = doc.createElement('superproject') + e.setAttribute('name', self._superproject['name']) + remoteName = None + if d.remote: + remoteName = d.remote.name + remote = self._superproject.get('remote') + if not d.remote or remote.orig_name != remoteName: + remoteName = remote.orig_name + e.setAttribute('remote', remoteName) + root.appendChild(e) + return doc def ToDict(self, **kwargs): @@ -473,6 +486,7 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md 'default', 'manifest-server', 'repo-hooks', + 'superproject', } # Elements that may be repeated. MULTI_ELEMENTS = { @@ -544,6 +558,11 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md self._Load() return self._repo_hooks_project + @property + def superproject(self): + self._Load() + return self._superproject + @property def notice(self): self._Load() @@ -591,6 +610,7 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md self._remotes = {} self._default = None self._repo_hooks_project = None + self._superproject = {} self._notice = None self.branch = None self._manifest_server = None @@ -793,6 +813,23 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md # Store the enabled hooks in the Project object. self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks + if node.nodeName == 'superproject': + name = self._reqatt(node, 'name') + # There can only be one superproject. + if self._superproject.get('name'): + raise ManifestParseError( + 'duplicate superproject in %s' % + (self.manifestFile)) + self._superproject['name'] = name + remote_name = node.getAttribute('remote') + if not remote_name: + remote = self._default.remote + else: + remote = self._get_remote(node) + if remote is None: + raise ManifestParseError("no remote for superproject %s within %s" % + (name, self.manifestFile)) + self._superproject['remote'] = remote.ToRemoteSpec(name) if node.nodeName == 'remove-project': name = self._reqatt(node, 'name') 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): self.assertEqual(manifest.repo_hooks_project.name, 'repohooks') self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b']) + def test_superproject(self): + """Check superproject settings.""" + manifest = self.getXmlManifest(""" + + + + + +""") + self.assertEqual(manifest.superproject['name'], 'superproject') + self.assertEqual(manifest.superproject['remote'].name, 'test-remote') + self.assertEqual( + manifest.ToXml().toxml(), + '' + + '' + + '' + + '' + + '') + + def test_superproject_with_remote(self): + """Check superproject settings.""" + manifest = self.getXmlManifest(""" + + + + + + +""") + self.assertEqual(manifest.superproject['name'], 'superproject') + self.assertEqual(manifest.superproject['remote'].name, 'test-remote') + self.assertEqual( + manifest.ToXml().toxml(), + '' + + '' + + '' + + '' + + '' + + '') + + def test_superproject_with_defalut_remote(self): + """Check superproject settings.""" + manifest = self.getXmlManifest(""" + + + + + +""") + self.assertEqual(manifest.superproject['name'], 'superproject') + self.assertEqual(manifest.superproject['remote'].name, 'default-remote') + self.assertEqual( + manifest.ToXml().toxml(), + '' + + '' + + '' + + '' + + '') + def test_project_group(self): """Check project group settings.""" manifest = self.getXmlManifest("""