/
replace.go
79 lines (71 loc) · 1.83 KB
/
replace.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
package main
import (
"strings"
)
func replace(input string) string {
if strings.Contains(input, "xerrors.New") {
input = strings.ReplaceAll(input, "xerrors.New", "errors.New")
}
if strings.Contains(input, "xerrors.Is") {
input = strings.ReplaceAll(input, "xerrors.Is", "errors.Is")
}
const marker = `xerrors.Errorf("`
start := strings.Index(input, marker)
if start < 0 {
return input
}
const endMarker = `)`
end := strings.LastIndex(input[start:], endMarker)
if !strings.Contains(input, "%") {
// No format.
return strings.ReplaceAll(input, "xerrors.Errorf", "errors.New")
}
if end == 0 || !strings.Contains(input, `%w`) {
// No wrapping, just new error.
return strings.ReplaceAll(input, "xerrors.Errorf", "errors.Errorf")
}
// xerrors.Errorf("MESSAGE: %w", a1, a2, a3, a4, err)
// fmtStart------^ fmtEnd-^ ^--firstComma ^---lastComma
call := input[start : start+end+len(endMarker)]
lastComma := strings.LastIndex(call, ",")
fmtEnd := strings.Index(call, `: %w"`)
fmtStart := strings.Index(call, `"`)
for _, idx := range [...]int{
lastComma,
fmtEnd,
fmtStart,
} {
if idx > 0 {
continue
}
return input
}
firstComma := strings.Index(call[fmtEnd:], ",")
if firstComma < 0 {
return input
}
firstComma += fmtEnd + 1
var formatArgs string
if firstComma < lastComma {
formatArgs = strings.TrimSpace(call[firstComma:lastComma])
}
wrapTarget := strings.TrimSpace(call[lastComma+1 : len(call)-1])
var b strings.Builder
b.WriteString("errors.")
if formatArgs != "" {
b.WriteString("Wrapf")
} else {
b.WriteString("Wrap")
}
b.WriteByte('(')
b.WriteString(wrapTarget)
b.WriteString(`, "`)
b.WriteString(call[fmtStart+1 : fmtEnd])
b.WriteString(`"`)
if formatArgs != "" {
b.WriteString(", ")
b.WriteString(formatArgs)
}
b.WriteString(")")
return strings.ReplaceAll(input, call, b.String())
}