podman
317 строк · 8.1 Кб
1package sprig
2
3import (
4"errors"
5"html/template"
6"math/rand"
7"os"
8"path"
9"path/filepath"
10"reflect"
11"strconv"
12"strings"
13ttemplate "text/template"
14"time"
15)
16
17// FuncMap produces the function map.
18//
19// Use this to pass the functions into the template engine:
20//
21// tpl := template.New("foo").Funcs(sprig.FuncMap()))
22//
23func FuncMap() template.FuncMap {
24return HtmlFuncMap()
25}
26
27// HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions.
28func HermeticTxtFuncMap() ttemplate.FuncMap {
29r := TxtFuncMap()
30for _, name := range nonhermeticFunctions {
31delete(r, name)
32}
33return r
34}
35
36// HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions.
37func HermeticHtmlFuncMap() template.FuncMap {
38r := HtmlFuncMap()
39for _, name := range nonhermeticFunctions {
40delete(r, name)
41}
42return r
43}
44
45// TxtFuncMap returns a 'text/template'.FuncMap
46func TxtFuncMap() ttemplate.FuncMap {
47return ttemplate.FuncMap(GenericFuncMap())
48}
49
50// HtmlFuncMap returns an 'html/template'.Funcmap
51func HtmlFuncMap() template.FuncMap {
52return template.FuncMap(GenericFuncMap())
53}
54
55// GenericFuncMap returns a copy of the basic function map as a map[string]interface{}.
56func GenericFuncMap() map[string]interface{} {
57gfm := make(map[string]interface{}, len(genericMap))
58for k, v := range genericMap {
59gfm[k] = v
60}
61return gfm
62}
63
64// These functions are not guaranteed to evaluate to the same result for given input, because they
65// refer to the environment or global state.
66var nonhermeticFunctions = []string{
67// Date functions
68"date",
69"date_in_zone",
70"date_modify",
71"now",
72"htmlDate",
73"htmlDateInZone",
74"dateInZone",
75"dateModify",
76
77// Strings
78"randAlphaNum",
79"randAlpha",
80"randAscii",
81"randNumeric",
82"randBytes",
83"uuidv4",
84
85// OS
86"env",
87"expandenv",
88
89// Network
90"getHostByName",
91}
92
93var genericMap = map[string]interface{}{
94"hello": func() string { return "Hello!" },
95
96// Date functions
97"ago": dateAgo,
98"date": date,
99"date_in_zone": dateInZone,
100"date_modify": dateModify,
101"dateInZone": dateInZone,
102"dateModify": dateModify,
103"duration": duration,
104"durationRound": durationRound,
105"htmlDate": htmlDate,
106"htmlDateInZone": htmlDateInZone,
107"must_date_modify": mustDateModify,
108"mustDateModify": mustDateModify,
109"mustToDate": mustToDate,
110"now": time.Now,
111"toDate": toDate,
112"unixEpoch": unixEpoch,
113
114// Strings
115"trunc": trunc,
116"trim": strings.TrimSpace,
117"upper": strings.ToUpper,
118"lower": strings.ToLower,
119"title": strings.Title,
120"substr": substring,
121// Switch order so that "foo" | repeat 5
122"repeat": func(count int, str string) string { return strings.Repeat(str, count) },
123// Deprecated: Use trimAll.
124"trimall": func(a, b string) string { return strings.Trim(b, a) },
125// Switch order so that "$foo" | trimall "$"
126"trimAll": func(a, b string) string { return strings.Trim(b, a) },
127"trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) },
128"trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) },
129// Switch order so that "foobar" | contains "foo"
130"contains": func(substr string, str string) bool { return strings.Contains(str, substr) },
131"hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) },
132"hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) },
133"quote": quote,
134"squote": squote,
135"cat": cat,
136"indent": indent,
137"nindent": nindent,
138"replace": replace,
139"plural": plural,
140"sha1sum": sha1sum,
141"sha256sum": sha256sum,
142"adler32sum": adler32sum,
143"toString": strval,
144
145// Wrap Atoi to stop errors.
146"atoi": func(a string) int { i, _ := strconv.Atoi(a); return i },
147"int64": toInt64,
148"int": toInt,
149"float64": toFloat64,
150"seq": seq,
151"toDecimal": toDecimal,
152
153//"gt": func(a, b int) bool {return a > b},
154//"gte": func(a, b int) bool {return a >= b},
155//"lt": func(a, b int) bool {return a < b},
156//"lte": func(a, b int) bool {return a <= b},
157
158// split "/" foo/bar returns map[int]string{0: foo, 1: bar}
159"split": split,
160"splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
161// splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu}
162"splitn": splitn,
163"toStrings": strslice,
164
165"until": until,
166"untilStep": untilStep,
167
168// VERY basic arithmetic.
169"add1": func(i interface{}) int64 { return toInt64(i) + 1 },
170"add": func(i ...interface{}) int64 {
171var a int64 = 0
172for _, b := range i {
173a += toInt64(b)
174}
175return a
176},
177"sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) },
178"div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) },
179"mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) },
180"mul": func(a interface{}, v ...interface{}) int64 {
181val := toInt64(a)
182for _, b := range v {
183val = val * toInt64(b)
184}
185return val
186},
187"randInt": func(min, max int) int { return rand.Intn(max-min) + min },
188"biggest": max,
189"max": max,
190"min": min,
191"maxf": maxf,
192"minf": minf,
193"ceil": ceil,
194"floor": floor,
195"round": round,
196
197// string slices. Note that we reverse the order b/c that's better
198// for template processing.
199"join": join,
200"sortAlpha": sortAlpha,
201
202// Defaults
203"default": dfault,
204"empty": empty,
205"coalesce": coalesce,
206"all": all,
207"any": any,
208"compact": compact,
209"mustCompact": mustCompact,
210"fromJson": fromJson,
211"toJson": toJson,
212"toPrettyJson": toPrettyJson,
213"toRawJson": toRawJson,
214"mustFromJson": mustFromJson,
215"mustToJson": mustToJson,
216"mustToPrettyJson": mustToPrettyJson,
217"mustToRawJson": mustToRawJson,
218"ternary": ternary,
219
220// Reflection
221"typeOf": typeOf,
222"typeIs": typeIs,
223"typeIsLike": typeIsLike,
224"kindOf": kindOf,
225"kindIs": kindIs,
226"deepEqual": reflect.DeepEqual,
227
228// OS:
229"env": os.Getenv,
230"expandenv": os.ExpandEnv,
231
232// Network:
233"getHostByName": getHostByName,
234
235// Paths:
236"base": path.Base,
237"dir": path.Dir,
238"clean": path.Clean,
239"ext": path.Ext,
240"isAbs": path.IsAbs,
241
242// Filepaths:
243"osBase": filepath.Base,
244"osClean": filepath.Clean,
245"osDir": filepath.Dir,
246"osExt": filepath.Ext,
247"osIsAbs": filepath.IsAbs,
248
249// Encoding:
250"b64enc": base64encode,
251"b64dec": base64decode,
252"b32enc": base32encode,
253"b32dec": base32decode,
254
255// Data Structures:
256"tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
257"list": list,
258"dict": dict,
259"get": get,
260"set": set,
261"unset": unset,
262"hasKey": hasKey,
263"pluck": pluck,
264"keys": keys,
265"pick": pick,
266"omit": omit,
267"values": values,
268
269"append": push, "push": push,
270"mustAppend": mustPush, "mustPush": mustPush,
271"prepend": prepend,
272"mustPrepend": mustPrepend,
273"first": first,
274"mustFirst": mustFirst,
275"rest": rest,
276"mustRest": mustRest,
277"last": last,
278"mustLast": mustLast,
279"initial": initial,
280"mustInitial": mustInitial,
281"reverse": reverse,
282"mustReverse": mustReverse,
283"uniq": uniq,
284"mustUniq": mustUniq,
285"without": without,
286"mustWithout": mustWithout,
287"has": has,
288"mustHas": mustHas,
289"slice": slice,
290"mustSlice": mustSlice,
291"concat": concat,
292"dig": dig,
293"chunk": chunk,
294"mustChunk": mustChunk,
295
296// Flow Control:
297"fail": func(msg string) (string, error) { return "", errors.New(msg) },
298
299// Regex
300"regexMatch": regexMatch,
301"mustRegexMatch": mustRegexMatch,
302"regexFindAll": regexFindAll,
303"mustRegexFindAll": mustRegexFindAll,
304"regexFind": regexFind,
305"mustRegexFind": mustRegexFind,
306"regexReplaceAll": regexReplaceAll,
307"mustRegexReplaceAll": mustRegexReplaceAll,
308"regexReplaceAllLiteral": regexReplaceAllLiteral,
309"mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral,
310"regexSplit": regexSplit,
311"mustRegexSplit": mustRegexSplit,
312"regexQuoteMeta": regexQuoteMeta,
313
314// URLs:
315"urlParse": urlParse,
316"urlJoin": urlJoin,
317}
318