manifest: make repo-hooks more robust wrt element ordering
Currently, repo will fail to sync to a manifest if the definition
of the repo-hooks project comes after the repo-hooks element.
BUG=none
TEST=new test, run_tests
Change-Id: I0bf85625173492af6c6404d4b67543e96e670562
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/318520
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Jack Neus <jackneus@google.com>
diff --git a/manifest_xml.py b/manifest_xml.py
index 55ad6c0..7099d5f 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -852,6 +852,8 @@
for subproject in project.subprojects:
recursively_add_projects(subproject)
+ repo_hooks_project = None
+ enabled_repo_hooks = None
for node in itertools.chain(*node_list):
if node.nodeName == 'project':
project = self._ParseProject(node)
@@ -886,32 +888,15 @@
if remote:
p.remote = remote.ToRemoteSpec(name)
if node.nodeName == 'repo-hooks':
- # Get the name of the project and the (space-separated) list of enabled.
- repo_hooks_project = self._reqatt(node, 'in-project')
- enabled_repo_hooks = self._ParseList(self._reqatt(node, 'enabled-list'))
-
# Only one project can be the hooks project
- if self._repo_hooks_project is not None:
+ if repo_hooks_project is not None:
raise ManifestParseError(
'duplicate repo-hooks in %s' %
(self.manifestFile))
- # Store a reference to the Project.
- try:
- repo_hooks_projects = self._projects[repo_hooks_project]
- except KeyError:
- raise ManifestParseError(
- 'project %s not found for repo-hooks' %
- (repo_hooks_project))
-
- if len(repo_hooks_projects) != 1:
- raise ManifestParseError(
- 'internal error parsing repo-hooks in %s' %
- (self.manifestFile))
- self._repo_hooks_project = repo_hooks_projects[0]
-
- # Store the enabled hooks in the Project object.
- self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks
+ # Get the name of the project and the (space-separated) list of enabled.
+ repo_hooks_project = self._reqatt(node, 'in-project')
+ enabled_repo_hooks = self._ParseList(self._reqatt(node, 'enabled-list'))
if node.nodeName == 'superproject':
name = self._reqatt(node, 'name')
# There can only be one superproject.
@@ -944,12 +929,30 @@
# If the manifest removes the hooks project, treat it as if it deleted
# the repo-hooks element too.
- if self._repo_hooks_project and (self._repo_hooks_project.name == name):
- self._repo_hooks_project = None
+ if repo_hooks_project == name:
+ repo_hooks_project = None
elif not XmlBool(node, 'optional', False):
raise ManifestParseError('remove-project element specifies non-existent '
'project: %s' % name)
+ # Store repo hooks project information.
+ if repo_hooks_project:
+ # Store a reference to the Project.
+ try:
+ repo_hooks_projects = self._projects[repo_hooks_project]
+ except KeyError:
+ raise ManifestParseError(
+ 'project %s not found for repo-hooks' %
+ (repo_hooks_project))
+
+ if len(repo_hooks_projects) != 1:
+ raise ManifestParseError(
+ 'internal error parsing repo-hooks in %s' %
+ (self.manifestFile))
+ self._repo_hooks_project = repo_hooks_projects[0]
+ # Store the enabled hooks in the Project object.
+ self._repo_hooks_project.enabled_repo_hooks = enabled_repo_hooks
+
def _AddMetaProjectMirror(self, m):
name = None
m_url = m.GetRemote(m.remote.name).url
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py
index 59f2a77..20459d1 100644
--- a/tests/test_manifest_xml.py
+++ b/tests/test_manifest_xml.py
@@ -265,6 +265,19 @@
self.assertEqual(manifest.repo_hooks_project.name, 'repohooks')
self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b'])
+ def test_repo_hooks_unordered(self):
+ """Check repo-hooks settings work even if the project def comes second."""
+ manifest = self.getXmlManifest("""
+<manifest>
+ <remote name="test-remote" fetch="http://localhost" />
+ <default remote="test-remote" revision="refs/heads/main" />
+ <repo-hooks in-project="repohooks" enabled-list="a, b"/>
+ <project name="repohooks" path="src/repohooks"/>
+</manifest>
+""")
+ self.assertEqual(manifest.repo_hooks_project.name, 'repohooks')
+ self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b'])
+
def test_unknown_tags(self):
"""Check superproject settings."""
manifest = self.getXmlManifest("""