Skip to content

Commit

Permalink
Make logging shell calls optional
Browse files Browse the repository at this point in the history
  • Loading branch information
shreve committed Jun 13, 2024
1 parent bcf5ce5 commit 990aff8
Showing 1 changed file with 24 additions and 14 deletions.
38 changes: 24 additions & 14 deletions src/mads/build/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
BUILD_ROOT = Path(".").resolve()


def shell(cmd: str, raise_on_error: bool = True, **kwargs) -> str:
def shell(cmd: str, raise_on_error: bool = True, log_out: bool = True, **kwargs) -> str:
"""Run a command and return a string of it's output."""

res = proc(cmd, **kwargs)
res = proc(cmd, log_out, **kwargs)

# We're usually requiring processes to exit successfully.
if raise_on_error:
Expand All @@ -29,33 +29,38 @@ def shell(cmd: str, raise_on_error: bool = True, **kwargs) -> str:
return res.stdout.decode("utf-8").strip()


def proc(cmd: str, **kwargs) -> subprocess.CompletedProcess:
def proc(cmd: str, log_out: bool = False, **kwargs) -> subprocess.CompletedProcess:
"""Like shell, but return the process object."""

# Prepare the command to be printed
printcmd = cmd
if "cwd" in kwargs:
printdir = str(kwargs["cwd"]).replace(str(BUILD_ROOT), ".")
printcmd = f"cd {printdir} && {cmd}"
log.info("[shell] %s", printcmd)
log.indent()
if log_out:
log.info("[shell] %s", printcmd)
log.indent()

# Run the process
start = time.time()
res = _stream_process(cmd, **kwargs)
res = _stream_process(cmd, log_out, **kwargs)
delta = time.time() - start

# Close out the logging indent.
log.outdent()
log.info(
"%s Completed with code %s after %0.2f seconds", LSS_END, res.returncode, delta
)
log.info("")
if log_out:
log.outdent()
log.info(
"%s Completed with code %s after %0.2f seconds",
LSS_END,
res.returncode,
delta,
)
log.info("")

return res


def _stream_process(cmd, **kwargs):
def _stream_process(cmd: str, log_out: bool, **kwargs):
with subprocess.Popen(
cmd,
encoding="utf-8",
Expand All @@ -82,6 +87,11 @@ def _stream_process(cmd, **kwargs):
stdout = ""
stderr = ""

def noop(*_):
pass

log_fn = log.info if log_out else noop

def communicate(proc):
"""Read stdin and stdout from a process as streams."""
nonlocal stdout, stderr
Expand All @@ -94,10 +104,10 @@ def communicate(proc):
lines = [line.rstrip() for line in stream.readlines()]
for line in lines:
if stream == process.stdout:
log.info(" %s", line)
log_fn(" %s", line)
stdout += line + "\n"
else:
log.info("* %s", line)
log_fn("* %s", line)
stderr += line + "\n"

# While the process is alive, read it's output streams
Expand Down

0 comments on commit 990aff8

Please sign in to comment.