diff --git a/data/data.go b/data/data.go index adf6b2b73..d2fc32fb8 100644 --- a/data/data.go +++ b/data/data.go @@ -12,6 +12,9 @@ import ( "io" "strings" + "cuelang.org/go/cue" + "cuelang.org/go/cue/cuecontext" + "cuelang.org/go/cue/format" "github.com/Shopify/ejson" ejsonJson "github.com/Shopify/ejson/json" "github.com/hairyhenderson/gomplate/v4/conv" @@ -442,3 +445,63 @@ func ToTOML(in interface{}) (string, error) { } return buf.String(), nil } + +// CUE - Unmarshal a CUE expression into the appropriate type +func CUE(in string) (interface{}, error) { + cuectx := cuecontext.New() + val := cuectx.CompileString(in) + + if val.Err() != nil { + return nil, fmt.Errorf("unable to process CUE: %w", val.Err()) + } + + switch val.Kind() { + case cue.StructKind: + out := map[string]interface{}{} + err := val.Decode(&out) + return out, err + case cue.ListKind: + out := []interface{}{} + err := val.Decode(&out) + return out, err + case cue.BytesKind: + out := []byte{} + err := val.Decode(&out) + return out, err + case cue.StringKind: + out := "" + err := val.Decode(&out) + return out, err + case cue.IntKind: + out := 0 + err := val.Decode(&out) + return out, err + case cue.NumberKind, cue.FloatKind: + out := 0.0 + err := val.Decode(&out) + return out, err + case cue.BoolKind: + out := false + err := val.Decode(&out) + return out, err + case cue.NullKind: + return nil, nil + default: + return nil, fmt.Errorf("unsupported CUE type %q", val.Kind()) + } +} + +func ToCUE(in interface{}) (string, error) { + cuectx := cuecontext.New() + v := cuectx.Encode(in) + if v.Err() != nil { + return "", v.Err() + } + + bs, err := format.Node(v.Syntax()) + if err != nil { + return "", err + } + + return string(bs), nil +} diff --git a/data/data_test.go b/data/data_test.go index 4bfea43ef..ac65768b1 100644 --- a/data/data_test.go +++ b/data/data_test.go @@ -659,3 +659,120 @@ func TestStringifyYAMLMapMapKeys(t *testing.T) { assert.EqualValues(t, c.want, c.input) } } + +func TestCUE(t *testing.T) { + in := `package foo +import "regexp" +matches: regexp.FindSubmatch(#"^([^:]*):(\d+)$"#, "localhost:443") +one: 1 +two: 2 +// A field using quotes. +"two-and-a-half": 2.5 +list: [ 1, 2, 3 ] +` + + expected := map[string]interface{}{ + "matches": []interface{}{ + "localhost:443", + "localhost", + "443", + }, + "one": 1, + "two": 2, + "two-and-a-half": 2.5, + "list": []interface{}{1, 2, 3}, + } + + out, err := CUE(in) + require.NoError(t, err) + assert.EqualValues(t, expected, out) + + out, err = CUE(`[1,2,3]`) + require.NoError(t, err) + assert.EqualValues(t, []interface{}{1, 2, 3}, out) + + out, err = CUE(`"hello world"`) + require.NoError(t, err) + assert.EqualValues(t, "hello world", out) + + out, err = CUE(`true`) + require.NoError(t, err) + assert.EqualValues(t, true, out) + + out, err = CUE(`'\x00\x01\x02\x03\x04'`) + require.NoError(t, err) + assert.EqualValues(t, []byte{0, 1, 2, 3, 4}, out) + + out, err = CUE(`42`) + require.NoError(t, err) + assert.EqualValues(t, 42, out) + + out, err = CUE(`42.0`) + require.NoError(t, err) + assert.EqualValues(t, 42.0, out) + + out, err = CUE(`null`) + require.NoError(t, err) + assert.EqualValues(t, nil, out) + + _, err = CUE(`>=0 & <=7 & >=3 & <=10`) + require.Error(t, err) +} + +func TestToCUE(t *testing.T) { + in := map[string]interface{}{ + "matches": []interface{}{ + "localhost:443", + "localhost", + "443", + }, + "one": 1, + "two": 2, + "two-and-a-half": 2.5, + "list": []interface{}{1, 2, 3}, + } + + expected := `{ + "two-and-a-half": 2.5 + list: [1, 2, 3] + two: 2 + one: 1 + matches: ["localhost:443", "localhost", "443"] +}` + + out, err := ToCUE(in) + require.NoError(t, err) + assert.EqualValues(t, expected, out) + + out, err = ToCUE([]interface{}{1, 2, 3}) + require.NoError(t, err) + assert.EqualValues(t, `[1, 2, 3]`, out) + + out, err = ToCUE("hello world") + require.NoError(t, err) + assert.EqualValues(t, `"hello world"`, out) + + out, err = ToCUE(true) + require.NoError(t, err) + assert.EqualValues(t, `true`, out) + + out, err = ToCUE([]byte{0, 1, 2, 3, 4}) + require.NoError(t, err) + assert.EqualValues(t, `'\x00\x01\x02\x03\x04'`, out) + + out, err = ToCUE(42) + require.NoError(t, err) + assert.EqualValues(t, `42`, out) + + out, err = ToCUE(42.0) + require.NoError(t, err) + assert.EqualValues(t, `42.0`, out) + + out, err = ToCUE(nil) + require.NoError(t, err) + assert.EqualValues(t, `null`, out) + + out, err = ToCUE(struct{}{}) + require.NoError(t, err) + assert.EqualValues(t, `{}`, out) +} diff --git a/data/datasource.go b/data/datasource.go index d16fe09a9..fe3f08777 100644 --- a/data/datasource.go +++ b/data/datasource.go @@ -32,6 +32,7 @@ func init() { regExtension(".csv", csvMimetype) regExtension(".toml", tomlMimetype) regExtension(".env", envMimetype) + regExtension(".cue", cueMimetype) } // registerReaders registers the source-reader functions @@ -348,6 +349,8 @@ func parseData(mimeType, s string) (out interface{}, err error) { out, err = dotEnv(s) case textMimetype: out = s + case cueMimetype: + out, err = CUE(s) default: return nil, fmt.Errorf("datasources of type %s not yet supported", mimeType) } diff --git a/data/mimetypes.go b/data/mimetypes.go index bdc12ad4c..1f2432199 100644 --- a/data/mimetypes.go +++ b/data/mimetypes.go @@ -8,6 +8,7 @@ const ( tomlMimetype = "application/toml" yamlMimetype = "application/yaml" envMimetype = "application/x-env" + cueMimetype = "application/cue" ) // mimeTypeAliases defines a mapping for non-canonical mime types that are diff --git a/docs-src/content/functions/data.yml b/docs-src/content/functions/data.yml index 89f9f1a4e..82f9e3852 100644 --- a/docs-src/content/functions/data.yml +++ b/docs-src/content/functions/data.yml @@ -369,6 +369,27 @@ funcs: Go COBOL ``` + - name: data.CUE + alias: cue + description: | + Converts a [CUE](https://cuelang.org/) document into an object. Any type + of CUE document is supported. This can be used to access properties of CUE + documents. + + Note that the `import` statement is not yet supported, and will result in + an error (except for importing builtin packages). + pipeline: true + arguments: + - name: input + required: true + description: the CUE document to parse + examples: + - | + $ gomplate -i '{{ $t := `data: { + hello: "world" + }` -}} + Hello {{ (cue $t).data.hello }}' + Hello world - name: data.ToJSON alias: toJSON description: | @@ -492,3 +513,28 @@ funcs: 1,2 3,4 ``` + - name: data.ToCUE + alias: toCUE + description: | + Converts an object to a [CUE](https://cuelang.org/) document in canonical + format. The input object can be of any type. + + This is roughly equivalent to using the `cue export --out=cue ` + command to convert from other formats to CUE. + pipeline: true + arguments: + - name: input + required: true + description: the object to marshal as a CUE document + examples: + - | + $ gomplate -i '{{ `{"foo":"bar"}` | data.JSON | data.ToCUE }}' + { + foo: "bar" + } + - | + $ gomplate -i '{{ toCUE "hello world" }}' + "hello world" + - | + $ gomplate -i '{{ coll.Slice 1 "two" true | data.ToCUE }}' + [1, "two", true] diff --git a/funcs/data.go b/funcs/data.go index c706bc325..bb47988b8 100644 --- a/funcs/data.go +++ b/funcs/data.go @@ -48,11 +48,13 @@ func CreateDataFuncs(ctx context.Context, f["csv"] = ns.CSV f["csvByRow"] = ns.CSVByRow f["csvByColumn"] = ns.CSVByColumn + f["cue"] = ns.CUE f["toJSON"] = ns.ToJSON f["toJSONPretty"] = ns.ToJSONPretty f["toYAML"] = ns.ToYAML f["toTOML"] = ns.ToTOML f["toCSV"] = ns.ToCSV + f["toCUE"] = ns.ToCUE return f } @@ -101,11 +103,21 @@ func (f *DataFuncs) CSVByColumn(args ...string) (cols map[string][]string, err e return data.CSVByColumn(args...) } +// CUE - +func (f *DataFuncs) CUE(in interface{}) (interface{}, error) { + return data.CUE(conv.ToString(in)) +} + // ToCSV - func (f *DataFuncs) ToCSV(args ...interface{}) (string, error) { return data.ToCSV(args...) } +// ToCUE - +func (f *DataFuncs) ToCUE(in interface{}) (string, error) { + return data.ToCUE(in) +} + // ToJSON - func (f *DataFuncs) ToJSON(in interface{}) (string, error) { return data.ToJSON(in) diff --git a/go.mod b/go.mod index 9cc4de499..d6784ce3a 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/hairyhenderson/gomplate/v4 go 1.20 require ( + cuelang.org/go v0.6.0-alpha.2 github.com/Masterminds/goutils v1.1.1 github.com/Masterminds/semver v1.5.0 github.com/Shopify/ejson v1.4.0 @@ -73,6 +74,7 @@ require ( github.com/aws/smithy-go v1.13.5 // indirect github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/cloudflare/circl v1.3.3 // indirect + github.com/cockroachdb/apd/v3 v3.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -109,6 +111,7 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect diff --git a/go.sum b/go.sum index 5edfd7afa..1657516b5 100644 --- a/go.sum +++ b/go.sum @@ -416,6 +416,8 @@ code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= contrib.go.opencensus.io/exporter/stackdriver v0.13.14/go.mod h1:5pSSGY0Bhuk7waTHuDf4aQ8D2DrhgETRo9fy6k3Xlzc= contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= +cuelang.org/go v0.6.0-alpha.2 h1:7HRnexrOVLT+isLFeFEsZ/DfnZ/28+Wwn0bBU4dowIA= +cuelang.org/go v0.6.0-alpha.2/go.mod h1:PTRw1+DrzCDmGIHM00bLxnwGEYlblJ5Lql4jgprAh2c= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= @@ -693,6 +695,8 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/apd/v3 v3.2.0 h1:79kHCn4tO0VGu3W0WujYrMjBDk8a2H4KEUYcXf7whcg= +github.com/cockroachdb/apd/v3 v3.2.0/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= @@ -877,6 +881,7 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/proto v1.10.0 h1:pDGyFRVV5RvV+nkBK9iy3q67FBy9Xa7vwrOTE+g5aGw= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -1005,6 +1010,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-quicktest/qt v1.100.0 h1:I7iSLgIwNp0E0UnSvKJzs7ig0jg/Iq83zsZjtQNW7jY= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -1480,6 +1486,7 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/linode/linodego v1.4.0/go.mod h1:PVsRxSlOiJyvG4/scTszpmZDTdgS+to3X6eS8pRrWI8= github.com/linode/linodego v1.12.0/go.mod h1:NJlzvlNtdMRRkXb0oN6UWzUkj6t+IBsyveHgZ5Ppjyk= @@ -1551,6 +1558,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -1582,6 +1590,8 @@ github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3P github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto= +github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -1757,6 +1767,7 @@ github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0ua github.com/prometheus/prometheus v0.35.0/go.mod h1:7HaLx5kEPKJ0GDgbODG0fZgXbQ8K/XjZNJXQmbmgQlY= github.com/prometheus/prometheus v0.42.0/go.mod h1:Pfqb/MLnnR2KK+0vchiaH39jXxvLMBk+3lnIGP4N7Vk= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4= github.com/rakyll/embedmd v0.0.0-20171029212350-c8060a0752a2/go.mod h1:7jOTMgqac46PZcF54q6l2hkLEG8op93fZu61KmxWDV4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -1765,8 +1776,8 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= diff --git a/internal/tests/integration/datasources_file_test.go b/internal/tests/integration/datasources_file_test.go index 67d6b8958..9af8503bf 100644 --- a/internal/tests/integration/datasources_file_test.go +++ b/internal/tests/integration/datasources_file_test.go @@ -30,6 +30,24 @@ FOO.BAR = "values can be double-quoted, and shell\nescapes are supported" BAZ = "variable expansion: ${FOO}" QUX='single quotes ignore $variables' +`, + "test.cue": `package core + +import "regexp" + +matches: regexp.FindSubmatch(#"^([^:]*):(\d+)$"#, "localhost:443") + +one: 1 +two: 2 + +// A field using quotes. +"two-and-a-half": 2.5 + +list: [ + 1, + 2, + 3, +] `, }), fs.WithDir("sortorder", fs.WithFiles(map[string]string{ @@ -120,7 +138,7 @@ func TestDatasources_File(t *testing.T) { o, e, err = cmd(t, "-d", "dir="+tmpDir.Path()+"/", "-i", `{{ range (ds "dir") }}{{ . }} {{ end }}`).run() - assertSuccess(t, o, e, err, "ajsonfile config.json config.yml config2.yml encrypted.json foo.csv sortorder test.env ") + assertSuccess(t, o, e, err, "ajsonfile config.json config.yml config2.yml encrypted.json foo.csv sortorder test.cue test.env ") o, e, err = cmd(t, "-d", "enc="+tmpDir.Join("encrypted.json"), "-i", `{{ (ds "enc").password }}`). @@ -149,6 +167,14 @@ func TestDatasources_File(t *testing.T) { "FOO.BAR": "values can be double-quoted, and shell\nescapes are supported", "QUX": "single quotes ignore $variables" }`) + + o, e, err = cmd(t, "-d", "cuedata="+tmpDir.Join("test.cue"), + "-i", `{{ (ds "cuedata").matches | data.ToJSONPretty " " }}`).run() + assertSuccess(t, o, e, err, `[ + "localhost:443", + "localhost", + "443" +]`) } func TestDatasources_File_Directory(t *testing.T) {