forked from leonlee/drone-exec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
strings.go
186 lines (172 loc) · 4.86 KB
/
strings.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package inject
import (
"fmt"
"regexp"
"strconv"
"strings"
)
// these are helper functions that bring bash-substitution
// to the drone yaml file.
// see http://tldp.org/LDP/abs/html/parameter-substitution.html
type substituteFunc func(str, key, val string) string
var substitutors = []substituteFunc{
substituteQ,
substitute,
substituteBracket,
substitutePrefix,
substituteSuffix,
substituteDefault,
substituteReplace,
substituteLeft,
substituteSubstr,
}
// substitute is a helper function that substitutes
// a simple parameter using $parameter notation.
func substitute(str, key, val string) string {
key = fmt.Sprintf("$$%s", key)
return strings.Replace(str, key, val, -1)
}
// substituteQ is a helper function that substitutes
// a simple parameter using "$parameter" notation with
// the escaped value, using %q.
func substituteQ(str, key, val string) string {
key = fmt.Sprintf(`"$$%s"`, key)
val = fmt.Sprintf("%q", val)
return strings.Replace(str, key, val, -1)
}
// substituteBracket is a helper function that substitutes
// paramters using ${parameter} notation with the value.
func substituteBracket(str, key, val string) string {
key = fmt.Sprintf("$${%s}", key)
return strings.Replace(str, key, val, -1)
}
// substitutePrefix is a helper function that substitutes
// paramters using ${parameter##prefix} notation with the
// parameter value minus the trimmed prefix.
func substitutePrefix(str, key, val string) string {
key = fmt.Sprintf("\\$\\${%s##(.+)}", key)
reg, err := regexp.Compile(key)
if err != nil {
return str
}
for _, match := range reg.FindAllStringSubmatch(str, -1) {
if len(match) != 2 {
continue
}
val_ := strings.TrimPrefix(val, match[1])
str = strings.Replace(str, match[0], val_, -1)
}
return str
}
// substituteSuffix is a helper function that substitutes
// paramters using ${parameter%%suffix} notation with the
// parameter value minus the trimmed suffix.
func substituteSuffix(str, key, val string) string {
key = fmt.Sprintf("\\$\\${%s%%%%(.+)}", key)
reg, err := regexp.Compile(key)
if err != nil {
return str
}
for _, match := range reg.FindAllStringSubmatch(str, -1) {
if len(match) != 2 {
continue
}
val_ := strings.TrimSuffix(val, match[1])
str = strings.Replace(str, match[0], val_, -1)
}
return str
}
// substituteDefault is a helper function that substitutes
// paramters using ${parameter=default} notation with the
// parameter value. When empty the default value is used.
func substituteDefault(str, key, val string) string {
key = fmt.Sprintf("\\$\\${%s=(.+)}", key)
reg, err := regexp.Compile(key)
if err != nil {
return str
}
for _, match := range reg.FindAllStringSubmatch(str, -1) {
if len(match) != 2 {
continue
}
if len(val) == 0 {
str = strings.Replace(str, match[0], match[1], -1)
} else {
str = strings.Replace(str, match[0], val, -1)
}
}
return str
}
// substituteReplace is a helper function that substitutes
// paramters using ${parameter/old/new} notation with the
// parameter value. A find and replace is performed before
// injecting the strings, replacing the old pattern with the
// new value.
func substituteReplace(str, key, val string) string {
key = fmt.Sprintf("\\$\\${%s/(.+)/(.+)}", key)
reg, err := regexp.Compile(key)
if err != nil {
return str
}
for _, match := range reg.FindAllStringSubmatch(str, -1) {
if len(match) != 3 {
continue
}
with := strings.Replace(val, match[1], match[2], -1)
str = strings.Replace(str, match[0], with, -1)
}
return str
}
// substituteLeft is a helper function that substitutes
// paramters using ${parameter:pos} notation with the
// parameter value, sliced up to the specified position.
func substituteLeft(str, key, val string) string {
key = fmt.Sprintf("\\$\\${%s:([0-9]*)}", key)
reg, err := regexp.Compile(key)
if err != nil {
return str
}
for _, match := range reg.FindAllStringSubmatch(str, -1) {
if len(match) != 2 {
continue
}
index, err := strconv.Atoi(match[1])
if err != nil {
continue // skip
}
if index > len(val)-1 {
continue // skip
}
str = strings.Replace(str, match[0], val[:index], -1)
}
return str
}
// substituteLeft is a helper function that substitutes
// paramters using ${parameter:pos:len} notation with the
// parameter value as a substring, starting at the specified
// position for the specified length.
func substituteSubstr(str, key, val string) string {
key = fmt.Sprintf("\\$\\${%s:([0-9]*):([0-9]*)}", key)
reg, err := regexp.Compile(key)
if err != nil {
return str
}
for _, match := range reg.FindAllStringSubmatch(str, -1) {
if len(match) != 3 {
continue
}
pos, err := strconv.Atoi(match[1])
if err != nil {
continue // skip
}
length, err := strconv.Atoi(match[2])
if err != nil {
continue // skip
}
if pos+length > len(val)-1 {
continue // skip
}
str = strings.Replace(str, match[0], val[pos:pos+length], -1)
}
return str
}