From 5edec76b62d532dbb0e67a427b43377277660ad2 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Mon, 22 Jul 2024 21:52:20 -0500 Subject: [PATCH] feat: jsonnet Signed-off-by: jolheiser --- cfg.go | 25 +++++++++---- cfg_test.go | 77 ++++++++++++++++++++++++++++------------- cmd/cfg/main.go | 2 +- example/example.jsonnet | 16 +++++++++ go.mod | 4 ++- go.mod.sri | 2 +- go.sum | 19 +++++----- 7 files changed, 102 insertions(+), 43 deletions(-) create mode 100644 example/example.jsonnet diff --git a/cfg.go b/cfg.go index 53b30f5..cde1d7a 100644 --- a/cfg.go +++ b/cfg.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/google/go-jsonnet" "github.com/pelletier/go-toml/v2" "github.com/philandstuff/dhall-golang/v6" "github.com/sblinch/kdl-go" @@ -17,13 +18,14 @@ import ( type Encoding string const ( - JSON Encoding = "json" - JSONC Encoding = "jsonc" - YAML Encoding = "yaml" - TOML Encoding = "toml" - NIX Encoding = "nix" - DHALL Encoding = "dhall" - KDL Encoding = "kdl" + JSON Encoding = "json" + JSONC Encoding = "jsonc" + JSONNET Encoding = "jsonnet" + YAML Encoding = "yaml" + TOML Encoding = "toml" + NIX Encoding = "nix" + DHALL Encoding = "dhall" + KDL Encoding = "kdl" ) // Marshal takes data and encodes for an [Encoding] @@ -43,6 +45,8 @@ func ParseEncoding(s string) (Encoding, error) { return JSON, nil case "jsonc": return JSONC, nil + case "jsonnet": + return JSONNET, nil case "yaml": return YAML, nil case "toml": @@ -88,6 +92,13 @@ func Unmarshal(e Encoding, data []byte, v any) error { return err } return json.Unmarshal(b, v) + case JSONNET: + vm := jsonnet.MakeVM() + data, err := vm.EvaluateAnonymousSnippet("cfg", string(data)) + if err != nil { + return err + } + return json.Unmarshal([]byte(data), v) case YAML: return yaml.Unmarshal(data, v) case TOML: diff --git a/cfg_test.go b/cfg_test.go index c6b055f..afdd375 100644 --- a/cfg_test.go +++ b/cfg_test.go @@ -21,21 +21,6 @@ type TestSubData struct { } func TestEncoding(t *testing.T) { - assert := is.New(t) - - // Starting with dhall since it can't be encoded - dhall := ` - { - Foo = "bar" - , Baz = True - , Bux = 10 - , Qux = { - Honk = "bonk" - , Chonk = 50 - , Gonk = False - } - } - ` final := TestData{ Foo: "bar", Baz: true, @@ -47,21 +32,65 @@ func TestEncoding(t *testing.T) { }, } + // Each decode-only [Encoding] + tt := []struct { + Name string + Input string + Encoding Encoding + }{ + { + Name: "dhall", + Input: ` + { + Foo = "bar" + , Baz = True + , Bux = 10 + , Qux = { + Honk = "bonk" + , Chonk = 50 + , Gonk = False + } + } + `, + Encoding: DHALL, + }, { + Name: "jsonnet", + Input: ` + { + Foo: "bar", + Baz: true, + Bux: 10, + Qux: { + Honk: "bonk", + Chonk: 50, + Gonk: false, + } + } + `, + Encoding: JSONNET, + }, + } + encoders := []Encoding{JSON, JSONC, YAML, TOML, KDL} // Only test nix if it's available if nixfig.Nix != "" { encoders = append(encoders, NIX) } - var data TestData - err := DHALL.Unmarshal([]byte(dhall), &data) - assert.NoErr(err) // Should be able to unmarshal dhall + for _, tc := range tt { + t.Run(tc.Name, func(t *testing.T) { + assert := is.New(t) + var data TestData + err := tc.Encoding.Unmarshal([]byte(tc.Input), &data) + assert.NoErr(err) // Should be able to unmarshal - for _, e := range encoders { - out, err := e.Marshal(data) - assert.NoErr(err) // Should be able to marshal - err = e.Unmarshal(out, &data) - assert.NoErr(err) // Should be able to unmarshal + for _, e := range encoders { + out, err := e.Marshal(data) + assert.NoErr(err) // Should be able to marshal + err = e.Unmarshal(out, &data) + assert.NoErr(err) // Should be able to unmarshal + } + assert.Equal(data, final) // Final structs should be equal + }) } - assert.Equal(data, final) // Final structs should be equal } diff --git a/cmd/cfg/main.go b/cmd/cfg/main.go index cf92c9b..309044d 100644 --- a/cmd/cfg/main.go +++ b/cmd/cfg/main.go @@ -24,7 +24,7 @@ func maine() error { unmarshal = e.Unmarshal return nil } - fs.Func("from", "The format to convert from [json(c), yaml, toml, nix, dhall, kdl]", fromFunc) + fs.Func("from", "The format to convert from [json(c), jsonnet, yaml, toml, nix, dhall, kdl]", fromFunc) fs.Func("f", "--from", fromFunc) toFunc := func(s string) error { e, err := cfg.ParseEncoding(s) diff --git a/example/example.jsonnet b/example/example.jsonnet new file mode 100644 index 0000000..a6aa989 --- /dev/null +++ b/example/example.jsonnet @@ -0,0 +1,16 @@ +local name = 'jolheiser'; + +{ + username: name, + home: '/home/' + self.username, + admins: [name, 'admin'], + email: std.format('%s@example.com', self.username), + address: + { + street: '123', + country: 'USA', + state: 'MT', + zip: '12345', + phone: '123-456-7890', + }, +} diff --git a/go.mod b/go.mod index 1be84f7..5b553a6 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module go.jolheiser.com/cfg go 1.22.3 require ( + github.com/google/go-jsonnet v0.20.0 github.com/matryer/is v1.4.1 github.com/pelletier/go-toml/v2 v2.2.2 github.com/philandstuff/dhall-golang/v6 v6.0.2 @@ -15,6 +16,7 @@ require ( require ( github.com/fxamacker/cbor/v2 v2.2.1-0.20200511212021-28e39be4a84f // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect golang.org/x/text v0.3.7 // indirect + gopkg.in/yaml.v2 v2.2.7 // indirect + sigs.k8s.io/yaml v1.1.0 // indirect ) diff --git a/go.mod.sri b/go.mod.sri index 112a9d3..977bf15 100644 --- a/go.mod.sri +++ b/go.mod.sri @@ -1 +1 @@ -sha256-UbjwyV55TOyTXiYZCdTmwinZ0SGLRS95qYmvD4odnnM= \ No newline at end of file +sha256-VPU5cABkFpZPdRhpmhtrjguCj+8Q+njEjc8iU/W0KJ8= \ No newline at end of file diff --git a/go.sum b/go.sum index 906a790..d8f8bee 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g= +github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= @@ -43,6 +45,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sblinch/kdl-go v0.0.0-20240410000746-21754ba9ac55 h1:scyq0E9FvdGLX5lxAwjK0HebTM3Y7dG3tYrlXP+x+tk= github.com/sblinch/kdl-go v0.0.0-20240410000746-21754ba9ac55/go.mod h1:b3oNGuAKOQzhsCKmuLc/urEOPzgHj6fB8vl8bwTBh28= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -58,12 +62,6 @@ github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NA github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -go.jolheiser.com/nixfig v0.0.0-20231129190849-8b2170b2ecda h1:TdrB7ewFKHdv61ziR0Fzhj6zalgyjXdjBZIJJcdTohc= -go.jolheiser.com/nixfig v0.0.0-20231129190849-8b2170b2ecda/go.mod h1:GlnM735CZXZdJ7v9CMZ8Xjw1gZTrDXJ66Ak+jNwlwNU= -go.jolheiser.com/nixfig v0.0.0-20240620013146-d3931c448175 h1:PDwpdixizHZQbU6DrXQCtMmnuTCPFivBUw7th2Fs+2k= -go.jolheiser.com/nixfig v0.0.0-20240620013146-d3931c448175/go.mod h1:ua/+4W7HyAsknnkU2gT2jzuURFx0cImj7Uht27606TY= -go.jolheiser.com/nixfig v0.0.0-20240620014138-f34fba6b99d6 h1:TB+c0tNI8bLvn+AddMV8Vy2r0zGRmZEkC4yhICrC7ts= -go.jolheiser.com/nixfig v0.0.0-20240620014138-f34fba6b99d6/go.mod h1:ua/+4W7HyAsknnkU2gT2jzuURFx0cImj7Uht27606TY= go.jolheiser.com/nixfig v0.0.0-20240620014425-c1d5ec9d077a h1:KMiVqwvnDM3wpW7LmFb0W64HM2X7JZRXusGRrwGsYak= go.jolheiser.com/nixfig v0.0.0-20240620014425-c1d5ec9d077a/go.mod h1:ua/+4W7HyAsknnkU2gT2jzuURFx0cImj7Uht27606TY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -75,8 +73,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -88,8 +86,11 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=