diff options
author | Jason Chang <jasonnc@google.com> | 2023-08-08 14:12:53 -0700 |
---|---|---|
committer | LUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-08-10 23:46:31 +0000 |
commit | 1a3612fe6d347e458a53d7a9e920a91ea502e6ba (patch) | |
tree | 02b1a61f1d97e32201ea5fa309bf1f1b6050e929 /subcmds/grep.py | |
parent | f0aeb220def22edfac9838288ad251f86da782c1 (diff) | |
download | git-repo-1a3612fe6d347e458a53d7a9e920a91ea502e6ba.tar.gz |
Raise RepoExitError in place of sys.exit
Bug: b/293344017
Change-Id: Icae4932b00e4068cba502a5ab4a0274fd7854d9d
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/382214
Reviewed-by: Gavin Mak <gavinmak@google.com>
Tested-by: Jason Chang <jasonnc@google.com>
Reviewed-by: Aravind Vasudevan <aravindvasudev@google.com>
Commit-Queue: Jason Chang <jasonnc@google.com>
Diffstat (limited to 'subcmds/grep.py')
-rw-r--r-- | subcmds/grep.py | 84 |
1 files changed, 58 insertions, 26 deletions
diff --git a/subcmds/grep.py b/subcmds/grep.py index 5cd33763..9ebd776c 100644 --- a/subcmds/grep.py +++ b/subcmds/grep.py | |||
@@ -17,8 +17,10 @@ import sys | |||
17 | 17 | ||
18 | from color import Coloring | 18 | from color import Coloring |
19 | from command import DEFAULT_LOCAL_JOBS, PagedCommand | 19 | from command import DEFAULT_LOCAL_JOBS, PagedCommand |
20 | from error import GitError | 20 | from error import GitError, InvalidArgumentsError, SilentRepoExitError |
21 | from git_command import GitCommand | 21 | from git_command import GitCommand |
22 | from typing import NamedTuple | ||
23 | from project import Project | ||
22 | 24 | ||
23 | 25 | ||
24 | class GrepColoring(Coloring): | 26 | class GrepColoring(Coloring): |
@@ -28,6 +30,22 @@ class GrepColoring(Coloring): | |||
28 | self.fail = self.printer("fail", fg="red") | 30 | self.fail = self.printer("fail", fg="red") |
29 | 31 | ||
30 | 32 | ||
33 | class ExecuteOneResult(NamedTuple): | ||
34 | """Result from an execute instance.""" | ||
35 | |||
36 | project: Project | ||
37 | rc: int | ||
38 | stdout: str | ||
39 | stderr: str | ||
40 | error: GitError | ||
41 | |||
42 | |||
43 | class GrepCommandError(SilentRepoExitError): | ||
44 | """Grep command failure. Since Grep command | ||
45 | output already outputs errors ensure that | ||
46 | aggregate errors exit silently.""" | ||
47 | |||
48 | |||
31 | class Grep(PagedCommand): | 49 | class Grep(PagedCommand): |
32 | COMMON = True | 50 | COMMON = True |
33 | helpSummary = "Print lines matching a pattern" | 51 | helpSummary = "Print lines matching a pattern" |
@@ -246,11 +264,18 @@ contain a line that matches both expressions: | |||
246 | bare=False, | 264 | bare=False, |
247 | capture_stdout=True, | 265 | capture_stdout=True, |
248 | capture_stderr=True, | 266 | capture_stderr=True, |
267 | verify_command=True, | ||
249 | ) | 268 | ) |
250 | except GitError as e: | 269 | except GitError as e: |
251 | return (project, -1, None, str(e)) | 270 | return ExecuteOneResult(project, -1, None, str(e), e) |
252 | 271 | ||
253 | return (project, p.Wait(), p.stdout, p.stderr) | 272 | try: |
273 | error = None | ||
274 | rc = p.Wait() | ||
275 | except GitError as e: | ||
276 | rc = 1 | ||
277 | error = e | ||
278 | return ExecuteOneResult(project, rc, p.stdout, p.stderr, error) | ||
254 | 279 | ||
255 | @staticmethod | 280 | @staticmethod |
256 | def _ProcessResults(full_name, have_rev, opt, _pool, out, results): | 281 | def _ProcessResults(full_name, have_rev, opt, _pool, out, results): |
@@ -258,31 +283,40 @@ contain a line that matches both expressions: | |||
258 | bad_rev = False | 283 | bad_rev = False |
259 | have_match = False | 284 | have_match = False |
260 | _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only) | 285 | _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only) |
286 | errors = [] | ||
261 | 287 | ||
262 | for project, rc, stdout, stderr in results: | 288 | for result in results: |
263 | if rc < 0: | 289 | if result.rc < 0: |
264 | git_failed = True | 290 | git_failed = True |
265 | out.project("--- project %s ---" % _RelPath(project)) | 291 | out.project("--- project %s ---" % _RelPath(result.project)) |
266 | out.nl() | 292 | out.nl() |
267 | out.fail("%s", stderr) | 293 | out.fail("%s", result.stderr) |
268 | out.nl() | 294 | out.nl() |
295 | errors.append(result.error) | ||
269 | continue | 296 | continue |
270 | 297 | ||
271 | if rc: | 298 | if result.rc: |
272 | # no results | 299 | # no results |
273 | if stderr: | 300 | if result.stderr: |
274 | if have_rev and "fatal: ambiguous argument" in stderr: | 301 | if ( |
302 | have_rev | ||
303 | and "fatal: ambiguous argument" in result.stderr | ||
304 | ): | ||
275 | bad_rev = True | 305 | bad_rev = True |
276 | else: | 306 | else: |
277 | out.project("--- project %s ---" % _RelPath(project)) | 307 | out.project( |
308 | "--- project %s ---" % _RelPath(result.project) | ||
309 | ) | ||
278 | out.nl() | 310 | out.nl() |
279 | out.fail("%s", stderr.strip()) | 311 | out.fail("%s", result.stderr.strip()) |
280 | out.nl() | 312 | out.nl() |
313 | if result.error is not None: | ||
314 | errors.append(result.error) | ||
281 | continue | 315 | continue |
282 | have_match = True | 316 | have_match = True |
283 | 317 | ||
284 | # We cut the last element, to avoid a blank line. | 318 | # We cut the last element, to avoid a blank line. |
285 | r = stdout.split("\n") | 319 | r = result.stdout.split("\n") |
286 | r = r[0:-1] | 320 | r = r[0:-1] |
287 | 321 | ||
288 | if have_rev and full_name: | 322 | if have_rev and full_name: |
@@ -290,13 +324,13 @@ contain a line that matches both expressions: | |||
290 | rev, line = line.split(":", 1) | 324 | rev, line = line.split(":", 1) |
291 | out.write("%s", rev) | 325 | out.write("%s", rev) |
292 | out.write(":") | 326 | out.write(":") |
293 | out.project(_RelPath(project)) | 327 | out.project(_RelPath(result.project)) |
294 | out.write("/") | 328 | out.write("/") |
295 | out.write("%s", line) | 329 | out.write("%s", line) |
296 | out.nl() | 330 | out.nl() |
297 | elif full_name: | 331 | elif full_name: |
298 | for line in r: | 332 | for line in r: |
299 | out.project(_RelPath(project)) | 333 | out.project(_RelPath(result.project)) |
300 | out.write("/") | 334 | out.write("/") |
301 | out.write("%s", line) | 335 | out.write("%s", line) |
302 | out.nl() | 336 | out.nl() |
@@ -304,7 +338,7 @@ contain a line that matches both expressions: | |||
304 | for line in r: | 338 | for line in r: |
305 | print(line) | 339 | print(line) |
306 | 340 | ||
307 | return (git_failed, bad_rev, have_match) | 341 | return (git_failed, bad_rev, have_match, errors) |
308 | 342 | ||
309 | def Execute(self, opt, args): | 343 | def Execute(self, opt, args): |
310 | out = GrepColoring(self.manifest.manifestProject.config) | 344 | out = GrepColoring(self.manifest.manifestProject.config) |
@@ -333,16 +367,14 @@ contain a line that matches both expressions: | |||
333 | have_rev = False | 367 | have_rev = False |
334 | if opt.revision: | 368 | if opt.revision: |
335 | if "--cached" in cmd_argv: | 369 | if "--cached" in cmd_argv: |
336 | print( | 370 | msg = "fatal: cannot combine --cached and --revision" |
337 | "fatal: cannot combine --cached and --revision", | 371 | print(msg, file=sys.stderr) |
338 | file=sys.stderr, | 372 | raise InvalidArgumentsError(msg) |
339 | ) | ||
340 | sys.exit(1) | ||
341 | have_rev = True | 373 | have_rev = True |
342 | cmd_argv.extend(opt.revision) | 374 | cmd_argv.extend(opt.revision) |
343 | cmd_argv.append("--") | 375 | cmd_argv.append("--") |
344 | 376 | ||
345 | git_failed, bad_rev, have_match = self.ExecuteInParallel( | 377 | git_failed, bad_rev, have_match, errors = self.ExecuteInParallel( |
346 | opt.jobs, | 378 | opt.jobs, |
347 | functools.partial(self._ExecuteOne, cmd_argv), | 379 | functools.partial(self._ExecuteOne, cmd_argv), |
348 | projects, | 380 | projects, |
@@ -354,12 +386,12 @@ contain a line that matches both expressions: | |||
354 | ) | 386 | ) |
355 | 387 | ||
356 | if git_failed: | 388 | if git_failed: |
357 | sys.exit(1) | 389 | raise GrepCommandError( |
390 | "error: git failures", aggregate_errors=errors | ||
391 | ) | ||
358 | elif have_match: | 392 | elif have_match: |
359 | sys.exit(0) | 393 | sys.exit(0) |
360 | elif have_rev and bad_rev: | 394 | elif have_rev and bad_rev: |
361 | for r in opt.revision: | 395 | for r in opt.revision: |
362 | print("error: can't search revision %s" % r, file=sys.stderr) | 396 | print("error: can't search revision %s" % r, file=sys.stderr) |
363 | sys.exit(1) | 397 | raise GrepCommandError(aggregate_errors=errors) |
364 | else: | ||
365 | sys.exit(1) | ||