diff options
-rw-r--r-- | docs/manifest-format.md | 27 | ||||
-rw-r--r-- | manifest_xml.py | 37 | ||||
-rw-r--r-- | tests/test_manifest_xml.py | 59 |
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 | ||
378 | Attribute `enabled-list`: List of hooks to use, whitespace or comma separated. | 383 | Attribute `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 | |||
391 | NB: See the [git superprojects documentation]( | ||
392 | https://en.wikibooks.org/wiki/Git/Submodules_and_Superprojects) for background | ||
393 | information. | ||
394 | |||
395 | This 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 | ||
397 | reasonable defaults. At most one superproject may be specified. | ||
398 | Attempting to redefine it will fail to parse. | ||
399 | |||
400 | Attribute `name`: A unique name for the superproject. This attribute has the | ||
401 | same meaning as project's name attribute. See the | ||
402 | [element project](#element-project) for more information. | ||
403 | |||
404 | Attribute `remote`: Name of a previously defined remote element. | ||
405 | If not supplied the remote given by the default element is used. | ||
406 | |||
380 | ### Element include | 407 | ### Element include |
381 | 408 | ||
382 | This element provides the capability of including another manifest | 409 | 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 | |||
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(""" |