diff --git a/assets/chezmoi.io/docs/reference/templates/functions/fromJsonc.md b/assets/chezmoi.io/docs/reference/templates/functions/fromJsonc.md new file mode 100644 index 00000000000..eff5aafa907 --- /dev/null +++ b/assets/chezmoi.io/docs/reference/templates/functions/fromJsonc.md @@ -0,0 +1,5 @@ +# `fromJsonc` *jsonctext* + +`fromJsonc` parses *jsonctext* as JSONC using +[`github.com/tailscale/hujson`](https://github.com/tailscale/hujson) and returns +the parsed value. diff --git a/assets/chezmoi.io/docs/user-guide/manage-different-types-of-file.md b/assets/chezmoi.io/docs/user-guide/manage-different-types-of-file.md index 578f6a9b8d0..7f1f59b880f 100644 --- a/assets/chezmoi.io/docs/user-guide/manage-different-types-of-file.md +++ b/assets/chezmoi.io/docs/user-guide/manage-different-types-of-file.md @@ -86,8 +86,8 @@ contents of the file. {{- .chezmoi.stdin | replaceAllRegex "old" "new" }} ``` - To set individual values in JSON, TOML, and YAML files you can use the - `setValueAtPath` template function, for example: + To set individual values in JSON, JSONC, TOML, and YAML files you can use + the `setValueAtPath` template function, for example: ``` {{- /* chezmoi:modify-template */ -}} diff --git a/assets/chezmoi.io/mkdocs.yml b/assets/chezmoi.io/mkdocs.yml index d38472776c0..82fc4eeb347 100644 --- a/assets/chezmoi.io/mkdocs.yml +++ b/assets/chezmoi.io/mkdocs.yml @@ -182,6 +182,7 @@ nav: - encrypt: reference/templates/functions/encrypt.md - eqFold: reference/templates/functions/eqFold.md - fromIni: reference/templates/functions/fromIni.md + - fromJsonc: reference/templates/functions/fromJsonc.md - fromToml: reference/templates/functions/fromToml.md - fromYaml: reference/templates/functions/fromYaml.md - glob: reference/templates/functions/glob.md diff --git a/pkg/cmd/config.go b/pkg/cmd/config.go index 77a81812e44..4a4fc2be7ac 100644 --- a/pkg/cmd/config.go +++ b/pkg/cmd/config.go @@ -369,6 +369,7 @@ func newConfig(options ...configOption) (*Config, error) { "encrypt": c.encryptTemplateFunc, "eqFold": c.eqFoldTemplateFunc, "fromIni": c.fromIniTemplateFunc, + "fromJsonc": c.fromJsoncTemplateFunc, "fromToml": c.fromTomlTemplateFunc, "fromYaml": c.fromYamlTemplateFunc, "gitHubKeys": c.gitHubKeysTemplateFunc, diff --git a/pkg/cmd/templatefuncs.go b/pkg/cmd/templatefuncs.go index c05a141d86d..f20f1f5ae36 100644 --- a/pkg/cmd/templatefuncs.go +++ b/pkg/cmd/templatefuncs.go @@ -140,6 +140,14 @@ func (c *Config) fromIniTemplateFunc(s string) map[string]any { return iniFileToMap(file) } +func (c *Config) fromJsoncTemplateFunc(s string) any { + var data any + if err := chezmoi.FormatJSONC.Unmarshal([]byte(s), &data); err != nil { + panic(err) + } + return data +} + func (c *Config) fromTomlTemplateFunc(s string) any { var data any if err := chezmoi.FormatTOML.Unmarshal([]byte(s), &data); err != nil { diff --git a/pkg/cmd/testdata/scripts/templatefuncs.txtar b/pkg/cmd/testdata/scripts/templatefuncs.txtar index 6f6dc86caf2..12fd9ccd018 100644 --- a/pkg/cmd/testdata/scripts/templatefuncs.txtar +++ b/pkg/cmd/testdata/scripts/templatefuncs.txtar @@ -23,6 +23,11 @@ cmp stdout golden/deleteValueAtPath exec chezmoi execute-template '{{ eqFold "foo" "Foo" "FOO" }}' stdout '^true$' +# test fromJsonc template function +stdin golden/example.jsonc +exec chezmoi execute-template --with-stdin '{{ fromJsonc .chezmoi.stdin | toJson }}' +stdout '{"key":1}' + # test glob template function exec chezmoi execute-template '{{ glob "*.txt" | join "\n" }}{{ "\n" }}' cmp stdout golden/glob @@ -191,6 +196,10 @@ echo '' # line2 -- golden/deleteValueAtPath -- {"a":{"b":{"d":2}}} +-- golden/example.jsonc -- +{ + "key": 1, // Comment +} -- golden/expected -- 255 -- golden/glob --