forked from leanprover/lean4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProc.lean
64 lines (56 loc) · 2.29 KB
/
Proc.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/-
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
def mkCmdLog (args : IO.Process.SpawnArgs) : String :=
let envStr := String.join <| args.env.toList.map fun (k, v) =>
if k == "PATH" then "PATH " else s!"{k}={v.getD ""} " -- PATH too big
let cmdStr := " ".intercalate (args.cmd :: args.args.toList)
let cwd := args.cwd.getD "."
s!"{cwd}> {envStr}{cmdStr}"
@[inline] def logOutput
[Monad m] (out : IO.Process.Output) (log : String → m PUnit)
: m Unit := do
unless out.stdout.isEmpty do
log s!"stdout:\n{out.stdout}"
unless out.stderr.isEmpty do
log s!"stderr:\n{out.stderr}"
@[inline] def rawProc (args : IO.Process.SpawnArgs) (quiet := false) : LogIO IO.Process.Output := do
withLogErrorPos do
unless quiet do logVerbose (mkCmdLog args)
match (← IO.Process.output args |>.toBaseIO) with
| .ok out => return out
| .error err => error s!"failed to execute '{args.cmd}': {err}"
def proc (args : IO.Process.SpawnArgs) (quiet := false) : LogIO Unit := do
withLogErrorPos do
let out ← rawProc args
logOutput out (if quiet then logVerbose else logInfo)
if out.exitCode ≠ 0 then
error s!"external command '{args.cmd}' exited with code {out.exitCode}"
def captureProc (args : IO.Process.SpawnArgs) : LogIO String := do
let out ← rawProc args (quiet := true)
if out.exitCode = 0 then
return out.stdout.trim -- remove, e.g., newline at end
else errorWithLog do
logVerbose (mkCmdLog args)
logOutput out logInfo
logError s!"external command '{args.cmd}' exited with code {out.exitCode}"
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
stdin := IO.Process.Stdio.null
stdout := IO.Process.Stdio.null
stderr := IO.Process.Stdio.null
}
return (← child.wait) == 0