From 7a04b757321f6201c870cc63770363ff54fd47c2 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Fri, 2 Jun 2023 16:39:52 +0200 Subject: [PATCH] commands: Show less generic error when no manifest is loaded If loading the manifest fails, running a command which needs to read the manifest could result in this being shown: FATAL ERROR: can't run west manifest; it requires the manifest, which was not available. Try "west manifest --validate" to debug. In this case, trying "west manifest --validate" would also display the same error, which is not very helpful. Instead of that, west can print the deferred error from load_manifest(), which contains a more specific message. Rework the WestCommand.manifest property handling by adding a dummy _ManifestRequired exception. It is caught by run_builtin() in main.py, which can access the stored error. Signed-off-by: Grzegorz Swiderski --- src/west/app/main.py | 19 ++++++++++++++----- src/west/commands.py | 6 ++---- src/west/manifest.py | 4 ++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/west/app/main.py b/src/west/app/main.py index 69b457a4..866f5de8 100755 --- a/src/west/app/main.py +++ b/src/west/app/main.py @@ -37,8 +37,8 @@ SelfUpdate, ForAll, Init, Update, Topdir from west.app.config import Config from west.manifest import Manifest, MalformedConfig, MalformedManifest, \ - ManifestVersionError, ManifestImportFailed, _ManifestImportDepth, \ - ManifestProject, MANIFEST_REV_BRANCH + _ManifestRequired, ManifestVersionError, ManifestImportFailed, \ + _ManifestImportDepth, ManifestProject, MANIFEST_REV_BRANCH from west.util import quote_sh_list, west_topdir, WestNotFound from west.version import __version__ @@ -608,9 +608,18 @@ def run_builtin(self, args, unknown): self.handle_builtin_manifest_load_err(args) for io_hook in self.queued_io: self.cmd.add_pre_run_hook(io_hook) - self.cmd.run(args, unknown, self.topdir, - manifest=self.manifest, - config=self.config) + try: + self.cmd.run(args, unknown, self.topdir, + manifest=self.manifest, + config=self.config) + except _ManifestRequired: + # We tried to run the command despite having failed to + # load_manifest(), but the manifest was needed after all. + # Show the deferred exception and exit. + if self.mle.args: + self.cmd.die('\n '.join(str(arg) for arg in self.mle.args)) + else: + self.cmd.die(str(self.mle)) def run_extension(self, name, argv): # Check a program invariant. We should never get here diff --git a/src/west/commands.py b/src/west/commands.py index c77a0dfd..73ab5dd3 100644 --- a/src/west/commands.py +++ b/src/west/commands.py @@ -25,7 +25,7 @@ import yaml from west.configuration import Configuration -from west.manifest import Manifest, Project +from west.manifest import Manifest, _ManifestRequired, Project from west.util import escapes_directory, quote_sh_list, PathType '''\ @@ -258,9 +258,7 @@ def _get_manifest(self) -> Manifest: Otherwise, a fatal error occurs. ''' if self._manifest is None: - self.die(f"can't run west {self.name};", - "it requires the manifest, which was not available.", - 'Try "west manifest --validate" to debug.') + raise _ManifestRequired return self._manifest def _set_manifest(self, manifest: Optional[Manifest]): diff --git a/src/west/manifest.py b/src/west/manifest.py index c2bb85bc..2326d0b0 100644 --- a/src/west/manifest.py +++ b/src/west/manifest.py @@ -685,6 +685,10 @@ class _ManifestImportDepth(ManifestImportFailed): # A hack to signal to main.py what happened. pass +class _ManifestRequired(Exception): + # A built-in command had to read the manifest but it wasn't loaded. + pass + # # The main Manifest class and its public helper types, like Project # and ImportFlag.