Run subprocess and retry using fallback command if initial command fails. Args: args: A string, or a sequence of program arguments. show_status_message: The status message to be displayed in the console. fallbacks: The fallback command to run if the initial command fails
(
args: list[str],
*,
show_status_message: str,
fallbacks: str | Sequence[str] | Sequence[Sequence[str]] | None = None,
analytics_enabled: bool = False,
prior_logs: tuple[tuple[str, ...], ...] = (),
**kwargs,
)
| 484 | |
| 485 | |
| 486 | def run_process_with_fallbacks( |
| 487 | args: list[str], |
| 488 | *, |
| 489 | show_status_message: str, |
| 490 | fallbacks: str | Sequence[str] | Sequence[Sequence[str]] | None = None, |
| 491 | analytics_enabled: bool = False, |
| 492 | prior_logs: tuple[tuple[str, ...], ...] = (), |
| 493 | **kwargs, |
| 494 | ): |
| 495 | """Run subprocess and retry using fallback command if initial command fails. |
| 496 | |
| 497 | Args: |
| 498 | args: A string, or a sequence of program arguments. |
| 499 | show_status_message: The status message to be displayed in the console. |
| 500 | fallbacks: The fallback command to run if the initial command fails. |
| 501 | analytics_enabled: Whether analytics are enabled for this command. |
| 502 | prior_logs: The logs of the prior processes that have been run. |
| 503 | **kwargs: Kwargs to pass to new_process function. |
| 504 | """ |
| 505 | process = new_process(get_command_with_loglevel(args), **kwargs) |
| 506 | if not fallbacks: |
| 507 | # No fallback given, or this _is_ the fallback command. |
| 508 | show_status( |
| 509 | show_status_message, |
| 510 | process, |
| 511 | analytics_enabled=analytics_enabled, |
| 512 | prior_logs=prior_logs, |
| 513 | ) |
| 514 | else: |
| 515 | # Suppress errors for initial command, because we will try to fallback |
| 516 | logs = show_status(show_status_message, process, suppress_errors=True) |
| 517 | |
| 518 | current_fallback = fallbacks[0] if not isinstance(fallbacks, str) else fallbacks |
| 519 | next_fallbacks = fallbacks[1:] if not isinstance(fallbacks, str) else None |
| 520 | |
| 521 | if process.returncode != 0: |
| 522 | # retry with fallback command. |
| 523 | fallback_with_args = ( |
| 524 | [current_fallback, *args[1:]] |
| 525 | if isinstance(current_fallback, str) |
| 526 | else [*current_fallback, *args[1:]] |
| 527 | ) |
| 528 | console.warn( |
| 529 | f"There was an error running command: {args}. Falling back to: {fallback_with_args}." |
| 530 | ) |
| 531 | run_process_with_fallbacks( |
| 532 | fallback_with_args, |
| 533 | show_status_message=show_status_message, |
| 534 | fallbacks=next_fallbacks, |
| 535 | analytics_enabled=analytics_enabled, |
| 536 | prior_logs=(*prior_logs, tuple(logs)), |
| 537 | **kwargs, |
| 538 | ) |
| 539 | |
| 540 | |
| 541 | def execute_command_and_return_output(command: str) -> str | None: |
nothing calls this directly
no test coverage detected