#!/usr/bin/env python3 # Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) import shlex import subprocess import sys import textwrap def with_pty(command): return [sys.executable, "-c", "import pty, sys; pty.spawn(sys.argv[1:])"] + command def run( cmd, verbose=True, cwd=None, check=True, capture_output=False, encoding="utf-8", # Specify an integer number of seconds timeout=-1, **kwargs, ): if verbose: info = "$ " if cwd is not None: info += f"cd {cwd}; " info += " ".join(shlex.quote(c) for c in cmd) if capture_output: info += " >& ..." lines = textwrap.wrap( info, break_on_hyphens=False, break_long_words=False, replace_whitespace=False, subsequent_indent=" ", ) print(" \\\n".join(lines)) if timeout != -1: cmd = ["timeout", "--signal=KILL", f"{timeout}s", *cmd] try: return subprocess.run( cmd, cwd=cwd, check=check, capture_output=capture_output, encoding=encoding, **kwargs, ) except subprocess.CalledProcessError as e: if e.returncode == -9: # Error code from `timeout` command signaling it had to be killed raise TimeoutError("Command timed out", cmd) raise