-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathshell_commands.py
More file actions
72 lines (57 loc) · 2.19 KB
/
shell_commands.py
File metadata and controls
72 lines (57 loc) · 2.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from __future__ import annotations
import subprocess
import sys
from collections.abc import Iterable
from logging import getLogger
from pathlib import Path
from typing import Any, Union
# For Python versions that don't have typing.Unpack yet (pre-3.13),
# we import from typing_extensions instead
if sys.version_info < (3, 13):
from typing_extensions import Unpack # noqa: F401
logger = getLogger(__name__)
# Define type for shell commands, using Iterable for improved compatibility
ShellCommand = Iterable[Union[str, Path]]
def run_shell_command(
cmd: ShellCommand,
*,
quiet: bool,
check: bool = True,
**kwargs: Any, # noqa: ANN401
) -> subprocess.CompletedProcess:
"""Runs a shell command using the arguments provided.
This is essentially a wrapper around subprocess.run, with more reasonable
default arguments, and some debug logging.
Args:
cmd: shell command to run.
check: see subprocess.run for semantics.
**kwargs: see subprocess.run for semantics
(https://docs.python.org/3/library/subprocess.html#subprocess.run).
Returns:
A subprocess.CompletedProcess object.
"""
if "shell" in kwargs:
raise ValueError("shell support has been removed")
_ = subprocess.list2cmdline(cmd)
if quiet:
kwargs.update({"stdout": subprocess.DEVNULL, "stderr": subprocess.DEVNULL})
logger.debug("Running: %s", cmd)
return subprocess.run(list(map(str, cmd)), **kwargs, check=check)
def get_command_output(
cmd: ShellCommand,
**kwargs: Any, # noqa: ANN401
) -> str:
"""A wrapper over run_shell_command that captures stdout into a string.
Args:
cmd: shell command to run.
**kwargs: see run_shell_command for semantics. Passing capture_output is
not allowed.
Returns:
Captured stdout of the command as a string.
Raises:
ValueError: if the capture_output keyword argument is specified.
"""
if "capture_output" in kwargs:
raise ValueError("Cannot pass capture_output when using get_command_output")
proc = run_shell_command(cmd, capture_output=True, quiet=False, **kwargs)
return str(proc.stdout.decode("utf-8").rstrip())