this repo has no description
at trunk 73 lines 1.8 kB view raw
1import logging 2import os 3import subprocess 4import sys 5import shlex 6import textwrap 7 8SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__)) 9 10 11def run( 12 cmd, 13 verbose=True, 14 cwd=None, 15 check=True, 16 capture_output=False, 17 encoding="utf-8", 18 log_level=logging.DEBUG, 19 # Only pipe stdout; we want stderr (logging, errors) to be unbuffered. 20 stdout=subprocess.PIPE, 21 # Specify an integer number of seconds 22 timeout=-1, 23 **kwargs, 24): 25 if verbose: 26 info = "$ " 27 if cwd is not None: 28 info += f"cd {cwd}; " 29 info += " ".join(shlex.quote(c) for c in cmd) 30 if capture_output: 31 info += " >& ..." 32 lines = textwrap.wrap( 33 info, 34 break_on_hyphens=False, 35 break_long_words=False, 36 replace_whitespace=False, 37 subsequent_indent=" ", 38 ) 39 logging.log(log_level, " \\\n".join(lines)) 40 if timeout != -1: 41 cmd = ["timeout", "--signal=KILL", f"{timeout}s", *cmd] 42 try: 43 return subprocess.run( 44 cmd, 45 cwd=cwd, 46 check=check, 47 capture_output=capture_output, 48 encoding=encoding, 49 stdout=stdout, 50 **kwargs, 51 ) 52 except subprocess.CalledProcessError as e: 53 if e.returncode == -9: 54 # Error code from `timeout` command signaling it had to be killed 55 raise TimeoutError("Command timed out", cmd) 56 logging.critical("%s", e.stdout) 57 raise 58 59 60def get_repo_root(dirname): 61 proc = run( 62 ["git", "rev-parse", "--show-toplevel"], 63 cwd=dirname, 64 ) 65 return proc.stdout.strip() 66 67 68def normalize_revision(repo_root, revspec): 69 proc = run( 70 ["git", "rev-parse", revspec], 71 cwd=repo_root, 72 ) 73 return proc.stdout.strip()