From f9aacd4087b02948da9a7878da48ea186ab99d5a Mon Sep 17 00:00:00 2001 From: Jason Chang Date: Thu, 3 Aug 2023 14:38:00 -0700 Subject: Raise repo exit errors in place of sys.exit Bug: b/293344017 Change-Id: I92d81c78eba8ff31b5252415f4c9a515a6c76411 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/381774 Tested-by: Jason Chang Reviewed-by: Joanna Wang Commit-Queue: Jason Chang --- subcmds/abandon.py | 24 +++++++++++++++++++----- subcmds/init.py | 12 +++++++++--- subcmds/upload.py | 10 +++++++--- 3 files changed, 35 insertions(+), 11 deletions(-) (limited to 'subcmds') diff --git a/subcmds/abandon.py b/subcmds/abandon.py index ded287f6..896b348f 100644 --- a/subcmds/abandon.py +++ b/subcmds/abandon.py @@ -20,6 +20,11 @@ import sys from command import Command, DEFAULT_LOCAL_JOBS from git_command import git from progress import Progress +from error import RepoError, RepoExitError + + +class AbandonError(RepoExitError): + """Exit error when abandon command fails.""" class Abandon(Command): @@ -68,28 +73,37 @@ It is equivalent to "git branch -D ". branches = nb ret = {} + errors = [] for name in branches: - status = project.AbandonBranch(name) + status = None + try: + status = project.AbandonBranch(name) + except RepoError as e: + status = False + errors.append(e) if status is not None: ret[name] = status - return (ret, project) + + return (ret, project, errors) def Execute(self, opt, args): nb = args[0].split() err = defaultdict(list) success = defaultdict(list) + aggregate_errors = [] all_projects = self.GetProjects( args[1:], all_manifests=not opt.this_manifest_only ) _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only) def _ProcessResults(_pool, pm, states): - for results, project in states: + for results, project, errors in states: for branch, status in results.items(): if status: success[branch].append(project) else: err[branch].append(project) + aggregate_errors.extend(errors) pm.update(msg="") self.ExecuteInParallel( @@ -116,13 +130,13 @@ It is equivalent to "git branch -D ". " " * len(err_msg) + " | %s" % _RelPath(proj), file=sys.stderr, ) - sys.exit(1) + raise AbandonError(aggregate_errors=aggregate_errors) elif not success: print( "error: no project has local branch(es) : %s" % nb, file=sys.stderr, ) - sys.exit(1) + raise AbandonError(aggregate_errors=aggregate_errors) else: # Everything below here is displaying status. if opt.quiet: diff --git a/subcmds/init.py b/subcmds/init.py index 6d7fd857..868d339e 100644 --- a/subcmds/init.py +++ b/subcmds/init.py @@ -19,6 +19,8 @@ from color import Coloring from command import InteractiveCommand, MirrorSafeCommand from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD from wrapper import Wrapper +from error import UpdateManifestError +from error import RepoUnhandledExceptionError _REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW") @@ -156,7 +158,10 @@ to update the working directory files. git_event_log=self.git_event_log, manifest_name=opt.manifest_name, ): - sys.exit(1) + manifest_name = opt.manifest_name + raise UpdateManifestError( + f"Unable to sync manifest {manifest_name}" + ) def _Prompt(self, prompt, value): print("%-10s [%s]: " % (prompt, value), end="", flush=True) @@ -346,14 +351,15 @@ to update the working directory files. repo_verify=opt.repo_verify, quiet=opt.quiet, ) - except wrapper.CloneFailure: + except wrapper.CloneFailure as e: err_msg = "fatal: double check your --repo-rev setting." print( err_msg, file=sys.stderr, ) self.git_event_log.ErrorEvent(err_msg) - sys.exit(1) + raise RepoUnhandledExceptionError(e) + branch = rp.GetBranch("default") branch.merge = remote_ref rp.work_git.reset("--hard", rev) diff --git a/subcmds/upload.py b/subcmds/upload.py index 8d949bef..d0c028b9 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py @@ -21,7 +21,7 @@ from typing import List from command import DEFAULT_LOCAL_JOBS, InteractiveCommand from editor import Editor -from error import UploadError +from error import UploadError, RepoExitError from git_command import GitCommand from git_refs import R_HEADS from hooks import RepoHook @@ -31,6 +31,10 @@ from project import ReviewableBranch _DEFAULT_UNUSUAL_COMMIT_THRESHOLD = 5 +class UploadExitError(RepoExitError): + """Indicates that there is an upload command error requiring a sys exit.""" + + def _VerifyPendingCommits(branches: List[ReviewableBranch]) -> bool: """Perform basic safety checks on the given set of branches. @@ -86,7 +90,7 @@ def _VerifyPendingCommits(branches: List[ReviewableBranch]) -> bool: def _die(fmt, *args): msg = fmt % args print("error: %s" % msg, file=sys.stderr) - sys.exit(1) + raise UploadExitError(msg) def _SplitEmails(values): @@ -697,7 +701,7 @@ Gerrit Code Review: https://www.gerritcodereview.com/ ) if have_errors: - sys.exit(1) + raise branch.error def _GetMergeBranch(self, project, local_branch=None): if local_branch is None: -- cgit v1.2.3-54-g00ecf