From 290ab8c760ec4f01e7b309d1bb4712c2588fde0e Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Wed, 16 Sep 2020 16:47:23 -0400 Subject: [PATCH] Refactor run_logged_subprocess to return a dict with returncode and output --- utils/venv-manager.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/utils/venv-manager.py b/utils/venv-manager.py index ec2f452..fbf01e6 100644 --- a/utils/venv-manager.py +++ b/utils/venv-manager.py @@ -13,6 +13,7 @@ from pathlib import Path import os, logging, argparse, subprocess +from typing import Union ################################################################################ @@ -67,8 +68,8 @@ def get_args() -> argparse.Namespace: ) return parser.parse_args() -command = f"cd {API_DIR} && python3 -m venv {VENV_NAME}" -def run_logged_shell_subprocess(command: str, timeout: int = 10) -> int: + +def run_logged_subprocess(command: Union[str, list], timeout: int = 10, shell: bool = False) -> list: """Executes a shell command using subprocess with logging. stderr is redirected to stdout and stdout is pipped to logger. @@ -76,23 +77,23 @@ def run_logged_shell_subprocess(command: str, timeout: int = 10) -> int: Example: Running a successful command: - run_logged_shell_subprocess(command="pwd") - Returns 0 + run_logged_subprocess(command=["git", "commit", "-m", "'Commit message.'"]) + Returns: {"returncode": 0, "output": []} - Running an unsuccessful command with a 20 second timeout: - run_logged_shell_subprocess(command="pwd", timeout=20) - Returns 1 + Running an unsuccessful shell command with a 20 second timeout: + run_logged_subprocess(command="cd test/", timeout=20, shell=True) + Returns: {"returncode": 1, "output": ["cd: test: No such file or directory"]} Args: - command (str): The command to run + command (Union): The command to run. If shell=False, pass a list with the first item being the command and the subsequent items being arguments. If shell=True, pass a string as you would type it into a shell. timeout (int): The number of seconds to wait for a program before killing it Returns: - int: The return code of the subprocess + dict: Containing subprocess return code and output. """ logger.debug(f"Entering subprocess for '{command}'") with subprocess.Popen(command,\ - stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True, text=True)\ + stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=shell, text=True)\ as logged_shell_process: subprocess_log_prefix = f"(PID: {logged_shell_process.pid})" @@ -108,16 +109,14 @@ def run_logged_shell_subprocess(command: str, timeout: int = 10) -> int: logger.debug(f"{subprocess_log_prefix}: {line}") except Exception as exception: logger.critical(str(exception)) - return logged_shell_process.returncode else: if logged_shell_process.returncode != 0: - logger.debug(f"Subprocess exitied with a return code of {logged_shell_process.returncode}") - return logged_shell_process.returncode + logger.debug(f"Something went wrong. '{command}' exited with return code {logged_shell_process.returncode}") elif logged_shell_process.returncode == 0: - logger.info(f"Subprocess for '{command}' completed successfuly") - return logged_shell_process.returncode + logger.debug(f"Subprocess for '{command}' completed successfuly") finally: - logger.debug(f"Exiting subprocess for '{command}''") + logger.debug(f"Exiting subprocess for '{command}'") + return {"returncode": logged_shell_process.returncode, "output": process_output_lines}