-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathresult.go
More file actions
72 lines (61 loc) · 2.55 KB
/
Copy pathresult.go
File metadata and controls
72 lines (61 loc) · 2.55 KB
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
65
66
67
68
69
70
71
72
package trexec
import (
"fmt"
"time"
)
// Result contains the complete outcome of a command execution.
//
// Unlike os/exec which returns a single error, Result preserves all
// information about what happened: exit code, whether cancellation was
// involved, whether the process shut down gracefully or was force-killed,
// and timing information.
type Result struct {
// ExitCode is the process exit code.
// 0 means success. -1 means the process was killed before it could exit normally.
ExitCode int
// Cancelled is true if the command was stopped due to context cancellation.
Cancelled bool
// GracefullyTerminated is true if the process exited on its own after
// receiving a graceful termination signal (SIGTERM on Unix, Ctrl+Break on Windows).
// This can only be true when Cancelled is also true.
GracefullyTerminated bool
// ForceKilled is true if the process had to be forcefully terminated
// after the grace period expired. This can only be true when Cancelled is also true.
ForceKilled bool
// Duration is the total wall-clock time from Start() to cleanup completion.
Duration time.Duration
// ProcessesCleaned is the count of descendant processes that were terminated
// during cleanup.
ProcessesCleaned int
// DescendantPIDs contains the process IDs of the descendant processes
// tracked by the process group / Job Object during execution.
DescendantPIDs []int
// Error contains the underlying error, if any.
// For non-zero exits: *ExitError. For cancellation-related kills: *ExitError
// with Cancelled=true. nil for successful exits.
Error error
}
// Success returns true if the command completed with exit code 0
// and was not cancelled. This is the "everything went perfectly" check.
func (r *Result) Success() bool {
return r.ExitCode == 0 && !r.Cancelled && r.Error == nil
}
// String returns a human-readable summary of the result.
func (r *Result) String() string {
switch {
case r.Success():
return fmt.Sprintf("exit=0 duration=%s", r.Duration.Round(time.Millisecond))
case r.Cancelled && r.GracefullyTerminated:
return fmt.Sprintf("cancelled (graceful exit=%d) duration=%s",
r.ExitCode, r.Duration.Round(time.Millisecond))
case r.Cancelled && r.ForceKilled:
return fmt.Sprintf("cancelled (force-killed, %d processes cleaned) duration=%s",
r.ProcessesCleaned, r.Duration.Round(time.Millisecond))
case r.Cancelled:
return fmt.Sprintf("cancelled exit=%d duration=%s",
r.ExitCode, r.Duration.Round(time.Millisecond))
default:
return fmt.Sprintf("exit=%d duration=%s",
r.ExitCode, r.Duration.Round(time.Millisecond))
}
}