def test_printable_command_with_string(cmd): """ Correctly transform a string into a runnable shell command. Arguments: cmd: The command as a string. """ assert printable_command(cmd) == cmd
def test_printable_command_with_list(cmd, expected) -> None: """ Correctly transform a list of arguments into a runnable shell command. Arguments: cmd: The command as a list of arguments. expected: The expected result after transformation. """ assert printable_command(cmd) == expected
def test_printable_command_with_callable(cmd, args, kwargs, expected): """ Correctly transform a callable into a runnable shell command. Arguments: cmd: The command as a string. args: Arguments passed to `printable_command`. kwargs: Keyword arguments passed to `printable_command`. expected: The expected result after transformation. """ assert printable_command(cmd, args, kwargs) == expected
def run_subprocess( cmd: CmdType, capture: Capture = Capture.BOTH, shell: bool = False, stdin: Optional[str] = None, ) -> Tuple[int, str]: """ Run a command in a subprocess. Arguments: cmd: The command to run. capture: The output to capture. shell: Whether to run the command in a shell. stdin: String to use as standard input. Returns: The exit code and the command raw output. """ if capture == Capture.NONE: stdout_opt = None stderr_opt = None else: stdout_opt = subprocess.PIPE if capture == Capture.BOTH: stderr_opt = subprocess.STDOUT else: stderr_opt = subprocess.PIPE if shell and not isinstance(cmd, str): cmd = printable_command(cmd) process = subprocess.run( # noqa: S603,W1510 (we trust the input, and don't want to "check") cmd, input=stdin, stdout=stdout_opt, stderr=stderr_opt, shell=shell, # noqa: S602 (shell=True) universal_newlines=True, encoding="utf8", ) if capture == Capture.NONE: output = "" elif capture == Capture.STDERR: output = process.stderr else: output = process.stdout return process.returncode, output
def run( # noqa: WPS231 (high complexity) cmd: CmdFuncType, args=None, kwargs=None, number: int = 1, capture: Optional[Union[str, bool, Capture]] = None, title: Optional[str] = None, fmt: Optional[str] = None, pty: bool = False, progress: bool = True, nofail: bool = False, quiet: bool = False, silent: bool = False, stdin: Optional[str] = None, ) -> RunResult: """ Run a command in a subprocess or a Python function, and print its output if it fails. Arguments: cmd: The command to run. args: Arguments to pass to the callable. kwargs: Keyword arguments to pass to the callable. number: The command number. capture: The output to capture. title: The command title. fmt: The output format. pty: Whether to run in a PTY. progress: Whether to show progress. nofail: Whether to always succeed. quiet: Whether to not print the command output. silent: Don't print anything. stdin: String to use as standard input. Returns: The command exit code, or 0 if `nofail` is True. """ format_name: str = fmt or os.environ.get("FAILPRINT_FORMAT", DEFAULT_FORMAT) # type: ignore format_name = accept_custom_format(format_name) format_obj = formats.get(format_name, formats[DEFAULT_FORMAT]) env = Environment(autoescape=False) # noqa: S701 (no HTML: no need to escape) env.filters["indent"] = textwrap.indent command = printable_command(cmd, args, kwargs) if not silent and progress and format_obj.progress_template: progress_template = env.from_string(format_obj.progress_template) ansiprint(progress_template.render({"title": title, "command": command}), end="\r") capture = cast_capture(capture) if callable(cmd): code, output = run_function(cmd, args, kwargs, capture, stdin) else: code, output = run_command(cmd, capture, format_obj.accept_ansi, pty, stdin) if not silent: template = env.from_string(format_obj.template) ansiprint( template.render( { "title": title, "command": command, "code": code, "success": code == 0, "failure": code != 0, "number": number, "output": output, "nofail": nofail, "quiet": quiet, "silent": silent, }, ), ) return RunResult(0 if nofail else code, output)