import io import subprocess import typing as T from pathlib import Path PathLike = T.Union[str, Path] PathOrBuffer = T.Union[PathLike, io.StringIO] def run_subprocess_with_errorcheck( *popenargs, capture_output: bool = False, quiet: bool = False, env: dict[str, str] | None = None, shell: bool = False, executable: str | None = None, **kws, ) -> subprocess.CompletedProcess: """A command similar to subprocess.run, however the errormessage will contain the stderr when using this function. This makes it significantly easier to diagnose issues. """ try: if capture_output: stdout = subprocess.PIPE elif quiet: stdout = subprocess.DEVNULL else: stdout = None p = subprocess.run( *popenargs, stderr=subprocess.PIPE, stdout=stdout, check=True, env=env, shell=shell, executable=executable, **kws, ) except subprocess.CalledProcessError as e: raise RuntimeError( f"Command failed with errorcode {e.returncode}." f"\n\n{e.stderr.decode()}" ) return p