diff options
author | LaMont Jones <lamontjones@google.com> | 2022-04-14 15:00:09 +0000 |
---|---|---|
committer | LaMont Jones <lamontjones@google.com> | 2022-04-19 21:28:20 +0000 |
commit | b90a422ab692657709ed49783212f7febe445ac7 (patch) | |
tree | 1cba036265a2f34a96cd89198151530a20fed8b1 /manifest_xml.py | |
parent | a46047a822ad13738af9b17a524a0bd483b98033 (diff) | |
download | git-repo-b90a422ab692657709ed49783212f7febe445ac7.tar.gz |
Override the manifest for the entire command
When a manifest file is overridden, remember that and keep using the
override for the remainder of the process. If we need to revert it,
make the override name evaluate False.
Change-Id: I1eee05fec6988c1ee4a3c751c4b540d5b5d11797
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/335136
Tested-by: LaMont Jones <lamontjones@google.com>
Reviewed-by: Mike Frysinger <vapier@google.com>
Diffstat (limited to 'manifest_xml.py')
-rw-r--r-- | manifest_xml.py | 122 |
1 files changed, 69 insertions, 53 deletions
diff --git a/manifest_xml.py b/manifest_xml.py index 7d19d63e..dbab974b 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
@@ -215,8 +215,9 @@ class _XmlSubmanifest: | |||
215 | manifestName: a string, the submanifest file name. | 215 | manifestName: a string, the submanifest file name. |
216 | groups: a list of strings, the groups to add to all projects in the submanifest. | 216 | groups: a list of strings, the groups to add to all projects in the submanifest. |
217 | path: a string, the relative path for the submanifest checkout. | 217 | path: a string, the relative path for the submanifest checkout. |
218 | parent: an XmlManifest, the parent manifest. | ||
218 | annotations: (derived) a list of annotations. | 219 | annotations: (derived) a list of annotations. |
219 | present: (derived) a boolean, whether the submanifest's manifest file is present. | 220 | present: (derived) a boolean, whether the sub manifest file is present. |
220 | """ | 221 | """ |
221 | def __init__(self, | 222 | def __init__(self, |
222 | name, | 223 | name, |
@@ -234,6 +235,7 @@ class _XmlSubmanifest: | |||
234 | self.manifestName = manifestName | 235 | self.manifestName = manifestName |
235 | self.groups = groups | 236 | self.groups = groups |
236 | self.path = path | 237 | self.path = path |
238 | self.parent = parent | ||
237 | self.annotations = [] | 239 | self.annotations = [] |
238 | outer_client = parent._outer_client or parent | 240 | outer_client = parent._outer_client or parent |
239 | if self.remote and not self.project: | 241 | if self.remote and not self.project: |
@@ -268,10 +270,10 @@ class _XmlSubmanifest: | |||
268 | def __ne__(self, other): | 270 | def __ne__(self, other): |
269 | return not self.__eq__(other) | 271 | return not self.__eq__(other) |
270 | 272 | ||
271 | def ToSubmanifestSpec(self, root): | 273 | def ToSubmanifestSpec(self): |
272 | """Return a SubmanifestSpec object, populating attributes""" | 274 | """Return a SubmanifestSpec object, populating attributes""" |
273 | mp = root.manifestProject | 275 | mp = self.parent.manifestProject |
274 | remote = root.remotes[self.remote or root.default.remote.name] | 276 | remote = self.parent.remotes[self.remote or self.parent.default.remote.name] |
275 | # If a project was given, generate the url from the remote and project. | 277 | # If a project was given, generate the url from the remote and project. |
276 | # If not, use this manifestProject's url. | 278 | # If not, use this manifestProject's url. |
277 | if self.project: | 279 | if self.project: |
@@ -348,6 +350,11 @@ class XmlManifest(object): | |||
348 | if manifest_file != os.path.abspath(manifest_file): | 350 | if manifest_file != os.path.abspath(manifest_file): |
349 | raise ManifestParseError('manifest_file must be abspath') | 351 | raise ManifestParseError('manifest_file must be abspath') |
350 | self.manifestFile = manifest_file | 352 | self.manifestFile = manifest_file |
353 | if not outer_client or outer_client == self: | ||
354 | # manifestFileOverrides only exists in the outer_client's manifest, since | ||
355 | # that is the only instance left when Unload() is called on the outer | ||
356 | # manifest. | ||
357 | self.manifestFileOverrides = {} | ||
351 | self.local_manifests = local_manifests | 358 | self.local_manifests = local_manifests |
352 | self._load_local_manifests = True | 359 | self._load_local_manifests = True |
353 | self.parent_groups = parent_groups | 360 | self.parent_groups = parent_groups |
@@ -396,14 +403,10 @@ class XmlManifest(object): | |||
396 | if not os.path.isfile(path): | 403 | if not os.path.isfile(path): |
397 | raise ManifestParseError('manifest %s not found' % name) | 404 | raise ManifestParseError('manifest %s not found' % name) |
398 | 405 | ||
399 | old = self.manifestFile | 406 | self._load_local_manifests = load_local_manifests |
400 | try: | 407 | self._outer_client.manifestFileOverrides[self.path_prefix] = path |
401 | self._load_local_manifests = load_local_manifests | 408 | self.Unload() |
402 | self.manifestFile = path | 409 | self._Load() |
403 | self.Unload() | ||
404 | self._Load() | ||
405 | finally: | ||
406 | self.manifestFile = old | ||
407 | 410 | ||
408 | def Link(self, name): | 411 | def Link(self, name): |
409 | """Update the repo metadata to use a different manifest. | 412 | """Update the repo metadata to use a different manifest. |
@@ -880,6 +883,10 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
880 | exclude = self.manifest.manifestProject.partial_clone_exclude or '' | 883 | exclude = self.manifest.manifestProject.partial_clone_exclude or '' |
881 | return set(x.strip() for x in exclude.split(',')) | 884 | return set(x.strip() for x in exclude.split(',')) |
882 | 885 | ||
886 | def SetManifestOverride(self, path): | ||
887 | """Override manifestFile. The caller must call Unload()""" | ||
888 | self._outer_client.manifest.manifestFileOverrides[self.path_prefix] = path | ||
889 | |||
883 | @property | 890 | @property |
884 | def UseLocalManifests(self): | 891 | def UseLocalManifests(self): |
885 | return self._load_local_manifests | 892 | return self._load_local_manifests |
@@ -1005,57 +1012,66 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md | |||
1005 | # This will load all clients. | 1012 | # This will load all clients. |
1006 | self._outer_client._Load(initial_client=self) | 1013 | self._outer_client._Load(initial_client=self) |
1007 | 1014 | ||
1008 | m = self.manifestProject | 1015 | savedManifestFile = self.manifestFile |
1009 | b = m.GetBranch(m.CurrentBranch).merge | 1016 | override = self._outer_client.manifestFileOverrides.get(self.path_prefix) |
1010 | if b is not None and b.startswith(R_HEADS): | 1017 | if override: |
1011 | b = b[len(R_HEADS):] | 1018 | self.manifestFile = override |
1012 | self.branch = b | ||
1013 | |||
1014 | parent_groups = self.parent_groups | ||
1015 | if self.path_prefix: | ||
1016 | parent_groups = f'{SUBMANIFEST_GROUP_PREFIX}:path:{self.path_prefix},{parent_groups}' | ||
1017 | 1019 | ||
1018 | # The manifestFile was specified by the user which is why we allow include | 1020 | try: |
1019 | # paths to point anywhere. | 1021 | m = self.manifestProject |
1020 | nodes = [] | 1022 | b = m.GetBranch(m.CurrentBranch).merge |
1021 | nodes.append(self._ParseManifestXml( | 1023 | if b is not None and b.startswith(R_HEADS): |
1022 | self.manifestFile, self.manifestProject.worktree, | 1024 | b = b[len(R_HEADS):] |
1023 | parent_groups=parent_groups, restrict_includes=False)) | 1025 | self.branch = b |
1026 | |||
1027 | parent_groups = self.parent_groups | ||
1028 | if self.path_prefix: | ||
1029 | parent_groups = f'{SUBMANIFEST_GROUP_PREFIX}:path:{self.path_prefix},{parent_groups}' | ||
1030 | |||
1031 | # The manifestFile was specified by the user which is why we allow include | ||
1032 | # paths to point anywhere. | ||
1033 | nodes = [] | ||
1034 | nodes.append(self._ParseManifestXml( | ||
1035 | self.manifestFile, self.manifestProject.worktree, | ||
1036 | parent_groups=parent_groups, restrict_includes=False)) | ||
1037 | |||
1038 | if self._load_local_manifests and self.local_manifests: | ||
1039 | try: | ||
1040 | for local_file in sorted(platform_utils.listdir(self.local_manifests)): | ||
1041 | if local_file.endswith('.xml'): | ||
1042 | local = os.path.join(self.local_manifests, local_file) | ||
1043 | # Since local manifests are entirely managed by the user, allow | ||
1044 | # them to point anywhere the user wants. | ||
1045 | local_group = f'{LOCAL_MANIFEST_GROUP_PREFIX}:{local_file[:-4]}' | ||
1046 | nodes.append(self._ParseManifestXml( | ||
1047 | local, self.subdir, | ||
1048 | parent_groups=f'{local_group},{parent_groups}', | ||
1049 | restrict_includes=False)) | ||
1050 | except OSError: | ||
1051 | pass | ||
1024 | 1052 | ||
1025 | if self._load_local_manifests and self.local_manifests: | ||
1026 | try: | 1053 | try: |
1027 | for local_file in sorted(platform_utils.listdir(self.local_manifests)): | 1054 | self._ParseManifest(nodes) |
1028 | if local_file.endswith('.xml'): | 1055 | except ManifestParseError as e: |
1029 | local = os.path.join(self.local_manifests, local_file) | 1056 | # There was a problem parsing, unload ourselves in case they catch |
1030 | # Since local manifests are entirely managed by the user, allow | 1057 | # this error and try again later, we will show the correct error |
1031 | # them to point anywhere the user wants. | 1058 | self.Unload() |
1032 | local_group = f'{LOCAL_MANIFEST_GROUP_PREFIX}:{local_file[:-4]}' | 1059 | raise e |
1033 | nodes.append(self._ParseManifestXml( | ||
1034 | local, self.subdir, | ||
1035 | parent_groups=f'{local_group},{parent_groups}', | ||
1036 | restrict_includes=False)) | ||
1037 | except OSError: | ||
1038 | pass | ||
1039 | |||
1040 | try: | ||
1041 | self._ParseManifest(nodes) | ||
1042 | except ManifestParseError as e: | ||
1043 | # There was a problem parsing, unload ourselves in case they catch | ||
1044 | # this error and try again later, we will show the correct error | ||
1045 | self.Unload() | ||
1046 | raise e | ||
1047 | 1060 | ||
1048 | if self.IsMirror: | 1061 | if self.IsMirror: |
1049 | self._AddMetaProjectMirror(self.repoProject) | 1062 | self._AddMetaProjectMirror(self.repoProject) |
1050 | self._AddMetaProjectMirror(self.manifestProject) | 1063 | self._AddMetaProjectMirror(self.manifestProject) |
1051 | 1064 | ||
1052 | self._loaded = True | 1065 | self._loaded = True |
1066 | finally: | ||
1067 | if override: | ||
1068 | self.manifestFile = savedManifestFile | ||
1053 | 1069 | ||
1054 | # Now that we have loaded this manifest, load any submanifest manifests | 1070 | # Now that we have loaded this manifest, load any submanifest manifests |
1055 | # as well. We need to do this after self._loaded is set to avoid looping. | 1071 | # as well. We need to do this after self._loaded is set to avoid looping. |
1056 | for name in self._submanifests: | 1072 | for name in self._submanifests: |
1057 | tree = self._submanifests[name] | 1073 | tree = self._submanifests[name] |
1058 | spec = tree.ToSubmanifestSpec(self) | 1074 | spec = tree.ToSubmanifestSpec() |
1059 | present = os.path.exists(os.path.join(self.subdir, MANIFEST_FILE_NAME)) | 1075 | present = os.path.exists(os.path.join(self.subdir, MANIFEST_FILE_NAME)) |
1060 | if present and tree.present and not tree.repo_client: | 1076 | if present and tree.present and not tree.repo_client: |
1061 | if initial_client and initial_client.topdir == self.topdir: | 1077 | if initial_client and initial_client.topdir == self.topdir: |