-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathdependency_error.go
More file actions
73 lines (59 loc) · 1.87 KB
/
dependency_error.go
File metadata and controls
73 lines (59 loc) · 1.87 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
73
package executor
import (
"errors"
"fmt"
"io"
"strings"
"github.com/fatih/color"
)
// DependencyError carries the full dependency chain when a command fails.
// Chain is outermost-first (e.g., ["deploy", "build", "lint"]).
type DependencyError struct {
Chain []string
Err error
}
const treePrefix = "lets: "
func (e *DependencyError) Error() string { return e.Err.Error() }
func (e *DependencyError) Unwrap() error { return e.Err }
// ExitCode propagates the exit code from the innermost ExecuteError, or returns 1.
func (e *DependencyError) ExitCode() int {
var exitErr *ExecuteError
if errors.As(e.Err, &exitErr) {
return exitErr.ExitCode()
}
return 1
}
func (e *DependencyError) FailureMessage() string {
var executeErr *ExecuteError
if errors.As(e.Err, &executeErr) {
return executeErr.Cause().Error()
}
return e.Err.Error()
}
// prependToChain prepends name to the chain in err if err is already a *DependencyError,
// otherwise wraps err in a new single-element DependencyError.
func prependToChain(name string, err error) error {
var depErr *DependencyError
if errors.As(err, &depErr) {
return &DependencyError{Chain: append([]string{name}, depErr.Chain...), Err: depErr.Err}
}
return &DependencyError{Chain: []string{name}, Err: err}
}
// PrintDependencyTree writes an indented tree of the dependency chain to w.
// The failing node (last in chain) is annotated in red.
// Respects NO_COLOR automatically via fatih/color.
func PrintDependencyTree(e *DependencyError, w io.Writer) {
red := color.New(color.FgRed).SprintFunc()
treeIndent := strings.Repeat(" ", len(treePrefix))
for i, name := range e.Chain {
indent := treeIndent + strings.Repeat(" ", i+1)
if i == 0 {
indent = treePrefix
}
if i == len(e.Chain)-1 {
fmt.Fprintf(w, "%s%s %s\n", indent, name, red("<-- failed here"))
} else {
fmt.Fprintf(w, "%s%s\n", indent, name)
}
}
}