diff options
Diffstat (limited to 'src/mlia/utils')
-rw-r--r-- | src/mlia/utils/proc.py | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/mlia/utils/proc.py b/src/mlia/utils/proc.py new file mode 100644 index 0000000..d11bfc5 --- /dev/null +++ b/src/mlia/utils/proc.py @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: Copyright 2023, Arm Limited and/or its affiliates. +# SPDX-License-Identifier: Apache-2.0 +"""Module for process management.""" +from __future__ import annotations + +import logging +import subprocess # nosec +from dataclasses import dataclass +from pathlib import Path +from typing import Callable +from typing import Generator + + +logger = logging.getLogger(__name__) + + +@dataclass(frozen=True) +class Command: + """Command information.""" + + cmd: list[str] + cwd: Path = Path.cwd() + env: dict[str, str] | None = None + + +def command_output(command: Command) -> Generator[str, None, None]: + """Get command output.""" + logger.debug("Running command: %s", command) + + with subprocess.Popen( # nosec + command.cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True, + bufsize=1, + cwd=command.cwd, + env=command.env, + ) as process: + yield from process.stdout or [] + + if process.returncode: + raise subprocess.CalledProcessError(process.returncode, command.cmd) + + +OutputConsumer = Callable[[str], None] + + +def process_command_output( + command: Command, + consumers: list[OutputConsumer], +) -> None: + """Execute command and process output.""" + for line in command_output(command): + for consumer in consumers: + consumer(line) |