61 lines
2.2 KiB
Text
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
|