-
Notifications
You must be signed in to change notification settings - Fork 33
/
helper.go
80 lines (68 loc) · 2.28 KB
/
helper.go
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
// SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Gardener contributors.
//
// SPDX-License-Identifier: Apache-2.0
package gotemplate
import (
"fmt"
"math"
"strings"
)
const (
// sourceCodePrepend the number of lines before the error line that are printed.
sourceCodePrepend = 5
// sourceCodeAppend the number of lines after the error line that are printed.
sourceCodeAppend = 5
// sourceIndentation is the fixed width of the code line prefix containing the line number.
sourceIndentation = 6
)
// CreateSourceSnippet creates an excerpt of lines of source code, containing some lines before
// and after the error line.
// The error line and column will be highlighted and looks like this:
// 14: updateStrategy: patch
// 15:
// 16: name: test
// 17: namespace: {{ .imports.namaspace }}
//
// ˆ≈≈≈≈≈≈≈
//
// 18:
// 19: exportsFromManifests:
// 20: - key: ingressClass
func CreateSourceSnippet(errorLine, errorColumn int, source []string) string {
var (
sourceStartLine, sourceEndLine int
formatted = strings.Builder{}
)
// convert to zero base index
errorLine -= 1
// calculate the starting line of the source code
sourceStartLine = errorLine - sourceCodePrepend
if sourceStartLine < 0 {
sourceStartLine = 0
}
errorLine -= sourceStartLine
source = source[sourceStartLine:]
// calculate the ending line of the source code
sourceEndLine = errorLine + sourceCodeAppend + 1
if sourceEndLine > len(source) {
sourceEndLine = len(source)
}
source = source[:sourceEndLine]
for i, line := range source {
// for printing, the line has to be converted back to one based index
realLine := sourceStartLine + i + 1
realLineWidth := int(math.Log10(float64(realLine)) + 1)
// account for the colon after the line number
repeat := sourceIndentation - realLineWidth - 1
if repeat < 0 {
repeat = 0
}
// the prefix contains the line number and some amount of whitespaces to keep the correct indentation
prefix := fmt.Sprintf("%d:%s", realLine, strings.Repeat(" ", repeat))
formatted.WriteString(fmt.Sprintf("%s%s\n", prefix, line))
if i == errorLine {
formatted.WriteString(fmt.Sprintf("%s\u02c6≈≈≈≈≈≈≈\n", strings.Repeat(" ", errorColumn+len(prefix))))
}
}
return formatted.String()
}