Files
buildkit/solver/errdefs/source.go
Tonis Tiigi 4e8334de75 lint: renable error types for errname
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2025-05-02 12:19:22 -07:00

120 lines
2.0 KiB
Go

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 &SourceError{Source: src, error: err}
}
type SourceError struct {
*Source
error
}
func (e *SourceError) Unwrap() error {
return e.error
}
func (e *SourceError) ToProto() grpcerrors.TypedErrorProto {
return e.Source
}
func Sources(err error) []*Source {
var out []*Source
var es *SourceError
if errors.As(err, &es) {
out = Sources(es.Unwrap())
out = append(out, es.CloneVT())
}
return out
}
func (s *Source) WrapError(err error) error {
return &SourceError{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 p < pad {
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 := max(r.End.Line, 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 := max(r.End.Line, 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
}