1 package envsubst
2
3 import (
4 "strconv"
5 "strings"
6 "unicode"
7 "unicode/utf8"
8
9 "github.com/drone/envsubst/v2/path"
10 )
11
12
13 type substituteFunc func(string, ...string) string
14
15
16 func toLen(s string, args ...string) string {
17 return strconv.Itoa(len(s))
18 }
19
20
21
22 func toLower(s string, args ...string) string {
23 return strings.ToLower(s)
24 }
25
26
27
28 func toUpper(s string, args ...string) string {
29 return strings.ToUpper(s)
30 }
31
32
33
34 func toLowerFirst(s string, args ...string) string {
35 if s == "" {
36 return s
37 }
38 r, n := utf8.DecodeRuneInString(s)
39 return string(unicode.ToLower(r)) + s[n:]
40 }
41
42
43
44 func toUpperFirst(s string, args ...string) string {
45 if s == "" {
46 return s
47 }
48 r, n := utf8.DecodeRuneInString(s)
49 return string(unicode.ToUpper(r)) + s[n:]
50 }
51
52
53
54 func toDefault(s string, args ...string) string {
55 if len(s) == 0 && len(args) > 0 {
56
57 s = strings.Join(args, "")
58 }
59 return s
60 }
61
62
63
64 func toSubstr(s string, args ...string) string {
65 if len(args) == 0 {
66 return s
67 }
68
69 pos, err := strconv.Atoi(args[0])
70 if err != nil {
71
72
73 return s
74 }
75
76 if pos < 0 {
77
78
79 pos = len(s) + pos
80
81
82
83 if pos < 0 {
84 pos = 0
85 }
86 }
87
88 if len(args) == 1 {
89 if pos < len(s) {
90 return s[pos:]
91 }
92
93
94 return ""
95 }
96
97 length, err := strconv.Atoi(args[1])
98 if err != nil {
99
100
101 return s
102 }
103
104 if pos+length >= len(s) {
105 if pos < len(s) {
106
107
108 return s[pos:]
109 }
110
111
112 return ""
113 }
114
115 return s[pos : pos+length]
116 }
117
118
119
120 func replaceAll(s string, args ...string) string {
121 switch len(args) {
122 case 0:
123 return s
124 case 1:
125 return strings.Replace(s, args[0], "", -1)
126 default:
127 return strings.Replace(s, args[0], args[1], -1)
128 }
129 }
130
131
132
133 func replaceFirst(s string, args ...string) string {
134 switch len(args) {
135 case 0:
136 return s
137 case 1:
138 return strings.Replace(s, args[0], "", 1)
139 default:
140 return strings.Replace(s, args[0], args[1], 1)
141 }
142 }
143
144
145
146 func replacePrefix(s string, args ...string) string {
147 if len(args) != 2 {
148 return s
149 }
150 if strings.HasPrefix(s, args[0]) {
151 return strings.Replace(s, args[0], args[1], 1)
152 }
153 return s
154 }
155
156
157
158 func replaceSuffix(s string, args ...string) string {
159 if len(args) != 2 {
160 return s
161 }
162 if strings.HasSuffix(s, args[0]) {
163 s = strings.TrimSuffix(s, args[0])
164 s = s + args[1]
165 }
166 return s
167 }
168
169
170
171 func trimShortestPrefix(s string, args ...string) string {
172 if len(args) != 0 {
173 s = trimShortest(s, args[0])
174 }
175 return s
176 }
177
178 func trimShortestSuffix(s string, args ...string) string {
179 if len(args) != 0 {
180 r := reverse(s)
181 rarg := reverse(args[0])
182 s = reverse(trimShortest(r, rarg))
183 }
184 return s
185 }
186
187 func trimLongestPrefix(s string, args ...string) string {
188 if len(args) != 0 {
189 s = trimLongest(s, args[0])
190 }
191 return s
192 }
193
194 func trimLongestSuffix(s string, args ...string) string {
195 if len(args) != 0 {
196 r := reverse(s)
197 rarg := reverse(args[0])
198 s = reverse(trimLongest(r, rarg))
199 }
200 return s
201 }
202
203 func trimShortest(s, arg string) string {
204 var shortestMatch string
205 for i := 0; i < len(s); i++ {
206 match, err := path.Match(arg, s[0:len(s)-i])
207
208 if err != nil {
209 return s
210 }
211
212 if match {
213 shortestMatch = s[0 : len(s)-i]
214 }
215 }
216
217 if shortestMatch != "" {
218 return strings.TrimPrefix(s, shortestMatch)
219 }
220
221 return s
222 }
223
224 func trimLongest(s, arg string) string {
225 for i := 0; i < len(s); i++ {
226 match, err := path.Match(arg, s[0:len(s)-i])
227
228 if err != nil {
229 return s
230 }
231
232 if match {
233 return strings.TrimPrefix(s, s[0:len(s)-i])
234 }
235 }
236
237 return s
238 }
239
240 func reverse(s string) string {
241 r := []rune(s)
242 for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
243 r[i], r[j] = r[j], r[i]
244 }
245 return string(r)
246 }
247
View as plain text