lean4-htt/Lake/Util/Proc.lean

61 lines
2.2 KiB
Text

/-
Copyright (c) 2022 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner, Sebastian Ullrich, Mac Malone
-/
import Lake.Util.Log
namespace Lake
@[specialize] def logProcWith [Monad m]
(args : IO.Process.SpawnArgs) (out : IO.Process.Output) (log : String → m PUnit) : m Unit := do
let envStr := String.join <| args.env.toList.filterMap fun (k, v) =>
if k == "PATH" then none else some s!"{k}={v.getD ""} " -- PATH too big
let cmdStr := " ".intercalate (args.cmd :: args.args.toList)
log <| "> " ++ envStr ++
match args.cwd with
| some cwd => s!"{cmdStr} # in directory {cwd}"
| none => cmdStr
unless out.stdout.isEmpty do
log s!"stdout:\n{out.stdout}"
unless out.stderr.isEmpty do
log s!"stderr:\n{out.stderr}"
def proc (args : IO.Process.SpawnArgs) : LogIO Unit := do
match (← IO.Process.output args |>.toBaseIO) with
| .ok out =>
if out.exitCode = 0 then
logProcWith args out logVerbose
else
logProcWith args out logError
error s!"external command `{args.cmd}` exited with code {out.exitCode}"
| .error err =>
error s!"failed to execute `{args.cmd}`: {err}"
def captureProc (args : IO.Process.SpawnArgs) : LogIO String := do
match (← IO.Process.output args |>.toBaseIO) with
| .ok out =>
if out.exitCode = 0 then
return out.stdout.trim -- remove, e.g., newline at end
else
logProcWith args out logError
error s!"external command `{args.cmd}` exited with code {out.exitCode}"
| .error err =>
error s!"failed to execute `{args.cmd}`: {err}"
def captureProc? (args : IO.Process.SpawnArgs) : BaseIO (Option String) := do
EIO.catchExceptions (h := fun _ => pure none) do
let out ← IO.Process.output args
if out.exitCode = 0 then
return some out.stdout.trim -- remove, e.g., newline at end
else
return none
def testProc (args : IO.Process.SpawnArgs) : BaseIO Bool :=
EIO.catchExceptions (h := fun _ => pure false) do
let child ← IO.Process.spawn {
args with
stdout := IO.Process.Stdio.null
stderr := IO.Process.Stdio.null
}
return (← child.wait) == 0