binwiederhier 7 месяцев назад
Родитель
Сommit
2a468493f9

+ 7 - 7
util/sprig/date.go

@@ -10,19 +10,19 @@ import (
 // Date can be a `time.Time` or an `int, int32, int64`.
 // In the later case, it is treated as seconds since UNIX
 // epoch.
-func date(fmt string, date interface{}) string {
+func date(fmt string, date any) string {
 	return dateInZone(fmt, date, "Local")
 }
 
-func htmlDate(date interface{}) string {
+func htmlDate(date any) string {
 	return dateInZone("2006-01-02", date, "Local")
 }
 
-func htmlDateInZone(date interface{}, zone string) string {
+func htmlDateInZone(date any, zone string) string {
 	return dateInZone("2006-01-02", date, zone)
 }
 
-func dateInZone(fmt string, date interface{}, zone string) string {
+func dateInZone(fmt string, date any, zone string) string {
 	var t time.Time
 	switch date := date.(type) {
 	default:
@@ -63,7 +63,7 @@ func mustDateModify(fmt string, date time.Time) (time.Time, error) {
 	return date.Add(d), nil
 }
 
-func dateAgo(date interface{}) string {
+func dateAgo(date any) string {
 	var t time.Time
 
 	switch date := date.(type) {
@@ -81,7 +81,7 @@ func dateAgo(date interface{}) string {
 	return duration.String()
 }
 
-func duration(sec interface{}) string {
+func duration(sec any) string {
 	var n int64
 	switch value := sec.(type) {
 	default:
@@ -94,7 +94,7 @@ func duration(sec interface{}) string {
 	return (time.Duration(n) * time.Second).String()
 }
 
-func durationRound(duration interface{}) string {
+func durationRound(duration any) string {
 	var d time.Duration
 	switch duration := duration.(type) {
 	default:

+ 17 - 17
util/sprig/date_test.go

@@ -15,15 +15,15 @@ func TestHtmlDate(t *testing.T) {
 
 func TestAgo(t *testing.T) {
 	tpl := "{{ ago .Time }}"
-	if err := runtv(tpl, "2m5s", map[string]interface{}{"Time": time.Now().Add(-125 * time.Second)}); err != nil {
+	if err := runtv(tpl, "2m5s", map[string]any{"Time": time.Now().Add(-125 * time.Second)}); err != nil {
 		t.Error(err)
 	}
 
-	if err := runtv(tpl, "2h34m17s", map[string]interface{}{"Time": time.Now().Add(-(2*3600 + 34*60 + 17) * time.Second)}); err != nil {
+	if err := runtv(tpl, "2h34m17s", map[string]any{"Time": time.Now().Add(-(2*3600 + 34*60 + 17) * time.Second)}); err != nil {
 		t.Error(err)
 	}
 
-	if err := runtv(tpl, "-5s", map[string]interface{}{"Time": time.Now().Add(5 * time.Second)}); err != nil {
+	if err := runtv(tpl, "-5s", map[string]any{"Time": time.Now().Add(5 * time.Second)}); err != nil {
 		t.Error(err)
 	}
 }
@@ -42,7 +42,7 @@ func TestUnixEpoch(t *testing.T) {
 	}
 	tpl := `{{unixEpoch .Time}}`
 
-	if err = runtv(tpl, "1560458379", map[string]interface{}{"Time": tm}); err != nil {
+	if err = runtv(tpl, "1560458379", map[string]any{"Time": tm}); err != nil {
 		t.Error(err)
 	}
 }
@@ -55,66 +55,66 @@ func TestDateInZone(t *testing.T) {
 	tpl := `{{ date_in_zone "02 Jan 06 15:04 -0700" .Time "UTC" }}`
 
 	// Test time.Time input
-	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]interface{}{"Time": tm}); err != nil {
+	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]any{"Time": tm}); err != nil {
 		t.Error(err)
 	}
 
 	// Test pointer to time.Time input
-	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]interface{}{"Time": &tm}); err != nil {
+	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]any{"Time": &tm}); err != nil {
 		t.Error(err)
 	}
 
 	// Test no time input. This should be close enough to time.Now() we can test
 	loc, _ := time.LoadLocation("UTC")
-	if err = runtv(tpl, time.Now().In(loc).Format("02 Jan 06 15:04 -0700"), map[string]interface{}{"Time": ""}); err != nil {
+	if err = runtv(tpl, time.Now().In(loc).Format("02 Jan 06 15:04 -0700"), map[string]any{"Time": ""}); err != nil {
 		t.Error(err)
 	}
 
 	// Test unix timestamp as int64
-	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]interface{}{"Time": int64(1560458379)}); err != nil {
+	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]any{"Time": int64(1560458379)}); err != nil {
 		t.Error(err)
 	}
 
 	// Test unix timestamp as int32
-	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]interface{}{"Time": int32(1560458379)}); err != nil {
+	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]any{"Time": int32(1560458379)}); err != nil {
 		t.Error(err)
 	}
 
 	// Test unix timestamp as int
-	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]interface{}{"Time": int(1560458379)}); err != nil {
+	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]any{"Time": int(1560458379)}); err != nil {
 		t.Error(err)
 	}
 
 	// Test case of invalid timezone
 	tpl = `{{ date_in_zone "02 Jan 06 15:04 -0700" .Time "foobar" }}`
-	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]interface{}{"Time": tm}); err != nil {
+	if err = runtv(tpl, "13 Jun 19 20:39 +0000", map[string]any{"Time": tm}); err != nil {
 		t.Error(err)
 	}
 }
 
 func TestDuration(t *testing.T) {
 	tpl := "{{ duration .Secs }}"
-	if err := runtv(tpl, "1m1s", map[string]interface{}{"Secs": "61"}); err != nil {
+	if err := runtv(tpl, "1m1s", map[string]any{"Secs": "61"}); err != nil {
 		t.Error(err)
 	}
-	if err := runtv(tpl, "1h0m0s", map[string]interface{}{"Secs": "3600"}); err != nil {
+	if err := runtv(tpl, "1h0m0s", map[string]any{"Secs": "3600"}); err != nil {
 		t.Error(err)
 	}
 	// 1d2h3m4s but go is opinionated
-	if err := runtv(tpl, "26h3m4s", map[string]interface{}{"Secs": "93784"}); err != nil {
+	if err := runtv(tpl, "26h3m4s", map[string]any{"Secs": "93784"}); err != nil {
 		t.Error(err)
 	}
 }
 
 func TestDurationRound(t *testing.T) {
 	tpl := "{{ durationRound .Time }}"
-	if err := runtv(tpl, "2h", map[string]interface{}{"Time": "2h5s"}); err != nil {
+	if err := runtv(tpl, "2h", map[string]any{"Time": "2h5s"}); err != nil {
 		t.Error(err)
 	}
-	if err := runtv(tpl, "1d", map[string]interface{}{"Time": "24h5s"}); err != nil {
+	if err := runtv(tpl, "1d", map[string]any{"Time": "24h5s"}); err != nil {
 		t.Error(err)
 	}
-	if err := runtv(tpl, "3mo", map[string]interface{}{"Time": "2400h5s"}); err != nil {
+	if err := runtv(tpl, "3mo", map[string]any{"Time": "2400h5s"}); err != nil {
 		t.Error(err)
 	}
 }

+ 16 - 17
util/sprig/defaults.go

@@ -17,7 +17,7 @@ import (
 // Structs are never considered unset.
 //
 // For everything else, including pointers, a nil value is unset.
-func dfault(d interface{}, given ...interface{}) interface{} {
+func dfault(d any, given ...any) any {
 
 	if empty(given) || empty(given[0]) {
 		return d
@@ -26,7 +26,7 @@ func dfault(d interface{}, given ...interface{}) interface{} {
 }
 
 // empty returns true if the given value has the zero value for its type.
-func empty(given interface{}) bool {
+func empty(given any) bool {
 	g := reflect.ValueOf(given)
 	if !g.IsValid() {
 		return true
@@ -54,7 +54,7 @@ func empty(given interface{}) bool {
 }
 
 // coalesce returns the first non-empty value.
-func coalesce(v ...interface{}) interface{} {
+func coalesce(v ...any) any {
 	for _, val := range v {
 		if !empty(val) {
 			return val
@@ -65,7 +65,7 @@ func coalesce(v ...interface{}) interface{} {
 
 // all returns true if empty(x) is false for all values x in the list.
 // If the list is empty, return true.
-func all(v ...interface{}) bool {
+func all(v ...any) bool {
 	for _, val := range v {
 		if empty(val) {
 			return false
@@ -74,9 +74,9 @@ func all(v ...interface{}) bool {
 	return true
 }
 
-// any returns true if empty(x) is false for any x in the list.
+// anyNonEmpty returns true if empty(x) is false for anyNonEmpty x in the list.
 // If the list is empty, return false.
-func any(v ...interface{}) bool {
+func anyNonEmpty(v ...any) bool {
 	for _, val := range v {
 		if !empty(val) {
 			return true
@@ -86,25 +86,25 @@ func any(v ...interface{}) bool {
 }
 
 // fromJSON decodes JSON into a structured value, ignoring errors.
-func fromJSON(v string) interface{} {
+func fromJSON(v string) any {
 	output, _ := mustFromJSON(v)
 	return output
 }
 
 // mustFromJSON decodes JSON into a structured value, returning errors.
-func mustFromJSON(v string) (interface{}, error) {
-	var output interface{}
+func mustFromJSON(v string) (any, error) {
+	var output any
 	err := json.Unmarshal([]byte(v), &output)
 	return output, err
 }
 
 // toJSON encodes an item into a JSON string
-func toJSON(v interface{}) string {
+func toJSON(v any) string {
 	output, _ := json.Marshal(v)
 	return string(output)
 }
 
-func mustToJSON(v interface{}) (string, error) {
+func mustToJSON(v any) (string, error) {
 	output, err := json.Marshal(v)
 	if err != nil {
 		return "", err
@@ -113,12 +113,12 @@ func mustToJSON(v interface{}) (string, error) {
 }
 
 // toPrettyJSON encodes an item into a pretty (indented) JSON string
-func toPrettyJSON(v interface{}) string {
+func toPrettyJSON(v any) string {
 	output, _ := json.MarshalIndent(v, "", "  ")
 	return string(output)
 }
 
-func mustToPrettyJSON(v interface{}) (string, error) {
+func mustToPrettyJSON(v any) (string, error) {
 	output, err := json.MarshalIndent(v, "", "  ")
 	if err != nil {
 		return "", err
@@ -127,7 +127,7 @@ func mustToPrettyJSON(v interface{}) (string, error) {
 }
 
 // toRawJSON encodes an item into a JSON string with no escaping of HTML characters.
-func toRawJSON(v interface{}) string {
+func toRawJSON(v any) string {
 	output, err := mustToRawJSON(v)
 	if err != nil {
 		panic(err)
@@ -136,7 +136,7 @@ func toRawJSON(v interface{}) string {
 }
 
 // mustToRawJSON encodes an item into a JSON string with no escaping of HTML characters.
-func mustToRawJSON(v interface{}) (string, error) {
+func mustToRawJSON(v any) (string, error) {
 	buf := new(bytes.Buffer)
 	enc := json.NewEncoder(buf)
 	enc.SetEscapeHTML(false)
@@ -148,10 +148,9 @@ func mustToRawJSON(v interface{}) (string, error) {
 }
 
 // ternary returns the first value if the last value is true, otherwise returns the second value.
-func ternary(vt interface{}, vf interface{}, v bool) interface{} {
+func ternary(vt any, vf any, v bool) any {
 	if v {
 		return vt
 	}
-
 	return vf
 }

+ 8 - 8
util/sprig/defaults_test.go

@@ -53,7 +53,7 @@ func TestEmpty(t *testing.T) {
 		t.Error(err)
 	}
 
-	dict := map[string]interface{}{"top": map[string]interface{}{}}
+	dict := map[string]any{"top": map[string]any{}}
 	tpl = `{{if empty .top.NoSuchThing}}1{{else}}0{{end}}`
 	if err := runtv(tpl, "1", dict); err != nil {
 		t.Error(err)
@@ -77,7 +77,7 @@ func TestCoalesce(t *testing.T) {
 		assert.NoError(t, runt(tpl, expect))
 	}
 
-	dict := map[string]interface{}{"top": map[string]interface{}{}}
+	dict := map[string]any{"top": map[string]any{}}
 	tpl := `{{ coalesce .top.NoSuchThing .bottom .bottom.dollar "airplane"}}`
 	if err := runtv(tpl, "airplane", dict); err != nil {
 		t.Error(err)
@@ -97,7 +97,7 @@ func TestAll(t *testing.T) {
 		assert.NoError(t, runt(tpl, expect))
 	}
 
-	dict := map[string]interface{}{"top": map[string]interface{}{}}
+	dict := map[string]any{"top": map[string]any{}}
 	tpl := `{{ all .top.NoSuchThing .bottom .bottom.dollar "airplane"}}`
 	if err := runtv(tpl, "false", dict); err != nil {
 		t.Error(err)
@@ -117,7 +117,7 @@ func TestAny(t *testing.T) {
 		assert.NoError(t, runt(tpl, expect))
 	}
 
-	dict := map[string]interface{}{"top": map[string]interface{}{}}
+	dict := map[string]any{"top": map[string]any{}}
 	tpl := `{{ any .top.NoSuchThing .bottom .bottom.dollar "airplane"}}`
 	if err := runtv(tpl, "true", dict); err != nil {
 		t.Error(err)
@@ -125,7 +125,7 @@ func TestAny(t *testing.T) {
 }
 
 func TestFromJSON(t *testing.T) {
-	dict := map[string]interface{}{"Input": `{"foo": 55}`}
+	dict := map[string]any{"Input": `{"foo": 55}`}
 
 	tpl := `{{.Input | fromJSON}}`
 	expected := `map[foo:55]`
@@ -141,7 +141,7 @@ func TestFromJSON(t *testing.T) {
 }
 
 func TestToJSON(t *testing.T) {
-	dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42}}
+	dict := map[string]any{"Top": map[string]any{"bool": true, "string": "test", "number": 42}}
 
 	tpl := `{{.Top | toJSON}}`
 	expected := `{"bool":true,"number":42,"string":"test"}`
@@ -151,7 +151,7 @@ func TestToJSON(t *testing.T) {
 }
 
 func TestToPrettyJSON(t *testing.T) {
-	dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42}}
+	dict := map[string]any{"Top": map[string]any{"bool": true, "string": "test", "number": 42}}
 	tpl := `{{.Top | toPrettyJSON}}`
 	expected := `{
   "bool": true,
@@ -164,7 +164,7 @@ func TestToPrettyJSON(t *testing.T) {
 }
 
 func TestToRawJSON(t *testing.T) {
-	dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42, "html": "<HEAD>"}}
+	dict := map[string]any{"Top": map[string]any{"bool": true, "string": "test", "number": 42, "html": "<HEAD>"}}
 	tpl := `{{.Top | toRawJSON}}`
 	expected := `{"bool":true,"html":"<HEAD>","number":42,"string":"test"}`
 

+ 19 - 20
util/sprig/dict.go

@@ -1,29 +1,29 @@
 package sprig
 
-func get(d map[string]interface{}, key string) interface{} {
+func get(d map[string]any, key string) any {
 	if val, ok := d[key]; ok {
 		return val
 	}
 	return ""
 }
 
-func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} {
+func set(d map[string]any, key string, value any) map[string]any {
 	d[key] = value
 	return d
 }
 
-func unset(d map[string]interface{}, key string) map[string]interface{} {
+func unset(d map[string]any, key string) map[string]any {
 	delete(d, key)
 	return d
 }
 
-func hasKey(d map[string]interface{}, key string) bool {
+func hasKey(d map[string]any, key string) bool {
 	_, ok := d[key]
 	return ok
 }
 
-func pluck(key string, d ...map[string]interface{}) []interface{} {
-	res := []interface{}{}
+func pluck(key string, d ...map[string]any) []any {
+	var res []any
 	for _, dict := range d {
 		if val, ok := dict[key]; ok {
 			res = append(res, val)
@@ -32,7 +32,7 @@ func pluck(key string, d ...map[string]interface{}) []interface{} {
 	return res
 }
 
-func keys(dicts ...map[string]interface{}) []string {
+func keys(dicts ...map[string]any) []string {
 	k := []string{}
 	for _, dict := range dicts {
 		for key := range dict {
@@ -42,8 +42,8 @@ func keys(dicts ...map[string]interface{}) []string {
 	return k
 }
 
-func pick(dict map[string]interface{}, keys ...string) map[string]interface{} {
-	res := map[string]interface{}{}
+func pick(dict map[string]any, keys ...string) map[string]any {
+	res := map[string]any{}
 	for _, k := range keys {
 		if v, ok := dict[k]; ok {
 			res[k] = v
@@ -52,8 +52,8 @@ func pick(dict map[string]interface{}, keys ...string) map[string]interface{} {
 	return res
 }
 
-func omit(dict map[string]interface{}, keys ...string) map[string]interface{} {
-	res := map[string]interface{}{}
+func omit(dict map[string]any, keys ...string) map[string]any {
+	res := map[string]any{}
 
 	omit := make(map[string]bool, len(keys))
 	for _, k := range keys {
@@ -68,8 +68,8 @@ func omit(dict map[string]interface{}, keys ...string) map[string]interface{} {
 	return res
 }
 
-func dict(v ...interface{}) map[string]interface{} {
-	dict := map[string]interface{}{}
+func dict(v ...any) map[string]any {
+	dict := map[string]any{}
 	lenv := len(v)
 	for i := 0; i < lenv; i += 2 {
 		key := strval(v[i])
@@ -82,20 +82,19 @@ func dict(v ...interface{}) map[string]interface{} {
 	return dict
 }
 
-func values(dict map[string]interface{}) []interface{} {
-	values := []interface{}{}
+func values(dict map[string]any) []any {
+	var values []any
 	for _, value := range dict {
 		values = append(values, value)
 	}
-
 	return values
 }
 
-func dig(ps ...interface{}) (interface{}, error) {
+func dig(ps ...any) (any, error) {
 	if len(ps) < 3 {
 		panic("dig needs at least three arguments")
 	}
-	dict := ps[len(ps)-1].(map[string]interface{})
+	dict := ps[len(ps)-1].(map[string]any)
 	def := ps[len(ps)-2]
 	ks := make([]string, len(ps)-2)
 	for i := 0; i < len(ks); i++ {
@@ -105,7 +104,7 @@ func dig(ps ...interface{}) (interface{}, error) {
 	return digFromDict(dict, def, ks)
 }
 
-func digFromDict(dict map[string]interface{}, d interface{}, ks []string) (interface{}, error) {
+func digFromDict(dict map[string]any, d any, ks []string) (any, error) {
 	k, ns := ks[0], ks[1:]
 	step, has := dict[k]
 	if !has {
@@ -114,5 +113,5 @@ func digFromDict(dict map[string]interface{}, d interface{}, ks []string) (inter
 	if len(ns) == 0 {
 		return step, nil
 	}
-	return digFromDict(step.(map[string]interface{}), d, ns)
+	return digFromDict(step.(map[string]any), d, ns)
 }

+ 1 - 1
util/sprig/example_test.go

@@ -8,7 +8,7 @@ import (
 
 func Example() {
 	// Set up variables and template.
-	vars := map[string]interface{}{"Name": "  John Jacob Jingleheimer Schmidt "}
+	vars := map[string]any{"Name": "  John Jacob Jingleheimer Schmidt "}
 	tpl := `Hello {{.Name | trim | lower}}`
 
 	// Get the Sprig function map.

+ 17 - 57
util/sprig/functions.go

@@ -24,68 +24,26 @@ func FuncMap() template.FuncMap {
 	return HTMLFuncMap()
 }
 
-// HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions.
-func HermeticTxtFuncMap() ttemplate.FuncMap {
-	r := TxtFuncMap()
-	for _, name := range nonhermeticFunctions {
-		delete(r, name)
-	}
-	return r
-}
-
-// HermeticHTMLFuncMap returns an 'html/template'.Funcmap with only repeatable functions.
-func HermeticHTMLFuncMap() template.FuncMap {
-	r := HTMLFuncMap()
-	for _, name := range nonhermeticFunctions {
-		delete(r, name)
-	}
-	return r
-}
-
 // TxtFuncMap returns a 'text/template'.FuncMap
 func TxtFuncMap() ttemplate.FuncMap {
-	return ttemplate.FuncMap(GenericFuncMap())
+	return GenericFuncMap()
 }
 
 // HTMLFuncMap returns an 'html/template'.Funcmap
 func HTMLFuncMap() template.FuncMap {
-	return template.FuncMap(GenericFuncMap())
+	return GenericFuncMap()
 }
 
-// GenericFuncMap returns a copy of the basic function map as a map[string]interface{}.
-func GenericFuncMap() map[string]interface{} {
-	gfm := make(map[string]interface{}, len(genericMap))
+// GenericFuncMap returns a copy of the basic function map as a map[string]any.
+func GenericFuncMap() map[string]any {
+	gfm := make(map[string]any, len(genericMap))
 	for k, v := range genericMap {
 		gfm[k] = v
 	}
 	return gfm
 }
 
-// These functions are not guaranteed to evaluate to the same result for given input, because they
-// refer to the environment or global state.
-var nonhermeticFunctions = []string{
-	// Date functions
-	"date",
-	"date_in_zone",
-	"date_modify",
-	"now",
-	"htmlDate",
-	"htmlDateInZone",
-	"dateInZone",
-	"dateModify",
-
-	// Strings
-	"randAlphaNum",
-	"randAlpha",
-	"randAscii",
-	"randNumeric",
-	"randBytes",
-	"uuidv4",
-}
-
-var genericMap = map[string]interface{}{
-	"hello": func() string { return "Hello!" },
-
+var genericMap = map[string]any{
 	// Date functions
 	"ago":              dateAgo,
 	"date":             date,
@@ -157,18 +115,18 @@ var genericMap = map[string]interface{}{
 	"untilStep": untilStep,
 
 	// VERY basic arithmetic.
-	"add1": func(i interface{}) int64 { return toInt64(i) + 1 },
-	"add": func(i ...interface{}) int64 {
+	"add1": func(i any) int64 { return toInt64(i) + 1 },
+	"add": func(i ...any) int64 {
 		var a int64 = 0
 		for _, b := range i {
 			a += toInt64(b)
 		}
 		return a
 	},
-	"sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) },
-	"div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) },
-	"mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) },
-	"mul": func(a interface{}, v ...interface{}) int64 {
+	"sub": func(a, b any) int64 { return toInt64(a) - toInt64(b) },
+	"div": func(a, b any) int64 { return toInt64(a) / toInt64(b) },
+	"mod": func(a, b any) int64 { return toInt64(a) % toInt64(b) },
+	"mul": func(a any, v ...any) int64 {
 		val := toInt64(a)
 		for _, b := range v {
 			val = val * toInt64(b)
@@ -195,7 +153,7 @@ var genericMap = map[string]interface{}{
 	"empty":            empty,
 	"coalesce":         coalesce,
 	"all":              all,
-	"any":              any,
+	"any":              anyNonEmpty,
 	"compact":          compact,
 	"mustCompact":      mustCompact,
 	"fromJSON":         fromJSON,
@@ -250,8 +208,10 @@ var genericMap = map[string]interface{}{
 	"omit":   omit,
 	"values": values,
 
-	"append": push, "push": push,
-	"mustAppend": mustPush, "mustPush": mustPush,
+	"append":      push,
+	"push":        push,
+	"mustAppend":  mustPush,
+	"mustPush":    mustPush,
 	"prepend":     prepend,
 	"mustPrepend": mustPrepend,
 	"first":       first,

+ 2 - 2
util/sprig/functions_test.go

@@ -43,7 +43,7 @@ func runt(tpl, expect string) error {
 // runtv takes a template, and expected return, and values for substitution.
 //
 // It runs the template and verifies that the output is an exact match.
-func runtv(tpl, expect string, vars interface{}) error {
+func runtv(tpl, expect string, vars any) error {
 	fmap := TxtFuncMap()
 	t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
 	var b bytes.Buffer
@@ -58,7 +58,7 @@ func runtv(tpl, expect string, vars interface{}) error {
 }
 
 // runRaw runs a template with the given variables and returns the result.
-func runRaw(tpl string, vars interface{}) (string, error) {
+func runRaw(tpl string, vars any) (string, error) {
 	fmap := TxtFuncMap()
 	t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
 	var b bytes.Buffer

+ 48 - 48
util/sprig/list.go

@@ -8,14 +8,14 @@ import (
 )
 
 // Reflection is used in these functions so that slices and arrays of strings,
-// ints, and other types not implementing []interface{} can be worked with.
+// ints, and other types not implementing []any can be worked with.
 // For example, this is useful if you need to work on the output of regexs.
 
-func list(v ...interface{}) []interface{} {
+func list(v ...any) []any {
 	return v
 }
 
-func push(list interface{}, v interface{}) []interface{} {
+func push(list any, v any) []any {
 	l, err := mustPush(list, v)
 	if err != nil {
 		panic(err)
@@ -24,14 +24,14 @@ func push(list interface{}, v interface{}) []interface{} {
 	return l
 }
 
-func mustPush(list interface{}, v interface{}) ([]interface{}, error) {
+func mustPush(list any, v any) ([]any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
 		l2 := reflect.ValueOf(list)
 
 		l := l2.Len()
-		nl := make([]interface{}, l)
+		nl := make([]any, l)
 		for i := 0; i < l; i++ {
 			nl[i] = l2.Index(i).Interface()
 		}
@@ -43,7 +43,7 @@ func mustPush(list interface{}, v interface{}) ([]interface{}, error) {
 	}
 }
 
-func prepend(list interface{}, v interface{}) []interface{} {
+func prepend(list any, v any) []any {
 	l, err := mustPrepend(list, v)
 	if err != nil {
 		panic(err)
@@ -52,8 +52,8 @@ func prepend(list interface{}, v interface{}) []interface{} {
 	return l
 }
 
-func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) {
-	//return append([]interface{}{v}, list...)
+func mustPrepend(list any, v any) ([]any, error) {
+	//return append([]any{v}, list...)
 
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
@@ -61,19 +61,19 @@ func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) {
 		l2 := reflect.ValueOf(list)
 
 		l := l2.Len()
-		nl := make([]interface{}, l)
+		nl := make([]any, l)
 		for i := 0; i < l; i++ {
 			nl[i] = l2.Index(i).Interface()
 		}
 
-		return append([]interface{}{v}, nl...), nil
+		return append([]any{v}, nl...), nil
 
 	default:
 		return nil, fmt.Errorf("cannot prepend on type %s", tp)
 	}
 }
 
-func chunk(size int, list interface{}) [][]interface{} {
+func chunk(size int, list any) [][]any {
 	l, err := mustChunk(size, list)
 	if err != nil {
 		panic(err)
@@ -82,7 +82,7 @@ func chunk(size int, list interface{}) [][]interface{} {
 	return l
 }
 
-func mustChunk(size int, list interface{}) ([][]interface{}, error) {
+func mustChunk(size int, list any) ([][]any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
@@ -91,7 +91,7 @@ func mustChunk(size int, list interface{}) ([][]interface{}, error) {
 		l := l2.Len()
 
 		cs := int(math.Floor(float64(l-1)/float64(size)) + 1)
-		nl := make([][]interface{}, cs)
+		nl := make([][]any, cs)
 
 		for i := 0; i < cs; i++ {
 			clen := size
@@ -102,7 +102,7 @@ func mustChunk(size int, list interface{}) ([][]interface{}, error) {
 				}
 			}
 
-			nl[i] = make([]interface{}, clen)
+			nl[i] = make([]any, clen)
 
 			for j := 0; j < clen; j++ {
 				ix := i*size + j
@@ -117,7 +117,7 @@ func mustChunk(size int, list interface{}) ([][]interface{}, error) {
 	}
 }
 
-func last(list interface{}) interface{} {
+func last(list any) any {
 	l, err := mustLast(list)
 	if err != nil {
 		panic(err)
@@ -126,7 +126,7 @@ func last(list interface{}) interface{} {
 	return l
 }
 
-func mustLast(list interface{}) (interface{}, error) {
+func mustLast(list any) (any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
@@ -143,7 +143,7 @@ func mustLast(list interface{}) (interface{}, error) {
 	}
 }
 
-func first(list interface{}) interface{} {
+func first(list any) any {
 	l, err := mustFirst(list)
 	if err != nil {
 		panic(err)
@@ -152,7 +152,7 @@ func first(list interface{}) interface{} {
 	return l
 }
 
-func mustFirst(list interface{}) (interface{}, error) {
+func mustFirst(list any) (any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
@@ -169,7 +169,7 @@ func mustFirst(list interface{}) (interface{}, error) {
 	}
 }
 
-func rest(list interface{}) []interface{} {
+func rest(list any) []any {
 	l, err := mustRest(list)
 	if err != nil {
 		panic(err)
@@ -178,7 +178,7 @@ func rest(list interface{}) []interface{} {
 	return l
 }
 
-func mustRest(list interface{}) ([]interface{}, error) {
+func mustRest(list any) ([]any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
@@ -189,7 +189,7 @@ func mustRest(list interface{}) ([]interface{}, error) {
 			return nil, nil
 		}
 
-		nl := make([]interface{}, l-1)
+		nl := make([]any, l-1)
 		for i := 1; i < l; i++ {
 			nl[i-1] = l2.Index(i).Interface()
 		}
@@ -200,7 +200,7 @@ func mustRest(list interface{}) ([]interface{}, error) {
 	}
 }
 
-func initial(list interface{}) []interface{} {
+func initial(list any) []any {
 	l, err := mustInitial(list)
 	if err != nil {
 		panic(err)
@@ -209,7 +209,7 @@ func initial(list interface{}) []interface{} {
 	return l
 }
 
-func mustInitial(list interface{}) ([]interface{}, error) {
+func mustInitial(list any) ([]any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
@@ -220,7 +220,7 @@ func mustInitial(list interface{}) ([]interface{}, error) {
 			return nil, nil
 		}
 
-		nl := make([]interface{}, l-1)
+		nl := make([]any, l-1)
 		for i := 0; i < l-1; i++ {
 			nl[i] = l2.Index(i).Interface()
 		}
@@ -231,7 +231,7 @@ func mustInitial(list interface{}) ([]interface{}, error) {
 	}
 }
 
-func sortAlpha(list interface{}) []string {
+func sortAlpha(list any) []string {
 	k := reflect.Indirect(reflect.ValueOf(list)).Kind()
 	switch k {
 	case reflect.Slice, reflect.Array:
@@ -243,7 +243,7 @@ func sortAlpha(list interface{}) []string {
 	return []string{strval(list)}
 }
 
-func reverse(v interface{}) []interface{} {
+func reverse(v any) []any {
 	l, err := mustReverse(v)
 	if err != nil {
 		panic(err)
@@ -252,7 +252,7 @@ func reverse(v interface{}) []interface{} {
 	return l
 }
 
-func mustReverse(v interface{}) ([]interface{}, error) {
+func mustReverse(v any) ([]any, error) {
 	tp := reflect.TypeOf(v).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
@@ -260,7 +260,7 @@ func mustReverse(v interface{}) ([]interface{}, error) {
 
 		l := l2.Len()
 		// We do not sort in place because the incoming array should not be altered.
-		nl := make([]interface{}, l)
+		nl := make([]any, l)
 		for i := 0; i < l; i++ {
 			nl[l-i-1] = l2.Index(i).Interface()
 		}
@@ -271,7 +271,7 @@ func mustReverse(v interface{}) ([]interface{}, error) {
 	}
 }
 
-func compact(list interface{}) []interface{} {
+func compact(list any) []any {
 	l, err := mustCompact(list)
 	if err != nil {
 		panic(err)
@@ -280,15 +280,15 @@ func compact(list interface{}) []interface{} {
 	return l
 }
 
-func mustCompact(list interface{}) ([]interface{}, error) {
+func mustCompact(list any) ([]any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
 		l2 := reflect.ValueOf(list)
 
 		l := l2.Len()
-		nl := []interface{}{}
-		var item interface{}
+		nl := []any{}
+		var item any
 		for i := 0; i < l; i++ {
 			item = l2.Index(i).Interface()
 			if !empty(item) {
@@ -302,7 +302,7 @@ func mustCompact(list interface{}) ([]interface{}, error) {
 	}
 }
 
-func uniq(list interface{}) []interface{} {
+func uniq(list any) []any {
 	l, err := mustUniq(list)
 	if err != nil {
 		panic(err)
@@ -311,15 +311,15 @@ func uniq(list interface{}) []interface{} {
 	return l
 }
 
-func mustUniq(list interface{}) ([]interface{}, error) {
+func mustUniq(list any) ([]any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
 		l2 := reflect.ValueOf(list)
 
 		l := l2.Len()
-		dest := []interface{}{}
-		var item interface{}
+		dest := []any{}
+		var item any
 		for i := 0; i < l; i++ {
 			item = l2.Index(i).Interface()
 			if !inList(dest, item) {
@@ -333,7 +333,7 @@ func mustUniq(list interface{}) ([]interface{}, error) {
 	}
 }
 
-func inList(haystack []interface{}, needle interface{}) bool {
+func inList(haystack []any, needle any) bool {
 	for _, h := range haystack {
 		if reflect.DeepEqual(needle, h) {
 			return true
@@ -342,7 +342,7 @@ func inList(haystack []interface{}, needle interface{}) bool {
 	return false
 }
 
-func without(list interface{}, omit ...interface{}) []interface{} {
+func without(list any, omit ...any) []any {
 	l, err := mustWithout(list, omit...)
 	if err != nil {
 		panic(err)
@@ -351,15 +351,15 @@ func without(list interface{}, omit ...interface{}) []interface{} {
 	return l
 }
 
-func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) {
+func mustWithout(list any, omit ...any) ([]any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
 		l2 := reflect.ValueOf(list)
 
 		l := l2.Len()
-		res := []interface{}{}
-		var item interface{}
+		res := []any{}
+		var item any
 		for i := 0; i < l; i++ {
 			item = l2.Index(i).Interface()
 			if !inList(omit, item) {
@@ -373,7 +373,7 @@ func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) {
 	}
 }
 
-func has(needle interface{}, haystack interface{}) bool {
+func has(needle any, haystack any) bool {
 	l, err := mustHas(needle, haystack)
 	if err != nil {
 		panic(err)
@@ -382,7 +382,7 @@ func has(needle interface{}, haystack interface{}) bool {
 	return l
 }
 
-func mustHas(needle interface{}, haystack interface{}) (bool, error) {
+func mustHas(needle any, haystack any) (bool, error) {
 	if haystack == nil {
 		return false, nil
 	}
@@ -390,7 +390,7 @@ func mustHas(needle interface{}, haystack interface{}) (bool, error) {
 	switch tp {
 	case reflect.Slice, reflect.Array:
 		l2 := reflect.ValueOf(haystack)
-		var item interface{}
+		var item any
 		l := l2.Len()
 		for i := 0; i < l; i++ {
 			item = l2.Index(i).Interface()
@@ -410,7 +410,7 @@ func mustHas(needle interface{}, haystack interface{}) (bool, error) {
 // slice $list 0 3 -> list[0:3] = list[:3]
 // slice $list 3 5 -> list[3:5]
 // slice $list 3   -> list[3:5] = list[3:]
-func slice(list interface{}, indices ...interface{}) interface{} {
+func slice(list any, indices ...any) any {
 	l, err := mustSlice(list, indices...)
 	if err != nil {
 		panic(err)
@@ -419,7 +419,7 @@ func slice(list interface{}, indices ...interface{}) interface{} {
 	return l
 }
 
-func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) {
+func mustSlice(list any, indices ...any) (any, error) {
 	tp := reflect.TypeOf(list).Kind()
 	switch tp {
 	case reflect.Slice, reflect.Array:
@@ -446,8 +446,8 @@ func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) {
 	}
 }
 
-func concat(lists ...interface{}) interface{} {
-	var res []interface{}
+func concat(lists ...any) any {
+	var res []any
 	for _, list := range lists {
 		tp := reflect.TypeOf(list).Kind()
 		switch tp {

+ 11 - 11
util/sprig/numeric.go

@@ -9,7 +9,7 @@ import (
 )
 
 // toFloat64 converts 64-bit floats
-func toFloat64(v interface{}) float64 {
+func toFloat64(v any) float64 {
 	if str, ok := v.(string); ok {
 		iv, err := strconv.ParseFloat(str, 64)
 		if err != nil {
@@ -38,13 +38,13 @@ func toFloat64(v interface{}) float64 {
 	}
 }
 
-func toInt(v interface{}) int {
+func toInt(v any) int {
 	// It's not optimal. But I don't want duplicate toInt64 code.
 	return int(toInt64(v))
 }
 
 // toInt64 converts integer types to 64-bit integers
-func toInt64(v interface{}) int64 {
+func toInt64(v any) int64 {
 	if str, ok := v.(string); ok {
 		iv, err := strconv.ParseInt(str, 10, 64)
 		if err != nil {
@@ -78,7 +78,7 @@ func toInt64(v interface{}) int64 {
 	}
 }
 
-func max(a interface{}, i ...interface{}) int64 {
+func max(a any, i ...any) int64 {
 	aa := toInt64(a)
 	for _, b := range i {
 		bb := toInt64(b)
@@ -89,7 +89,7 @@ func max(a interface{}, i ...interface{}) int64 {
 	return aa
 }
 
-func maxf(a interface{}, i ...interface{}) float64 {
+func maxf(a any, i ...any) float64 {
 	aa := toFloat64(a)
 	for _, b := range i {
 		bb := toFloat64(b)
@@ -98,7 +98,7 @@ func maxf(a interface{}, i ...interface{}) float64 {
 	return aa
 }
 
-func min(a interface{}, i ...interface{}) int64 {
+func min(a any, i ...any) int64 {
 	aa := toInt64(a)
 	for _, b := range i {
 		bb := toInt64(b)
@@ -109,7 +109,7 @@ func min(a interface{}, i ...interface{}) int64 {
 	return aa
 }
 
-func minf(a interface{}, i ...interface{}) float64 {
+func minf(a any, i ...any) float64 {
 	aa := toFloat64(a)
 	for _, b := range i {
 		bb := toFloat64(b)
@@ -148,17 +148,17 @@ func untilStep(start, stop, step int) []int {
 	return v
 }
 
-func floor(a interface{}) float64 {
+func floor(a any) float64 {
 	aa := toFloat64(a)
 	return math.Floor(aa)
 }
 
-func ceil(a interface{}) float64 {
+func ceil(a any) float64 {
 	aa := toFloat64(a)
 	return math.Ceil(aa)
 }
 
-func round(a interface{}, p int, rOpt ...float64) float64 {
+func round(a any, p int, rOpt ...float64) float64 {
 	roundOn := .5
 	if len(rOpt) > 0 {
 		roundOn = rOpt[0]
@@ -179,7 +179,7 @@ func round(a interface{}, p int, rOpt ...float64) float64 {
 }
 
 // converts unix octal to decimal
-func toDecimal(v interface{}) int64 {
+func toDecimal(v any) int64 {
 	result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
 	if err != nil {
 		return 0

+ 1 - 1
util/sprig/numeric_test.go

@@ -192,7 +192,7 @@ func TestToInt(t *testing.T) {
 }
 
 func TestToDecimal(t *testing.T) {
-	tests := map[interface{}]int64{
+	tests := map[any]int64{
 		"777": 511,
 		777:   511,
 		770:   504,

+ 5 - 5
util/sprig/reflect.go

@@ -6,23 +6,23 @@ import (
 )
 
 // typeIs returns true if the src is the type named in target.
-func typeIs(target string, src interface{}) bool {
+func typeIs(target string, src any) bool {
 	return target == typeOf(src)
 }
 
-func typeIsLike(target string, src interface{}) bool {
+func typeIsLike(target string, src any) bool {
 	t := typeOf(src)
 	return target == t || "*"+target == t
 }
 
-func typeOf(src interface{}) string {
+func typeOf(src any) string {
 	return fmt.Sprintf("%T", src)
 }
 
-func kindIs(target string, src interface{}) bool {
+func kindIs(target string, src any) bool {
 	return target == kindOf(src)
 }
 
-func kindOf(src interface{}) string {
+func kindOf(src any) string {
 	return reflect.ValueOf(src).Kind().String()
 }

+ 9 - 9
util/sprig/strings.go

@@ -33,7 +33,7 @@ func base32decode(v string) string {
 	return string(data)
 }
 
-func quote(str ...interface{}) string {
+func quote(str ...any) string {
 	out := make([]string, 0, len(str))
 	for _, s := range str {
 		if s != nil {
@@ -43,7 +43,7 @@ func quote(str ...interface{}) string {
 	return strings.Join(out, " ")
 }
 
-func squote(str ...interface{}) string {
+func squote(str ...any) string {
 	out := make([]string, 0, len(str))
 	for _, s := range str {
 		if s != nil {
@@ -53,7 +53,7 @@ func squote(str ...interface{}) string {
 	return strings.Join(out, " ")
 }
 
-func cat(v ...interface{}) string {
+func cat(v ...any) string {
 	v = removeNilElements(v)
 	r := strings.TrimSpace(strings.Repeat("%v ", len(v)))
 	return fmt.Sprintf(r, v...)
@@ -79,11 +79,11 @@ func plural(one, many string, count int) string {
 	return many
 }
 
-func strslice(v interface{}) []string {
+func strslice(v any) []string {
 	switch v := v.(type) {
 	case []string:
 		return v
-	case []interface{}:
+	case []any:
 		b := make([]string, 0, len(v))
 		for _, s := range v {
 			if s != nil {
@@ -114,8 +114,8 @@ func strslice(v interface{}) []string {
 	}
 }
 
-func removeNilElements(v []interface{}) []interface{} {
-	newSlice := make([]interface{}, 0, len(v))
+func removeNilElements(v []any) []any {
+	newSlice := make([]any, 0, len(v))
 	for _, i := range v {
 		if i != nil {
 			newSlice = append(newSlice, i)
@@ -124,7 +124,7 @@ func removeNilElements(v []interface{}) []interface{} {
 	return newSlice
 }
 
-func strval(v interface{}) string {
+func strval(v any) string {
 	switch v := v.(type) {
 	case string:
 		return v
@@ -149,7 +149,7 @@ func trunc(c int, s string) string {
 	return s
 }
 
-func join(sep string, v interface{}) string {
+func join(sep string, v any) string {
 	return strings.Join(strslice(v), sep)
 }
 

+ 8 - 8
util/sprig/strings_test.go

@@ -56,7 +56,7 @@ func TestQuote(t *testing.T) {
 		t.Error(err)
 	}
 	tpl = `{{ .value | quote }}`
-	values := map[string]interface{}{"value": nil}
+	values := map[string]any{"value": nil}
 	if err := runtv(tpl, ``, values); err != nil {
 		t.Error(err)
 	}
@@ -71,7 +71,7 @@ func TestSquote(t *testing.T) {
 		t.Error(err)
 	}
 	tpl = `{{ .value | squote }}`
-	values := map[string]interface{}{"value": nil}
+	values := map[string]any{"value": nil}
 	if err := runtv(tpl, ``, values); err != nil {
 		t.Error(err)
 	}
@@ -128,7 +128,7 @@ func TestToStrings(t *testing.T) {
 	tpl := `{{ $s := list 1 2 3 | toStrings }}{{ index $s 1 | kindOf }}`
 	assert.NoError(t, runt(tpl, "string"))
 	tpl = `{{ list 1 .value 2 | toStrings }}`
-	values := map[string]interface{}{"value": nil}
+	values := map[string]any{"value": nil}
 	if err := runtv(tpl, `[1 2]`, values); err != nil {
 		t.Error(err)
 	}
@@ -137,10 +137,10 @@ func TestToStrings(t *testing.T) {
 func TestJoin(t *testing.T) {
 	assert.NoError(t, runt(`{{ tuple "a" "b" "c" | join "-" }}`, "a-b-c"))
 	assert.NoError(t, runt(`{{ tuple 1 2 3 | join "-" }}`, "1-2-3"))
-	assert.NoError(t, runtv(`{{ join "-" .V }}`, "a-b-c", map[string]interface{}{"V": []string{"a", "b", "c"}}))
-	assert.NoError(t, runtv(`{{ join "-" .V }}`, "abc", map[string]interface{}{"V": "abc"}))
-	assert.NoError(t, runtv(`{{ join "-" .V }}`, "1-2-3", map[string]interface{}{"V": []int{1, 2, 3}}))
-	assert.NoError(t, runtv(`{{ join "-" .value }}`, "1-2", map[string]interface{}{"value": []interface{}{"1", nil, "2"}}))
+	assert.NoError(t, runtv(`{{ join "-" .V }}`, "a-b-c", map[string]any{"V": []string{"a", "b", "c"}}))
+	assert.NoError(t, runtv(`{{ join "-" .V }}`, "abc", map[string]any{"V": "abc"}))
+	assert.NoError(t, runtv(`{{ join "-" .V }}`, "1-2-3", map[string]any{"V": []int{1, 2, 3}}))
+	assert.NoError(t, runtv(`{{ join "-" .value }}`, "1-2", map[string]any{"value": []any{"1", nil, "2"}}))
 }
 
 func TestSortAlpha(t *testing.T) {
@@ -194,7 +194,7 @@ func TestCat(t *testing.T) {
 		t.Error(err)
 	}
 	tpl = `{{ .value | cat "a" "b"}}`
-	values := map[string]interface{}{"value": nil}
+	values := map[string]any{"value": nil}
 	if err := runtv(tpl, "a b", values); err != nil {
 		t.Error(err)
 	}

+ 4 - 4
util/sprig/url.go

@@ -6,7 +6,7 @@ import (
 	"reflect"
 )
 
-func dictGetOrEmpty(dict map[string]interface{}, key string) string {
+func dictGetOrEmpty(dict map[string]any, key string) string {
 	value, ok := dict[key]
 	if !ok {
 		return ""
@@ -19,8 +19,8 @@ func dictGetOrEmpty(dict map[string]interface{}, key string) string {
 }
 
 // parses given URL to return dict object
-func urlParse(v string) map[string]interface{} {
-	dict := map[string]interface{}{}
+func urlParse(v string) map[string]any {
+	dict := map[string]any{}
 	parsedURL, err := url.Parse(v)
 	if err != nil {
 		panic(fmt.Sprintf("unable to parse url: %s", err))
@@ -42,7 +42,7 @@ func urlParse(v string) map[string]interface{} {
 }
 
 // join given dict to URL string
-func urlJoin(d map[string]interface{}) string {
+func urlJoin(d map[string]any) string {
 	resURL := url.URL{
 		Scheme:   dictGetOrEmpty(d, "scheme"),
 		Host:     dictGetOrEmpty(d, "host"),

+ 1 - 1
util/sprig/url_test.go

@@ -6,7 +6,7 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-var urlTests = map[string]map[string]interface{}{
+var urlTests = map[string]map[string]any{
 	"proto://auth@host:80/path?query#fragment": {
 		"fragment": "fragment",
 		"host":     "host:80",