def run_cmd(cmd, show_output=True, raise_errs=True, **kwargs): """Run a console command. When show_output=True, prints output and returns exit code, otherwise returns output. When raise_errs=True, raises a subprocess.CalledProcessError if the command fails. """ internal_assert(cmd and isinstance(cmd, list), "console commands must be passed as non-empty lists") try: from shutil import which except ImportError: pass else: cmd[0] = which(cmd[0]) or cmd[0] logger.log_cmd(cmd) try: if show_output and raise_errs: return subprocess.check_call(cmd, **kwargs) elif show_output: return subprocess.call(cmd, **kwargs) else: stdout, stderr, retcode = call_output(cmd, **kwargs) output = "".join(stdout + stderr) if retcode and raise_errs: raise subprocess.CalledProcessError(retcode, cmd, output=output) return output except OSError: logger.log_exc() if raise_errs: raise subprocess.CalledProcessError(oserror_retcode, cmd) elif show_output: return oserror_retcode else: return ""
def mypy_run(args): """Run mypy with given arguments and return the result.""" logger.log_cmd(["mypy"] + args) try: stdout, stderr, exit_code = run(args) except BaseException: logger.print_exc() else: for line in stdout.splitlines(): yield line, False for line in stderr.splitlines(): yield line, True
def mypy_run(args): """Runs mypy with given arguments and shows the result.""" logger.log_cmd(["mypy"] + args) try: stdout, stderr, exit_code = run(args) except BaseException: traceback.print_exc() else: for line in stdout.splitlines(): yield line, False for line in stderr.splitlines(): yield line, True
def run_cmd(cmd, show_output=True, raise_errs=True): """Runs a console command.""" if not isinstance(cmd, list): raise CoconutInternalException("console commands must be passed as lists") else: if sys.version_info >= (3, 3): import shutil cmd[0] = shutil.which(cmd[0]) or cmd[0] logger.log_cmd(cmd) if show_output and raise_errs: return subprocess.check_call(cmd) elif raise_errs: return subprocess.check_output(cmd, stderr=subprocess.STDOUT) elif show_output: return subprocess.call(cmd) else: return "".join(call_output(cmd))
def run_cmd(cmd, show_output=True, raise_errs=True): """Runs a console command.""" if not cmd or not isinstance(cmd, list): raise CoconutInternalException( "console commands must be passed as non-empty lists") else: try: from shutil import which except ImportError: pass else: cmd[0] = which(cmd[0]) or cmd[0] logger.log_cmd(cmd) if show_output and raise_errs: return subprocess.check_call(cmd) elif show_output: return subprocess.call(cmd) else: stdout, stderr, _ = call_output(cmd) return "".join(stdout + stderr)
def call(raw_cmd, assert_output=False, check_mypy=False, check_errors=True, stderr_first=False, expect_retcode=0, convert_to_import=False, **kwargs): """Execute a shell command and assert that no errors were encountered.""" if isinstance(raw_cmd, str): cmd = raw_cmd.split() else: cmd = raw_cmd print() logger.log_cmd(cmd) if assert_output is False: assert_output = ("", ) elif assert_output is True: assert_output = ("<success>", ) elif isinstance(assert_output, str): if "\n" not in assert_output: assert_output = (assert_output, ) else: assert_output = tuple(x if x is not True else "<success>" for x in assert_output) if convert_to_import is None: convert_to_import = (cmd[0] == sys.executable and cmd[1] != "-c" and cmd[1:3] != ["-m", "coconut"]) if convert_to_import: assert cmd[0] == sys.executable if cmd[1] == "-m": module_name = cmd[2] extra_argv = cmd[3:] stdout, stderr, retcode = call_with_import(module_name, extra_argv) else: module_path = cmd[1] extra_argv = cmd[2:] module_dir = os.path.dirname(module_path) module_name = os.path.splitext(os.path.basename(module_path))[0] if os.path.isdir(module_path): module_name += ".__main__" with using_sys_path(module_dir): stdout, stderr, retcode = call_with_import( module_name, extra_argv) else: stdout, stderr, retcode = call_output(raw_cmd, **kwargs) if expect_retcode is not None: assert retcode == expect_retcode, "Return code not as expected ({retcode} != {expect_retcode}) in: {cmd!r}".format( retcode=retcode, expect_retcode=expect_retcode, cmd=raw_cmd, ) if stderr_first: out = stderr + stdout else: out = stdout + stderr out = "".join(out) raw_lines = out.splitlines() lines = [] i = 0 while True: if i >= len(raw_lines): break line = raw_lines[i] # ignore https://bugs.python.org/issue39098 errors if sys.version_info < ( 3, 9) and line == "Error in atexit._run_exitfuncs:": while True: i += 1 if i >= len(raw_lines): break new_line = raw_lines[i] if not new_line.startswith(" ") and not any( test in new_line for test in ignore_atexit_errors_with): i -= 1 break continue # combine mypy error lines if line.rstrip().endswith("error:"): line += raw_lines[i + 1] i += 1 lines.append(line) i += 1 for line in lines: assert "CoconutInternalException" not in line, "CoconutInternalException in " + repr( line) assert "<unprintable" not in line, "Unprintable error in " + repr(line) assert "*** glibc detected ***" not in line, "C error in " + repr(line) assert "INTERNAL ERROR" not in line, "MyPy INTERNAL ERROR in " + repr( line) if check_errors: assert "Traceback (most recent call last):" not in line, "Traceback in " + repr( line) assert "Exception" not in line, "Exception in " + repr(line) assert "Error" not in line, "Error in " + repr(line) if check_mypy and all(test not in line for test in ignore_mypy_errs_with): assert "error:" not in line, "MyPy error in " + repr(line) if isinstance(assert_output, str): got_output = "\n".join(raw_lines) + "\n" assert assert_output in got_output, "Expected " + repr( assert_output) + "; got " + repr(got_output) else: if not lines: last_line = "" elif "--mypy" in cmd: last_line = " ".join(lines[-2:]) else: last_line = lines[-1] if assert_output is None: assert not last_line, "Expected nothing; got:\n" + "\n".join( repr(li) for li in raw_lines) else: assert any(x in last_line for x in assert_output), ( "Expected " + ", ".join(repr(s) for s in assert_output) + "; got:\n" + "\n".join(repr(li) for li in raw_lines))