functions.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package sprig
  2. import (
  3. "errors"
  4. "html/template"
  5. "math/rand"
  6. "path"
  7. "path/filepath"
  8. "reflect"
  9. "strconv"
  10. "strings"
  11. ttemplate "text/template"
  12. "time"
  13. "golang.org/x/text/cases"
  14. )
  15. // FuncMap produces the function map.
  16. //
  17. // Use this to pass the functions into the template engine:
  18. //
  19. // tpl := template.New("foo").Funcs(sprig.FuncMap()))
  20. func FuncMap() template.FuncMap {
  21. return HTMLFuncMap()
  22. }
  23. // TxtFuncMap returns a 'text/template'.FuncMap
  24. func TxtFuncMap() ttemplate.FuncMap {
  25. return GenericFuncMap()
  26. }
  27. // HTMLFuncMap returns an 'html/template'.Funcmap
  28. func HTMLFuncMap() template.FuncMap {
  29. return GenericFuncMap()
  30. }
  31. // GenericFuncMap returns a copy of the basic function map as a map[string]any.
  32. func GenericFuncMap() map[string]any {
  33. gfm := make(map[string]any, len(genericMap))
  34. for k, v := range genericMap {
  35. gfm[k] = v
  36. }
  37. return gfm
  38. }
  39. var genericMap = map[string]any{
  40. // Date functions
  41. "ago": dateAgo,
  42. "date": date,
  43. "date_in_zone": dateInZone,
  44. "date_modify": dateModify,
  45. "dateInZone": dateInZone,
  46. "dateModify": dateModify,
  47. "duration": duration,
  48. "durationRound": durationRound,
  49. "htmlDate": htmlDate,
  50. "htmlDateInZone": htmlDateInZone,
  51. "must_date_modify": mustDateModify,
  52. "mustDateModify": mustDateModify,
  53. "mustToDate": mustToDate,
  54. "now": time.Now,
  55. "toDate": toDate,
  56. "unixEpoch": unixEpoch,
  57. // Strings
  58. "trunc": trunc,
  59. "trim": strings.TrimSpace,
  60. "upper": strings.ToUpper,
  61. "lower": strings.ToLower,
  62. "title": cases.Title,
  63. "substr": substring,
  64. // Switch order so that "foo" | repeat 5
  65. "repeat": func(count int, str string) string { return strings.Repeat(str, count) },
  66. // Deprecated: Use trimAll.
  67. "trimall": func(a, b string) string { return strings.Trim(b, a) },
  68. // Switch order so that "$foo" | trimall "$"
  69. "trimAll": func(a, b string) string { return strings.Trim(b, a) },
  70. "trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) },
  71. "trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) },
  72. // Switch order so that "foobar" | contains "foo"
  73. "contains": func(substr string, str string) bool { return strings.Contains(str, substr) },
  74. "hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) },
  75. "hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) },
  76. "quote": quote,
  77. "squote": squote,
  78. "cat": cat,
  79. "indent": indent,
  80. "nindent": nindent,
  81. "replace": replace,
  82. "plural": plural,
  83. "sha1sum": sha1sum,
  84. "sha256sum": sha256sum,
  85. "sha512sum": sha512sum,
  86. "adler32sum": adler32sum,
  87. "toString": strval,
  88. // Wrap Atoi to stop errors.
  89. "atoi": func(a string) int { i, _ := strconv.Atoi(a); return i },
  90. "seq": seq,
  91. "toDecimal": toDecimal,
  92. //"gt": func(a, b int) bool {return a > b},
  93. //"gte": func(a, b int) bool {return a >= b},
  94. //"lt": func(a, b int) bool {return a < b},
  95. //"lte": func(a, b int) bool {return a <= b},
  96. // split "/" foo/bar returns map[int]string{0: foo, 1: bar}
  97. "split": split,
  98. "splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
  99. // splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu}
  100. "splitn": splitn,
  101. "toStrings": strslice,
  102. "until": until,
  103. "untilStep": untilStep,
  104. // VERY basic arithmetic.
  105. "add1": func(i any) int64 { return toInt64(i) + 1 },
  106. "add": func(i ...any) int64 {
  107. var a int64 = 0
  108. for _, b := range i {
  109. a += toInt64(b)
  110. }
  111. return a
  112. },
  113. "sub": func(a, b any) int64 { return toInt64(a) - toInt64(b) },
  114. "div": func(a, b any) int64 { return toInt64(a) / toInt64(b) },
  115. "mod": func(a, b any) int64 { return toInt64(a) % toInt64(b) },
  116. "mul": func(a any, v ...any) int64 {
  117. val := toInt64(a)
  118. for _, b := range v {
  119. val = val * toInt64(b)
  120. }
  121. return val
  122. },
  123. "randInt": func(min, max int) int { return rand.Intn(max-min) + min },
  124. "biggest": max,
  125. "max": max,
  126. "min": min,
  127. "maxf": maxf,
  128. "minf": minf,
  129. "ceil": ceil,
  130. "floor": floor,
  131. "round": round,
  132. // string slices. Note that we reverse the order b/c that's better
  133. // for template processing.
  134. "join": join,
  135. "sortAlpha": sortAlpha,
  136. // Defaults
  137. "default": dfault,
  138. "empty": empty,
  139. "coalesce": coalesce,
  140. "all": all,
  141. "any": anyNonEmpty,
  142. "compact": compact,
  143. "mustCompact": mustCompact,
  144. "fromJSON": fromJSON,
  145. "toJSON": toJSON,
  146. "toPrettyJSON": toPrettyJSON,
  147. "toRawJSON": toRawJSON,
  148. "mustFromJSON": mustFromJSON,
  149. "mustToJSON": mustToJSON,
  150. "mustToPrettyJSON": mustToPrettyJSON,
  151. "mustToRawJSON": mustToRawJSON,
  152. "ternary": ternary,
  153. // Reflection
  154. "typeOf": typeOf,
  155. "typeIs": typeIs,
  156. "typeIsLike": typeIsLike,
  157. "kindOf": kindOf,
  158. "kindIs": kindIs,
  159. "deepEqual": reflect.DeepEqual,
  160. // Paths:
  161. "base": path.Base,
  162. "dir": path.Dir,
  163. "clean": path.Clean,
  164. "ext": path.Ext,
  165. "isAbs": path.IsAbs,
  166. // Filepaths:
  167. "osBase": filepath.Base,
  168. "osClean": filepath.Clean,
  169. "osDir": filepath.Dir,
  170. "osExt": filepath.Ext,
  171. "osIsAbs": filepath.IsAbs,
  172. // Encoding:
  173. "b64enc": base64encode,
  174. "b64dec": base64decode,
  175. "b32enc": base32encode,
  176. "b32dec": base32decode,
  177. // Data Structures:
  178. "tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
  179. "list": list,
  180. "dict": dict,
  181. "get": get,
  182. "set": set,
  183. "unset": unset,
  184. "hasKey": hasKey,
  185. "pluck": pluck,
  186. "keys": keys,
  187. "pick": pick,
  188. "omit": omit,
  189. "values": values,
  190. "append": push,
  191. "push": push,
  192. "mustAppend": mustPush,
  193. "mustPush": mustPush,
  194. "prepend": prepend,
  195. "mustPrepend": mustPrepend,
  196. "first": first,
  197. "mustFirst": mustFirst,
  198. "rest": rest,
  199. "mustRest": mustRest,
  200. "last": last,
  201. "mustLast": mustLast,
  202. "initial": initial,
  203. "mustInitial": mustInitial,
  204. "reverse": reverse,
  205. "mustReverse": mustReverse,
  206. "uniq": uniq,
  207. "mustUniq": mustUniq,
  208. "without": without,
  209. "mustWithout": mustWithout,
  210. "has": has,
  211. "mustHas": mustHas,
  212. "slice": slice,
  213. "mustSlice": mustSlice,
  214. "concat": concat,
  215. "dig": dig,
  216. "chunk": chunk,
  217. "mustChunk": mustChunk,
  218. // UUIDs:
  219. "uuidv4": uuidv4,
  220. // Flow Control:
  221. "fail": func(msg string) (string, error) { return "", errors.New(msg) },
  222. // Regex
  223. "regexMatch": regexMatch,
  224. "mustRegexMatch": mustRegexMatch,
  225. "regexFindAll": regexFindAll,
  226. "mustRegexFindAll": mustRegexFindAll,
  227. "regexFind": regexFind,
  228. "mustRegexFind": mustRegexFind,
  229. "regexReplaceAll": regexReplaceAll,
  230. "mustRegexReplaceAll": mustRegexReplaceAll,
  231. "regexReplaceAllLiteral": regexReplaceAllLiteral,
  232. "mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral,
  233. "regexSplit": regexSplit,
  234. "mustRegexSplit": mustRegexSplit,
  235. "regexQuoteMeta": regexQuoteMeta,
  236. // URLs:
  237. "urlParse": urlParse,
  238. "urlJoin": urlJoin,
  239. }