From 5eceffb188240d80488ac786c509482d575973a4 Mon Sep 17 00:00:00 2001 From: Patryk Zdunowski Date: Thu, 5 Jan 2023 11:08:04 +0100 Subject: [PATCH 1/2] feat(accept-sting): impl --- .gitignore | 1 + main.go | 13 +++- templatefile.go | 142 ------------------------------------------- templatefile_test.go | 35 ----------- 4 files changed, 11 insertions(+), 180 deletions(-) delete mode 100644 templatefile.go delete mode 100644 templatefile_test.go diff --git a/.gitignore b/.gitignore index ad09205..1dcb43a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /templatefile +.idea diff --git a/main.go b/main.go index 751b682..5ce34de 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/TypedSoftware/templatefile/templatefile" "io/ioutil" "os" ) @@ -32,10 +33,16 @@ func main() { argv[1] = os.Stdin.Name() } - vars, err := ioutil.ReadFile(argv[1]) - pp(err) + var vars []byte + if _, err := os.Stat(argv[1]); err == nil { + out, err := ioutil.ReadFile(argv[1]) + pp(err) + vars = out + } else { + vars = []byte(argv[1]) + } - out, err := templatefile(".", argv[0], string(vars)) + out, err := templatefile.New(".", argv[0], string(vars)) pp(err) _, err = fmt.Fprintf(os.Stdout, "%s", out) diff --git a/templatefile.go b/templatefile.go deleted file mode 100644 index a9ecb45..0000000 --- a/templatefile.go +++ /dev/null @@ -1,142 +0,0 @@ -package main - -import ( - "github.com/hashicorp/hcl/v2/ext/tryfunc" - "github.com/hashicorp/terraform/lang/funcs" - ctyyaml "github.com/zclconf/go-cty-yaml" - "github.com/zclconf/go-cty/cty" - "github.com/zclconf/go-cty/cty/function" - "github.com/zclconf/go-cty/cty/function/stdlib" -) - -func templatefile(baseDir string, path string, vars string) (string, error) { - terraformFunctions := map[string]function.Function{ - "abs": stdlib.AbsoluteFunc, - "abspath": funcs.AbsPathFunc, - "alltrue": funcs.AllTrueFunc, - "anytrue": funcs.AnyTrueFunc, - "basename": funcs.BasenameFunc, - "base64decode": funcs.Base64DecodeFunc, - "base64encode": funcs.Base64EncodeFunc, - "base64gzip": funcs.Base64GzipFunc, - "base64sha256": funcs.Base64Sha256Func, - "base64sha512": funcs.Base64Sha512Func, - "bcrypt": funcs.BcryptFunc, - "can": tryfunc.CanFunc, - "ceil": stdlib.CeilFunc, - "chomp": stdlib.ChompFunc, - "cidrhost": funcs.CidrHostFunc, - "cidrnetmask": funcs.CidrNetmaskFunc, - "cidrsubnet": funcs.CidrSubnetFunc, - "cidrsubnets": funcs.CidrSubnetsFunc, - "coalesce": funcs.CoalesceFunc, - "coalescelist": stdlib.CoalesceListFunc, - "compact": stdlib.CompactFunc, - "concat": stdlib.ConcatFunc, - "contains": stdlib.ContainsFunc, - "csvdecode": stdlib.CSVDecodeFunc, - "dirname": funcs.DirnameFunc, - "distinct": stdlib.DistinctFunc, - "element": stdlib.ElementFunc, - "chunklist": stdlib.ChunklistFunc, - "file": funcs.MakeFileFunc(baseDir, false), - "fileexists": funcs.MakeFileExistsFunc(baseDir), - "fileset": funcs.MakeFileSetFunc(baseDir), - "filebase64": funcs.MakeFileFunc(baseDir, true), - "filebase64sha256": funcs.MakeFileBase64Sha256Func(baseDir), - "filebase64sha512": funcs.MakeFileBase64Sha512Func(baseDir), - "filemd5": funcs.MakeFileMd5Func(baseDir), - "filesha1": funcs.MakeFileSha1Func(baseDir), - "filesha256": funcs.MakeFileSha256Func(baseDir), - "filesha512": funcs.MakeFileSha512Func(baseDir), - "flatten": stdlib.FlattenFunc, - "floor": stdlib.FloorFunc, - "format": stdlib.FormatFunc, - "formatdate": stdlib.FormatDateFunc, - "formatlist": stdlib.FormatListFunc, - "indent": stdlib.IndentFunc, - "index": funcs.IndexFunc, // stdlib.IndexFunc is not compatible - "join": stdlib.JoinFunc, - "jsondecode": stdlib.JSONDecodeFunc, - "jsonencode": stdlib.JSONEncodeFunc, - "keys": stdlib.KeysFunc, - "length": funcs.LengthFunc, - "list": funcs.ListFunc, - "log": stdlib.LogFunc, - "lookup": funcs.LookupFunc, - "lower": stdlib.LowerFunc, - "map": funcs.MapFunc, - "matchkeys": funcs.MatchkeysFunc, - "max": stdlib.MaxFunc, - "md5": funcs.Md5Func, - "merge": stdlib.MergeFunc, - "min": stdlib.MinFunc, - "parseint": stdlib.ParseIntFunc, - "pathexpand": funcs.PathExpandFunc, - "pow": stdlib.PowFunc, - "range": stdlib.RangeFunc, - "regex": stdlib.RegexFunc, - "regexall": stdlib.RegexAllFunc, - "replace": funcs.ReplaceFunc, - "reverse": stdlib.ReverseListFunc, - "rsadecrypt": funcs.RsaDecryptFunc, - "setintersection": stdlib.SetIntersectionFunc, - "setproduct": stdlib.SetProductFunc, - "setsubtract": stdlib.SetSubtractFunc, - "setunion": stdlib.SetUnionFunc, - "sha1": funcs.Sha1Func, - "sha256": funcs.Sha256Func, - "sha512": funcs.Sha512Func, - "signum": stdlib.SignumFunc, - "slice": stdlib.SliceFunc, - "sort": stdlib.SortFunc, - "split": stdlib.SplitFunc, - "strrev": stdlib.ReverseFunc, - "substr": stdlib.SubstrFunc, - "sum": funcs.SumFunc, - "textdecodebase64": funcs.TextDecodeBase64Func, - "textencodebase64": funcs.TextEncodeBase64Func, - "timestamp": funcs.TimestampFunc, - "timeadd": stdlib.TimeAddFunc, - "title": stdlib.TitleFunc, - "tostring": funcs.MakeToFunc(cty.String), - "tonumber": funcs.MakeToFunc(cty.Number), - "tobool": funcs.MakeToFunc(cty.Bool), - "toset": funcs.MakeToFunc(cty.Set(cty.DynamicPseudoType)), - "tolist": funcs.MakeToFunc(cty.List(cty.DynamicPseudoType)), - "tomap": funcs.MakeToFunc(cty.Map(cty.DynamicPseudoType)), - "transpose": funcs.TransposeFunc, - "trim": stdlib.TrimFunc, - "trimprefix": stdlib.TrimPrefixFunc, - "trimspace": stdlib.TrimSpaceFunc, - "trimsuffix": stdlib.TrimSuffixFunc, - "try": tryfunc.TryFunc, - "upper": stdlib.UpperFunc, - "urlencode": funcs.URLEncodeFunc, - "uuid": funcs.UUIDFunc, - "uuidv5": funcs.UUIDV5Func, - "values": stdlib.ValuesFunc, - "yamldecode": ctyyaml.YAMLDecodeFunc, - "yamlencode": ctyyaml.YAMLEncodeFunc, - "zipmap": stdlib.ZipmapFunc, - } - - f := funcs.MakeTemplateFileFunc(baseDir, func() map[string]function.Function { - return terraformFunctions - }) - data, err := ctyyaml.YAMLDecodeFunc.Call([]cty.Value{cty.StringVal(vars)}) - if err != nil { - return "", err - } - - args := []cty.Value{ - cty.StringVal(path), - data, - } - res, err := f.Call(args) - if err != nil { - return "", err - } - - return res.AsString(), err -} diff --git a/templatefile_test.go b/templatefile_test.go deleted file mode 100644 index 07f1f45..0000000 --- a/templatefile_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "io/ioutil" - "path/filepath" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestTemplatefile(t *testing.T) { - matches, err := filepath.Glob("testdata/*.tmpl") - require.Nil(t, err) - - for _, match := range matches { - t.Run(match, func(t *testing.T) { - expected, err := ioutil.ReadFile(strings.TrimSuffix(match, filepath.Ext(match)) + ".txt") - require.Nil(t, err) - - vars, err := ioutil.ReadFile(strings.TrimSuffix(match, filepath.Ext(match)) + ".yml") - require.Nil(t, err) - - actual, err := templatefile(".", match, string(vars)) - require.Nil(t, err) - require.EqualValues(t, expected, actual) - }) - } -} - -func TestTemplatefileRecursive(t *testing.T) { - _, err := templatefile(".", "testdata/recursive.tmpl-fails", "k: v") - require.NotNil(t, err) - require.Contains(t, err.Error(), "Call to unknown function") -} From 9239f8a91d8df9497df8286f2742dea2212d2a64 Mon Sep 17 00:00:00 2001 From: Patryk Zdunowski Date: Thu, 5 Jan 2023 11:09:34 +0100 Subject: [PATCH 2/2] feat(accept-sting): revert templatefile --- main.go | 3 +- templatefile.go | 142 +++++++++++++++++++++++++++++++++++++++++++ templatefile_test.go | 35 +++++++++++ 3 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 templatefile.go create mode 100644 templatefile_test.go diff --git a/main.go b/main.go index 5ce34de..259d45a 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "github.com/TypedSoftware/templatefile/templatefile" "io/ioutil" "os" ) @@ -42,7 +41,7 @@ func main() { vars = []byte(argv[1]) } - out, err := templatefile.New(".", argv[0], string(vars)) + out, err := templatefile(".", argv[0], string(vars)) pp(err) _, err = fmt.Fprintf(os.Stdout, "%s", out) diff --git a/templatefile.go b/templatefile.go new file mode 100644 index 0000000..a9ecb45 --- /dev/null +++ b/templatefile.go @@ -0,0 +1,142 @@ +package main + +import ( + "github.com/hashicorp/hcl/v2/ext/tryfunc" + "github.com/hashicorp/terraform/lang/funcs" + ctyyaml "github.com/zclconf/go-cty-yaml" + "github.com/zclconf/go-cty/cty" + "github.com/zclconf/go-cty/cty/function" + "github.com/zclconf/go-cty/cty/function/stdlib" +) + +func templatefile(baseDir string, path string, vars string) (string, error) { + terraformFunctions := map[string]function.Function{ + "abs": stdlib.AbsoluteFunc, + "abspath": funcs.AbsPathFunc, + "alltrue": funcs.AllTrueFunc, + "anytrue": funcs.AnyTrueFunc, + "basename": funcs.BasenameFunc, + "base64decode": funcs.Base64DecodeFunc, + "base64encode": funcs.Base64EncodeFunc, + "base64gzip": funcs.Base64GzipFunc, + "base64sha256": funcs.Base64Sha256Func, + "base64sha512": funcs.Base64Sha512Func, + "bcrypt": funcs.BcryptFunc, + "can": tryfunc.CanFunc, + "ceil": stdlib.CeilFunc, + "chomp": stdlib.ChompFunc, + "cidrhost": funcs.CidrHostFunc, + "cidrnetmask": funcs.CidrNetmaskFunc, + "cidrsubnet": funcs.CidrSubnetFunc, + "cidrsubnets": funcs.CidrSubnetsFunc, + "coalesce": funcs.CoalesceFunc, + "coalescelist": stdlib.CoalesceListFunc, + "compact": stdlib.CompactFunc, + "concat": stdlib.ConcatFunc, + "contains": stdlib.ContainsFunc, + "csvdecode": stdlib.CSVDecodeFunc, + "dirname": funcs.DirnameFunc, + "distinct": stdlib.DistinctFunc, + "element": stdlib.ElementFunc, + "chunklist": stdlib.ChunklistFunc, + "file": funcs.MakeFileFunc(baseDir, false), + "fileexists": funcs.MakeFileExistsFunc(baseDir), + "fileset": funcs.MakeFileSetFunc(baseDir), + "filebase64": funcs.MakeFileFunc(baseDir, true), + "filebase64sha256": funcs.MakeFileBase64Sha256Func(baseDir), + "filebase64sha512": funcs.MakeFileBase64Sha512Func(baseDir), + "filemd5": funcs.MakeFileMd5Func(baseDir), + "filesha1": funcs.MakeFileSha1Func(baseDir), + "filesha256": funcs.MakeFileSha256Func(baseDir), + "filesha512": funcs.MakeFileSha512Func(baseDir), + "flatten": stdlib.FlattenFunc, + "floor": stdlib.FloorFunc, + "format": stdlib.FormatFunc, + "formatdate": stdlib.FormatDateFunc, + "formatlist": stdlib.FormatListFunc, + "indent": stdlib.IndentFunc, + "index": funcs.IndexFunc, // stdlib.IndexFunc is not compatible + "join": stdlib.JoinFunc, + "jsondecode": stdlib.JSONDecodeFunc, + "jsonencode": stdlib.JSONEncodeFunc, + "keys": stdlib.KeysFunc, + "length": funcs.LengthFunc, + "list": funcs.ListFunc, + "log": stdlib.LogFunc, + "lookup": funcs.LookupFunc, + "lower": stdlib.LowerFunc, + "map": funcs.MapFunc, + "matchkeys": funcs.MatchkeysFunc, + "max": stdlib.MaxFunc, + "md5": funcs.Md5Func, + "merge": stdlib.MergeFunc, + "min": stdlib.MinFunc, + "parseint": stdlib.ParseIntFunc, + "pathexpand": funcs.PathExpandFunc, + "pow": stdlib.PowFunc, + "range": stdlib.RangeFunc, + "regex": stdlib.RegexFunc, + "regexall": stdlib.RegexAllFunc, + "replace": funcs.ReplaceFunc, + "reverse": stdlib.ReverseListFunc, + "rsadecrypt": funcs.RsaDecryptFunc, + "setintersection": stdlib.SetIntersectionFunc, + "setproduct": stdlib.SetProductFunc, + "setsubtract": stdlib.SetSubtractFunc, + "setunion": stdlib.SetUnionFunc, + "sha1": funcs.Sha1Func, + "sha256": funcs.Sha256Func, + "sha512": funcs.Sha512Func, + "signum": stdlib.SignumFunc, + "slice": stdlib.SliceFunc, + "sort": stdlib.SortFunc, + "split": stdlib.SplitFunc, + "strrev": stdlib.ReverseFunc, + "substr": stdlib.SubstrFunc, + "sum": funcs.SumFunc, + "textdecodebase64": funcs.TextDecodeBase64Func, + "textencodebase64": funcs.TextEncodeBase64Func, + "timestamp": funcs.TimestampFunc, + "timeadd": stdlib.TimeAddFunc, + "title": stdlib.TitleFunc, + "tostring": funcs.MakeToFunc(cty.String), + "tonumber": funcs.MakeToFunc(cty.Number), + "tobool": funcs.MakeToFunc(cty.Bool), + "toset": funcs.MakeToFunc(cty.Set(cty.DynamicPseudoType)), + "tolist": funcs.MakeToFunc(cty.List(cty.DynamicPseudoType)), + "tomap": funcs.MakeToFunc(cty.Map(cty.DynamicPseudoType)), + "transpose": funcs.TransposeFunc, + "trim": stdlib.TrimFunc, + "trimprefix": stdlib.TrimPrefixFunc, + "trimspace": stdlib.TrimSpaceFunc, + "trimsuffix": stdlib.TrimSuffixFunc, + "try": tryfunc.TryFunc, + "upper": stdlib.UpperFunc, + "urlencode": funcs.URLEncodeFunc, + "uuid": funcs.UUIDFunc, + "uuidv5": funcs.UUIDV5Func, + "values": stdlib.ValuesFunc, + "yamldecode": ctyyaml.YAMLDecodeFunc, + "yamlencode": ctyyaml.YAMLEncodeFunc, + "zipmap": stdlib.ZipmapFunc, + } + + f := funcs.MakeTemplateFileFunc(baseDir, func() map[string]function.Function { + return terraformFunctions + }) + data, err := ctyyaml.YAMLDecodeFunc.Call([]cty.Value{cty.StringVal(vars)}) + if err != nil { + return "", err + } + + args := []cty.Value{ + cty.StringVal(path), + data, + } + res, err := f.Call(args) + if err != nil { + return "", err + } + + return res.AsString(), err +} diff --git a/templatefile_test.go b/templatefile_test.go new file mode 100644 index 0000000..07f1f45 --- /dev/null +++ b/templatefile_test.go @@ -0,0 +1,35 @@ +package main + +import ( + "io/ioutil" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTemplatefile(t *testing.T) { + matches, err := filepath.Glob("testdata/*.tmpl") + require.Nil(t, err) + + for _, match := range matches { + t.Run(match, func(t *testing.T) { + expected, err := ioutil.ReadFile(strings.TrimSuffix(match, filepath.Ext(match)) + ".txt") + require.Nil(t, err) + + vars, err := ioutil.ReadFile(strings.TrimSuffix(match, filepath.Ext(match)) + ".yml") + require.Nil(t, err) + + actual, err := templatefile(".", match, string(vars)) + require.Nil(t, err) + require.EqualValues(t, expected, actual) + }) + } +} + +func TestTemplatefileRecursive(t *testing.T) { + _, err := templatefile(".", "testdata/recursive.tmpl-fails", "k: v") + require.NotNil(t, err) + require.Contains(t, err.Error(), "Call to unknown function") +}