internal/build/utils/debug.go (73 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package utils import ( "bufio" "fmt" "go/scanner" "go/token" "io" "os" "strings" ) // PrintSourceWithErr returns source code annotated with location of an error. // func PrintSourceWithErr(out io.Reader, err error) { if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[2m") } if e, ok := err.(scanner.ErrorList); ok { fmt.Fprintf(os.Stderr, "\x1b[2m✖ %s\n", e.Error()) } fmt.Fprintln(os.Stderr, strings.Repeat("━", TerminalWidth())) if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[0m") } if _, ok := err.(scanner.ErrorList); ok { cur := 0 ferr := err.(scanner.ErrorList) type ParseError struct { Pos token.Position Msg string } errlines := make(map[int]ParseError) for _, e := range ferr { errlines[e.Pos.Line] = ParseError{Pos: e.Pos, Msg: e.Msg} } scanner := bufio.NewScanner(out) for scanner.Scan() { cur++ if _, ok := errlines[cur]; ok { if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[1;31m") } fmt.Fprintf(os.Stderr, "%3d| ", cur) fmt.Fprintln(os.Stderr, scanner.Text()) } else { if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[2m") } fmt.Fprintf(os.Stderr, "%3d| ", cur) if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[0m") } fmt.Fprintln(os.Stderr, scanner.Text()) } if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[0m") } if e, ok := errlines[cur]; ok { if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[31m") } fmt.Fprintf(os.Stderr, strings.Repeat(" ", 4)) for i := 0; i < e.Pos.Column; i++ { fmt.Fprintf(os.Stderr, "-") } fmt.Fprintf(os.Stderr, "^ ") fmt.Fprintf(os.Stderr, e.Msg) fmt.Fprintf(os.Stderr, "\n") if IsTTY() { fmt.Fprint(os.Stderr, "\x1b[0m") } } } fmt.Fprintln(os.Stderr, "") } }