feat: jsonnet

Signed-off-by: jolheiser <git@jolheiser.com>
main
jolheiser 2024-07-22 21:52:20 -05:00
parent ae0d93434e
commit 5edec76b62
No known key found for this signature in database
7 changed files with 102 additions and 43 deletions

25
cfg.go
View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/google/go-jsonnet"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
"github.com/philandstuff/dhall-golang/v6" "github.com/philandstuff/dhall-golang/v6"
"github.com/sblinch/kdl-go" "github.com/sblinch/kdl-go"
@ -17,13 +18,14 @@ import (
type Encoding string type Encoding string
const ( const (
JSON Encoding = "json" JSON Encoding = "json"
JSONC Encoding = "jsonc" JSONC Encoding = "jsonc"
YAML Encoding = "yaml" JSONNET Encoding = "jsonnet"
TOML Encoding = "toml" YAML Encoding = "yaml"
NIX Encoding = "nix" TOML Encoding = "toml"
DHALL Encoding = "dhall" NIX Encoding = "nix"
KDL Encoding = "kdl" DHALL Encoding = "dhall"
KDL Encoding = "kdl"
) )
// Marshal takes data and encodes for an [Encoding] // Marshal takes data and encodes for an [Encoding]
@ -43,6 +45,8 @@ func ParseEncoding(s string) (Encoding, error) {
return JSON, nil return JSON, nil
case "jsonc": case "jsonc":
return JSONC, nil return JSONC, nil
case "jsonnet":
return JSONNET, nil
case "yaml": case "yaml":
return YAML, nil return YAML, nil
case "toml": case "toml":
@ -88,6 +92,13 @@ func Unmarshal(e Encoding, data []byte, v any) error {
return err return err
} }
return json.Unmarshal(b, v) 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: case YAML:
return yaml.Unmarshal(data, v) return yaml.Unmarshal(data, v)
case TOML: case TOML:

View File

@ -21,21 +21,6 @@ type TestSubData struct {
} }
func TestEncoding(t *testing.T) { 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{ final := TestData{
Foo: "bar", Foo: "bar",
Baz: true, 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} encoders := []Encoding{JSON, JSONC, YAML, TOML, KDL}
// Only test nix if it's available // Only test nix if it's available
if nixfig.Nix != "" { if nixfig.Nix != "" {
encoders = append(encoders, NIX) encoders = append(encoders, NIX)
} }
var data TestData for _, tc := range tt {
err := DHALL.Unmarshal([]byte(dhall), &data) t.Run(tc.Name, func(t *testing.T) {
assert.NoErr(err) // Should be able to unmarshal dhall 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 { for _, e := range encoders {
out, err := e.Marshal(data) out, err := e.Marshal(data)
assert.NoErr(err) // Should be able to marshal assert.NoErr(err) // Should be able to marshal
err = e.Unmarshal(out, &data) err = e.Unmarshal(out, &data)
assert.NoErr(err) // Should be able to unmarshal 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
} }

View File

@ -24,7 +24,7 @@ func maine() error {
unmarshal = e.Unmarshal unmarshal = e.Unmarshal
return nil 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) fs.Func("f", "--from", fromFunc)
toFunc := func(s string) error { toFunc := func(s string) error {
e, err := cfg.ParseEncoding(s) e, err := cfg.ParseEncoding(s)

View File

@ -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',
},
}

4
go.mod
View File

@ -3,6 +3,7 @@ module go.jolheiser.com/cfg
go 1.22.3 go 1.22.3
require ( require (
github.com/google/go-jsonnet v0.20.0
github.com/matryer/is v1.4.1 github.com/matryer/is v1.4.1
github.com/pelletier/go-toml/v2 v2.2.2 github.com/pelletier/go-toml/v2 v2.2.2
github.com/philandstuff/dhall-golang/v6 v6.0.2 github.com/philandstuff/dhall-golang/v6 v6.0.2
@ -15,6 +16,7 @@ require (
require ( require (
github.com/fxamacker/cbor/v2 v2.2.1-0.20200511212021-28e39be4a84f // indirect github.com/fxamacker/cbor/v2 v2.2.1-0.20200511212021-28e39be4a84f // indirect
github.com/x448/float16 v0.8.4 // 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 golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v2 v2.2.7 // indirect
sigs.k8s.io/yaml v1.1.0 // indirect
) )

View File

@ -1 +1 @@
sha256-UbjwyV55TOyTXiYZCdTmwinZ0SGLRS95qYmvD4odnnM= sha256-VPU5cABkFpZPdRhpmhtrjguCj+8Q+njEjc8iU/W0KJ8=

19
go.sum
View File

@ -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/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 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= 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/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 h1:scyq0E9FvdGLX5lxAwjK0HebTM3Y7dG3tYrlXP+x+tk=
github.com/sblinch/kdl-go v0.0.0-20240410000746-21754ba9ac55/go.mod h1:b3oNGuAKOQzhsCKmuLc/urEOPzgHj6fB8vl8bwTBh28= 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/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.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 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/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 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= 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 h1:KMiVqwvnDM3wpW7LmFb0W64HM2X7JZRXusGRrwGsYak=
go.jolheiser.com/nixfig v0.0.0-20240620014425-c1d5ec9d077a/go.mod h1:ua/+4W7HyAsknnkU2gT2jzuURFx0cImj7Uht27606TY= 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= 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-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-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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 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 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 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.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.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.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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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=