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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
package errdefs
import (
"fmt"
"io"
"strings"
pb "github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/util/grpcerrors"
"github.com/pkg/errors"
)
func WithSource(err error, src Source) error {
if err == nil {
return nil
}
return &ErrorSource{Source: src, error: err}
}
type ErrorSource struct {
Source
error
}
func (e *ErrorSource) Unwrap() error {
return e.error
}
func (e *ErrorSource) ToProto() grpcerrors.TypedErrorProto {
return &e.Source
}
func Sources(err error) []*Source {
var out []*Source
var es *ErrorSource
if errors.As(err, &es) {
out = Sources(es.Unwrap())
out = append(out, &es.Source)
}
return out
}
func (s *Source) WrapError(err error) error {
return &ErrorSource{error: err, Source: *s}
}
func (s *Source) Print(w io.Writer) error {
si := s.Info
if si == nil {
return nil
}
lines := strings.Split(string(si.Data), "\n")
start, end, ok := getStartEndLine(s.Ranges)
if !ok {
return nil
}
if start > len(lines) || start < 1 {
return nil
}
if end > len(lines) {
end = len(lines)
}
pad := 2
if end == start {
pad = 4
}
var p int
prepadStart := start
for {
if p >= pad {
break
}
if start > 1 {
start--
p++
}
if end != len(lines) {
end++
p++
}
p++
}
fmt.Fprintf(w, "%s:%d\n--------------------\n", si.Filename, prepadStart)
for i := start; i <= end; i++ {
pfx := " "
if containsLine(s.Ranges, i) {
pfx = ">>>"
}
fmt.Fprintf(w, " %3d | %s %s\n", i, pfx, lines[i-1])
}
fmt.Fprintf(w, "--------------------\n")
return nil
}
func containsLine(rr []*pb.Range, l int) bool {
for _, r := range rr {
e := r.End.Line
if e < r.Start.Line {
e = r.Start.Line
}
if r.Start.Line <= int32(l) && e >= int32(l) {
return true
}
}
return false
}
func getStartEndLine(rr []*pb.Range) (start int, end int, ok bool) {
first := true
for _, r := range rr {
e := r.End.Line
if e < r.Start.Line {
e = r.Start.Line
}
if first || int(r.Start.Line) < start {
start = int(r.Start.Line)
}
if int(e) > end {
end = int(e)
}
first = false
}
return start, end, !first
}
|