Skip to content

Commit

Permalink
Refactor run_logged_subprocess to return a dict with returncode and o…
Browse files Browse the repository at this point in the history
…utput
  • Loading branch information
Justin Campbell committed Sep 16, 2020
1 parent 74653c4 commit 290ab8c
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions utils/venv-manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from pathlib import Path
import os, logging, argparse, subprocess
from typing import Union


################################################################################
Expand Down Expand Up @@ -67,32 +68,32 @@ 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.
If the subprocess raises an exception, the exception is logged as critical.
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})"
Expand All @@ -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}



Expand Down

0 comments on commit 290ab8c

Please sign in to comment.