From 0ddcbaf18fddf81c957a8fdc5236d5ff40545287 Mon Sep 17 00:00:00 2001 From: Martin Grogan Date: Tue, 26 Nov 2024 12:05:05 -0500 Subject: [PATCH] hcl2template: add strcontains function The strcontains function check if a sub string is a indeed a subset of a given string. hcl2template: add strcontains function The strcontains function check if a sub string is a indeed a subset of a given string. --- hcl2template/function/strcontains.go | 32 ++++++++++ hcl2template/function/strcontains_test.go | 76 +++++++++++++++++++++++ hcl2template/functions.go | 1 + 3 files changed, 109 insertions(+) create mode 100644 hcl2template/function/strcontains.go create mode 100644 hcl2template/function/strcontains_test.go diff --git a/hcl2template/function/strcontains.go b/hcl2template/function/strcontains.go new file mode 100644 index 000000000..7ad962c9e --- /dev/null +++ b/hcl2template/function/strcontains.go @@ -0,0 +1,32 @@ +package function + +import ( + "strings" + + "github.com/zclconf/go-cty/cty" + "github.com/zclconf/go-cty/cty/function" +) + +var StrContains = function.New(&function.Spec{ + Params: []function.Parameter{ + { + Name: "str", + Type: cty.String, + }, + { + Name: "substr", + Type: cty.String, + }, + }, + Type: function.StaticReturnType(cty.Bool), + Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { + str := args[0].AsString() + substr := args[1].AsString() + + if strings.Contains(str, substr) { + return cty.True, nil + } + + return cty.False, nil + }, +}) diff --git a/hcl2template/function/strcontains_test.go b/hcl2template/function/strcontains_test.go new file mode 100644 index 000000000..3d1f46a20 --- /dev/null +++ b/hcl2template/function/strcontains_test.go @@ -0,0 +1,76 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package function + +import ( + "fmt" + "testing" + + "github.com/zclconf/go-cty/cty" +) + +func TestStrContains(t *testing.T) { + tests := []struct { + String cty.Value + Substr cty.Value + Want cty.Value + ExpectErr bool + }{ + { + cty.StringVal("hello"), + cty.StringVal("hel"), + cty.BoolVal(true), + false, + }, + { + cty.StringVal("hello"), + cty.StringVal("lo"), + cty.BoolVal(true), + false, + }, + { + cty.StringVal("hello1"), + cty.StringVal("1"), + cty.BoolVal(true), + false, + }, + { + cty.StringVal("hello1"), + cty.StringVal("heo"), + cty.BoolVal(false), + false, + }, + { + cty.StringVal("hello1"), + cty.NumberIntVal(1), + cty.UnknownVal(cty.Bool), + true, + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf("includes(%#v, %#v)", test.String, test.Substr), func(t *testing.T) { + got, err := StrContains.Call([]cty.Value{ + test.String, + test.Substr, + }) + + if test.ExpectErr && err == nil { + t.Fatal("succeeded; want error") + } + + if test.ExpectErr && err != nil { + return + } + + if !test.ExpectErr && err != nil { + t.Fatalf("unexpected error: %s", err) + } + + if !got.RawEquals(test.Want) { + t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) + } + }) + } +} diff --git a/hcl2template/functions.go b/hcl2template/functions.go index 3736d12f5..4e832cf93 100644 --- a/hcl2template/functions.go +++ b/hcl2template/functions.go @@ -103,6 +103,7 @@ func Functions(basedir string) map[string]function.Function { "slice": stdlib.SliceFunc, "sort": stdlib.SortFunc, "split": stdlib.SplitFunc, + "strcontains": pkrfunction.StrContains, "strrev": stdlib.ReverseFunc, "substr": stdlib.SubstrFunc, "textdecodebase64": TextDecodeBase64Func,