diff options
-rw-r--r-- | docs/manifest-format.md | 21 | ||||
-rw-r--r-- | manifest_xml.py | 17 | ||||
-rw-r--r-- | tests/test_manifest_xml.py | 59 |
3 files changed, 74 insertions, 23 deletions
diff --git a/docs/manifest-format.md b/docs/manifest-format.md index da83d0dd..0752a8cd 100644 --- a/docs/manifest-format.md +++ b/docs/manifest-format.md | |||
@@ -31,6 +31,7 @@ following DTD: | |||
31 | extend-project*, | 31 | extend-project*, |
32 | repo-hooks?, | 32 | repo-hooks?, |
33 | superproject?, | 33 | superproject?, |
34 | contactinfo?, | ||
34 | include*)> | 35 | include*)> |
35 | 36 | ||
36 | <!ELEMENT notice (#PCDATA)> | 37 | <!ELEMENT notice (#PCDATA)> |
@@ -100,10 +101,13 @@ following DTD: | |||
100 | <!ATTLIST repo-hooks in-project CDATA #REQUIRED> | 101 | <!ATTLIST repo-hooks in-project CDATA #REQUIRED> |
101 | <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED> | 102 | <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED> |
102 | 103 | ||
103 | <!ELEMENT superproject (EMPTY)> | 104 | <!ELEMENT superproject EMPTY> |
104 | <!ATTLIST superproject name CDATA #REQUIRED> | 105 | <!ATTLIST superproject name CDATA #REQUIRED> |
105 | <!ATTLIST superproject remote IDREF #IMPLIED> | 106 | <!ATTLIST superproject remote IDREF #IMPLIED> |
106 | 107 | ||
108 | <!ELEMENT contactinfo EMPTY> | ||
109 | <!ATTLIST contactinfo bugurl CDATA #REQUIRED> | ||
110 | |||
107 | <!ELEMENT include EMPTY> | 111 | <!ELEMENT include EMPTY> |
108 | <!ATTLIST include name CDATA #REQUIRED> | 112 | <!ATTLIST include name CDATA #REQUIRED> |
109 | <!ATTLIST include groups CDATA #IMPLIED> | 113 | <!ATTLIST include groups CDATA #IMPLIED> |
@@ -405,7 +409,7 @@ Attribute `enabled-list`: List of hooks to use, whitespace or comma separated. | |||
405 | ### Element superproject | 409 | ### Element superproject |
406 | 410 | ||
407 | *** | 411 | *** |
408 | *Note*: This is currently a WIP. | 412 | *Note*: This is currently a WIP. |
409 | *** | 413 | *** |
410 | 414 | ||
411 | NB: See the [git superprojects documentation]( | 415 | NB: See the [git superprojects documentation]( |
@@ -424,6 +428,19 @@ same meaning as project's name attribute. See the | |||
424 | Attribute `remote`: Name of a previously defined remote element. | 428 | Attribute `remote`: Name of a previously defined remote element. |
425 | If not supplied the remote given by the default element is used. | 429 | If not supplied the remote given by the default element is used. |
426 | 430 | ||
431 | ### Element contactinfo | ||
432 | |||
433 | *** | ||
434 | *Note*: This is currently a WIP. | ||
435 | *** | ||
436 | |||
437 | This element is used to let manifest authors self-register contact info. | ||
438 | It has "bugurl" as a required atrribute. This element can be repeated, | ||
439 | and any later entries will clobber earlier ones. This would allow manifest | ||
440 | authors who extend manifests to specify their own contact info. | ||
441 | |||
442 | Attribute `bugurl`: The URL to file a bug against the manifest owner. | ||
443 | |||
427 | ### Element include | 444 | ### Element include |
428 | 445 | ||
429 | This element provides the capability of including another manifest | 446 | This element provides the capability of including another manifest |
diff --git a/manifest_xml.py b/manifest_xml.py index 73556a5e..e1d630b3 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
@@ -479,6 +479,12 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
479 | e.setAttribute('remote', remoteName) | 479 | e.setAttribute('remote', remoteName) |
480 | root.appendChild(e) | 480 | root.appendChild(e) |
481 | 481 | ||
482 | if self._contactinfo: | ||
483 | root.appendChild(doc.createTextNode('')) | ||
484 | e = doc.createElement('contactinfo') | ||
485 | e.setAttribute('bugurl', self._contactinfo['bugurl']) | ||
486 | root.appendChild(e) | ||
487 | |||
482 | return doc | 488 | return doc |
483 | 489 | ||
484 | def ToDict(self, **kwargs): | 490 | def ToDict(self, **kwargs): |
@@ -490,6 +496,7 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
490 | 'manifest-server', | 496 | 'manifest-server', |
491 | 'repo-hooks', | 497 | 'repo-hooks', |
492 | 'superproject', | 498 | 'superproject', |
499 | 'contactinfo', | ||
493 | } | 500 | } |
494 | # Elements that may be repeated. | 501 | # Elements that may be repeated. |
495 | MULTI_ELEMENTS = { | 502 | MULTI_ELEMENTS = { |
@@ -566,6 +573,11 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
566 | return self._superproject | 573 | return self._superproject |
567 | 574 | ||
568 | @property | 575 | @property |
576 | def contactinfo(self): | ||
577 | self._Load() | ||
578 | return self._contactinfo | ||
579 | |||
580 | @property | ||
569 | def notice(self): | 581 | def notice(self): |
570 | self._Load() | 582 | self._Load() |
571 | return self._notice | 583 | return self._notice |
@@ -634,6 +646,7 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
634 | self._default = None | 646 | self._default = None |
635 | self._repo_hooks_project = None | 647 | self._repo_hooks_project = None |
636 | self._superproject = {} | 648 | self._superproject = {} |
649 | self._contactinfo = {} | ||
637 | self._notice = None | 650 | self._notice = None |
638 | self.branch = None | 651 | self.branch = None |
639 | self._manifest_server = None | 652 | self._manifest_server = None |
@@ -876,6 +889,10 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
876 | raise ManifestParseError("no remote for superproject %s within %s" % | 889 | raise ManifestParseError("no remote for superproject %s within %s" % |
877 | (name, self.manifestFile)) | 890 | (name, self.manifestFile)) |
878 | self._superproject['remote'] = remote.ToRemoteSpec(name) | 891 | self._superproject['remote'] = remote.ToRemoteSpec(name) |
892 | if node.nodeName == 'contactinfo': | ||
893 | bugurl = self._reqatt(node, 'bugurl') | ||
894 | # This element can be repeated, later entries will clobber earlier ones. | ||
895 | self._contactinfo['bugurl'] = bugurl | ||
879 | if node.nodeName == 'remove-project': | 896 | if node.nodeName == 'remove-project': |
880 | name = self._reqatt(node, 'name') | 897 | name = self._reqatt(node, 'name') |
881 | 898 | ||
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py index e78d85c3..bfdf366e 100644 --- a/tests/test_manifest_xml.py +++ b/tests/test_manifest_xml.py | |||
@@ -255,10 +255,10 @@ class XmlManifestTests(ManifestParseTestCase): | |||
255 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') | 255 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') |
256 | self.assertEqual( | 256 | self.assertEqual( |
257 | manifest.ToXml().toxml(), | 257 | manifest.ToXml().toxml(), |
258 | '<?xml version="1.0" ?><manifest>' + | 258 | '<?xml version="1.0" ?><manifest>' |
259 | '<remote name="test-remote" fetch="http://localhost"/>' + | 259 | '<remote name="test-remote" fetch="http://localhost"/>' |
260 | '<default remote="test-remote" revision="refs/heads/main"/>' + | 260 | '<default remote="test-remote" revision="refs/heads/main"/>' |
261 | '<superproject name="superproject"/>' + | 261 | '<superproject name="superproject"/>' |
262 | '</manifest>') | 262 | '</manifest>') |
263 | 263 | ||
264 | 264 | ||
@@ -409,10 +409,10 @@ class ProjectElementTests(ManifestParseTestCase): | |||
409 | project.SetRevisionId('ABCDEF') | 409 | project.SetRevisionId('ABCDEF') |
410 | self.assertEqual( | 410 | self.assertEqual( |
411 | manifest.ToXml().toxml(), | 411 | manifest.ToXml().toxml(), |
412 | '<?xml version="1.0" ?><manifest>' + | 412 | '<?xml version="1.0" ?><manifest>' |
413 | '<remote name="default-remote" fetch="http://localhost"/>' + | 413 | '<remote name="default-remote" fetch="http://localhost"/>' |
414 | '<default remote="default-remote" revision="refs/heads/main"/>' + | 414 | '<default remote="default-remote" revision="refs/heads/main"/>' |
415 | '<project name="test-name" revision="ABCDEF"/>' + | 415 | '<project name="test-name" revision="ABCDEF"/>' |
416 | '</manifest>') | 416 | '</manifest>') |
417 | 417 | ||
418 | def test_trailing_slash(self): | 418 | def test_trailing_slash(self): |
@@ -517,10 +517,10 @@ class SuperProjectElementTests(ManifestParseTestCase): | |||
517 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') | 517 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') |
518 | self.assertEqual( | 518 | self.assertEqual( |
519 | manifest.ToXml().toxml(), | 519 | manifest.ToXml().toxml(), |
520 | '<?xml version="1.0" ?><manifest>' + | 520 | '<?xml version="1.0" ?><manifest>' |
521 | '<remote name="test-remote" fetch="http://localhost"/>' + | 521 | '<remote name="test-remote" fetch="http://localhost"/>' |
522 | '<default remote="test-remote" revision="refs/heads/main"/>' + | 522 | '<default remote="test-remote" revision="refs/heads/main"/>' |
523 | '<superproject name="superproject"/>' + | 523 | '<superproject name="superproject"/>' |
524 | '</manifest>') | 524 | '</manifest>') |
525 | 525 | ||
526 | def test_remote(self): | 526 | def test_remote(self): |
@@ -538,11 +538,11 @@ class SuperProjectElementTests(ManifestParseTestCase): | |||
538 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/platform/superproject') | 538 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/platform/superproject') |
539 | self.assertEqual( | 539 | self.assertEqual( |
540 | manifest.ToXml().toxml(), | 540 | manifest.ToXml().toxml(), |
541 | '<?xml version="1.0" ?><manifest>' + | 541 | '<?xml version="1.0" ?><manifest>' |
542 | '<remote name="default-remote" fetch="http://localhost"/>' + | 542 | '<remote name="default-remote" fetch="http://localhost"/>' |
543 | '<remote name="superproject-remote" fetch="http://localhost"/>' + | 543 | '<remote name="superproject-remote" fetch="http://localhost"/>' |
544 | '<default remote="default-remote" revision="refs/heads/main"/>' + | 544 | '<default remote="default-remote" revision="refs/heads/main"/>' |
545 | '<superproject name="platform/superproject" remote="superproject-remote"/>' + | 545 | '<superproject name="platform/superproject" remote="superproject-remote"/>' |
546 | '</manifest>') | 546 | '</manifest>') |
547 | 547 | ||
548 | def test_defalut_remote(self): | 548 | def test_defalut_remote(self): |
@@ -558,8 +558,25 @@ class SuperProjectElementTests(ManifestParseTestCase): | |||
558 | self.assertEqual(manifest.superproject['remote'].name, 'default-remote') | 558 | self.assertEqual(manifest.superproject['remote'].name, 'default-remote') |
559 | self.assertEqual( | 559 | self.assertEqual( |
560 | manifest.ToXml().toxml(), | 560 | manifest.ToXml().toxml(), |
561 | '<?xml version="1.0" ?><manifest>' + | 561 | '<?xml version="1.0" ?><manifest>' |
562 | '<remote name="default-remote" fetch="http://localhost"/>' + | 562 | '<remote name="default-remote" fetch="http://localhost"/>' |
563 | '<default remote="default-remote" revision="refs/heads/main"/>' + | 563 | '<default remote="default-remote" revision="refs/heads/main"/>' |
564 | '<superproject name="superproject"/>' + | 564 | '<superproject name="superproject"/>' |
565 | '</manifest>') | 565 | '</manifest>') |
566 | |||
567 | |||
568 | class ContactinfoElementTests(ManifestParseTestCase): | ||
569 | """Tests for <contactinfo>.""" | ||
570 | |||
571 | def test_contactinfo(self): | ||
572 | """Check contactinfo settings.""" | ||
573 | bugurl = 'http://localhost/contactinfo' | ||
574 | manifest = self.getXmlManifest(f""" | ||
575 | <manifest> | ||
576 | <contactinfo bugurl="{bugurl}"/> | ||
577 | </manifest> | ||
578 | """) | ||
579 | self.assertEqual(manifest.contactinfo['bugurl'], bugurl) | ||
580 | self.assertEqual( | ||
581 | manifest.ToXml().toxml(), | ||
582 | f"""<?xml version="1.0" ?><manifest><contactinfo bugurl="{bugurl}"/></manifest>""") | ||