Ejemplo n.º 1
0
 def run_command(
     cls,
     cmd: Union[List[str], CommandArgs],
     show_stdout: bool = True,
     cwd: Optional[str] = None,
     on_returncode: 'Literal["raise", "warn", "ignore"]' = "raise",
     extra_ok_returncodes: Optional[Iterable[int]] = None,
     command_desc: Optional[str] = None,
     extra_environ: Optional[Mapping[str, Any]] = None,
     spinner: Optional[SpinnerInterface] = None,
     log_failed_cmd: bool = True,
     stdout_only: bool = False,
 ) -> str:
     """
     Run a VCS subcommand
     This is simply a wrapper around call_subprocess that adds the VCS
     command name, and checks that the VCS is available
     """
     cmd = make_command(cls.name, *cmd)
     if command_desc is None:
         command_desc = format_command_args(cmd)
     try:
         return call_subprocess(
             cmd,
             show_stdout,
             cwd,
             on_returncode=on_returncode,
             extra_ok_returncodes=extra_ok_returncodes,
             command_desc=command_desc,
             extra_environ=extra_environ,
             unset_environ=cls.unset_environ,
             spinner=spinner,
             log_failed_cmd=log_failed_cmd,
             stdout_only=stdout_only,
         )
     except FileNotFoundError:
         # errno.ENOENT = no such file or directory
         # In other words, the VCS executable isn't available
         raise BadCommand(f"Cannot find command {cls.name!r} - do you have "
                          f"{cls.name!r} installed and in your PATH?")
     except PermissionError:
         # errno.EACCES = Permission denied
         # This error occurs, for instance, when the command is installed
         # only for another user. So, the current user don't have
         # permission to call the other user command.
         raise BadCommand(
             f"No permission to execute {cls.name!r} - install it "
             f"locally, globally (ask admin), or check your PATH. "
             f"See possible solutions at "
             f"https://pip.pypa.io/en/latest/reference/pip_freeze/"
             f"#fixing-permission-denied.")
Ejemplo n.º 2
0
def format_command_result(
    command_args: List[str],
    command_output: str,
) -> str:
    """Format command information for logging."""
    command_desc = format_command_args(command_args)
    text = f"Command arguments: {command_desc}\n"

    if not command_output:
        text += "Command output: None"
    elif logger.getEffectiveLevel() > logging.DEBUG:
        text += "Command output: [use --verbose to show]"
    else:
        if not command_output.endswith("\n"):
            command_output += "\n"
        text += f"Command output:\n{command_output}"

    return text
Ejemplo n.º 3
0
def format_command_result(
    command_args: List[str],
    command_output: str,
) -> str:
    """Format command information for logging."""
    command_desc = format_command_args(command_args)
    text = f'Command arguments: {command_desc}\n'

    if not command_output:
        text += 'Command output: None'
    elif logger.getEffectiveLevel() > logging.DEBUG:
        text += 'Command output: [use --verbose to show]'
    else:
        if not command_output.endswith('\n'):
            command_output += '\n'
        text += f'Command output:\n{command_output}{LOG_DIVIDER}'

    return text
Ejemplo n.º 4
0
def format_command_result(
    command_args,  # type: List[str]
    command_output,  # type: str
):
    # type: (...) -> str
    """Format command information for logging."""
    command_desc = format_command_args(command_args)
    text = 'Command arguments: {}\n'.format(command_desc)

    if not command_output:
        text += 'Command output: None'
    elif logger.getEffectiveLevel() > logging.DEBUG:
        text += 'Command output: [use --verbose to show]'
    else:
        if not command_output.endswith('\n'):
            command_output += '\n'
        text += 'Command output:\n{}{}'.format(command_output, LOG_DIVIDER)

    return text
def call_subprocess(
    cmd,  # type: Union[List[str], CommandArgs]
    cwd=None,  # type: Optional[str]
    extra_environ=None,  # type: Optional[Mapping[str, Any]]
    extra_ok_returncodes=None,  # type: Optional[Iterable[int]]
    log_failed_cmd=True,  # type: Optional[bool]
):
    # type: (...) -> Text
    """
    Args:
      extra_ok_returncodes: an iterable of integer return codes that are
        acceptable, in addition to 0. Defaults to None, which means [].
      log_failed_cmd: if false, failed commands are not logged,
        only raised.
    """
    if extra_ok_returncodes is None:
        extra_ok_returncodes = []

    # log the subprocess output at DEBUG level.
    log_subprocess = subprocess_logger.debug

    env = os.environ.copy()
    if extra_environ:
        env.update(extra_environ)

    # Whether the subprocess will be visible in the console.
    showing_subprocess = True

    command_desc = format_command_args(cmd)
    try:
        proc = subprocess.Popen(
            # Convert HiddenText objects to the underlying str.
            reveal_command_args(cmd),
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=cwd,
        )
        if proc.stdin:
            proc.stdin.close()
    except Exception as exc:
        if log_failed_cmd:
            subprocess_logger.critical(
                "Error %s while executing command %s",
                exc,
                command_desc,
            )
        raise
    all_output = []
    while True:
        # The "line" value is a unicode string in Python 2.
        line = None
        if proc.stdout:
            line = console_to_str(proc.stdout.readline())
        if not line:
            break
        line = line.rstrip()
        all_output.append(line + "\n")

        # Show the line immediately.
        log_subprocess(line)
    try:
        proc.wait()
    finally:
        if proc.stdout:
            proc.stdout.close()

    proc_had_error = proc.returncode and proc.returncode not in extra_ok_returncodes
    if proc_had_error:
        if not showing_subprocess and log_failed_cmd:
            # Then the subprocess streams haven't been logged to the
            # console yet.
            msg = make_subprocess_output_error(
                cmd_args=cmd,
                cwd=cwd,
                lines=all_output,
                exit_status=proc.returncode,
            )
            subprocess_logger.error(msg)
        exc_msg = (
            "Command errored out with exit status {}: {} "
            "Check the logs for full command output."
        ).format(proc.returncode, command_desc)
        raise SubProcessError(exc_msg)
    return "".join(all_output)
Ejemplo n.º 6
0
def test_format_command_args(args, expected):
    actual = format_command_args(args)
    assert actual == expected
Ejemplo n.º 7
0
def test_format_command_args(args: CommandArgs, expected: str) -> None:
    actual = format_command_args(args)
    assert actual == expected
        only raised.
    """
    if extra_ok_returncodes is None:
        extra_ok_returncodes = []

    # log the subprocess output at DEBUG level.
    log_subprocess = subprocess_logger.debug

    env = os.environ.copy()
    if extra_environ:
        env.update(extra_environ)

    # Whether the subprocess will be visible in the console.
    showing_subprocess = True

    command_desc = format_command_args(cmd)
    try:
        proc = subprocess.Popen(
            # Convert HiddenText objects to the underlying str.
            reveal_command_args(cmd),
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=cwd
        )
        if proc.stdin:
            proc.stdin.close()
    except Exception as exc:
        if log_failed_cmd:
            subprocess_logger.critical(
                "Error %s while executing command %s", exc, command_desc,
            )