diff --git a/cmd/cmd.go b/cmd/cmd.go index 79904c5..84a5aee 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "github.com/clevyr/go-yampl/internal/config" + "github.com/clevyr/go-yampl/internal/node" "github.com/clevyr/go-yampl/internal/parser" "github.com/clevyr/go-yampl/internal/visitor" "github.com/goccy/go-yaml/ast" @@ -152,8 +153,13 @@ func templateReader(conf config.Config, r io.Reader) (string, error) { v := visitor.NewTemplateComments(conf) for _, doc := range file.Docs { - if ast.Walk(&v, doc.Body); v.Error() != nil { - return "", v.Error() + ast.Walk(&v, doc.Body) + if err := v.Error(); err != nil { + switch err := err.(type) { + case node.PrintableError: + return "", fmt.Errorf("%w\n%v", err, err.AnnotateSource(file.String(), colored)) + } + return "", err } } diff --git a/cmd/flag_log.go b/cmd/flag_log.go index 8ed7465..535f473 100644 --- a/cmd/flag_log.go +++ b/cmd/flag_log.go @@ -8,6 +8,7 @@ import ( var ( logLevel string logFormat string + colored bool ) func init() { @@ -54,8 +55,9 @@ func initLogFormat(format string) log.Formatter { var formatter log.Formatter = &log.TextFormatter{} switch format { case "auto", "a": - break + colored = true case "color", "c": + colored = true formatter.(*log.TextFormatter).ForceColors = true case "plain", "p": formatter.(*log.TextFormatter).DisableColors = true diff --git a/internal/node/printable_error.go b/internal/node/printable_error.go new file mode 100644 index 0000000..706fed1 --- /dev/null +++ b/internal/node/printable_error.go @@ -0,0 +1,36 @@ +package node + +import ( + "github.com/goccy/go-yaml" + "github.com/goccy/go-yaml/ast" +) + +func NewPrintableError(err error, node ast.Node) PrintableError { + return PrintableError{ + err: err, + node: node, + } +} + +type PrintableError struct { + err error + node ast.Node +} + +func (p PrintableError) Error() string { + return p.err.Error() +} + +func (p PrintableError) AnnotateSource(src string, colored bool) string { + path, err := yaml.PathString(p.node.GetPath()) + if err != nil { + return "" + } + + source, err := path.AnnotateSource([]byte(src), colored) + if err != nil { + return "" + } + + return string(source) +} diff --git a/internal/visitor/template_comments.go b/internal/visitor/template_comments.go index 45c55d9..8fa895c 100644 --- a/internal/visitor/template_comments.go +++ b/internal/visitor/template_comments.go @@ -29,7 +29,7 @@ func (v *TemplateComments) Visit(n ast.Node) ast.Visitor { newNode, err := templateComment(v.conf, comment, n.Value) if err != nil { if v.err == nil { - v.err = err + v.err = node.NewPrintableError(err, n) } return nil } @@ -37,7 +37,7 @@ func (v *TemplateComments) Visit(n ast.Node) ast.Visitor { if newNode != nil { if err := n.Replace(newNode); err != nil { if v.err == nil { - v.err = err + v.err = node.NewPrintableError(err, n) } return nil } @@ -49,7 +49,7 @@ func (v *TemplateComments) Visit(n ast.Node) ast.Visitor { newNode, err := templateComment(v.conf, comment, value) if err != nil { if v.err == nil { - v.err = err + v.err = node.NewPrintableError(err, value) } return nil } @@ -57,7 +57,7 @@ func (v *TemplateComments) Visit(n ast.Node) ast.Visitor { if newNode != nil { if err := n.Replace(i, newNode); err != nil { if v.err == nil { - v.err = err + v.err = node.NewPrintableError(err, value) } return nil }