diff --git a/assets/chezmoi.io/docs/reference/templates/functions/output.md b/assets/chezmoi.io/docs/reference/templates/functions/output.md index 64e76dca347..b4d2f9634dc 100644 --- a/assets/chezmoi.io/docs/reference/templates/functions/output.md +++ b/assets/chezmoi.io/docs/reference/templates/functions/output.md @@ -1,6 +1,6 @@ # `output` *name* [*arg*...] -`output` returns the output of executing the command *name* with *arg*s. If +`output` returns the output of executing the command _name_ with *arg*s. If executing the command returns an error then template execution exits with an error. The execution occurs every time that the template is executed. It is the user's responsibility to ensure that executing the command is both idempotent diff --git a/assets/chezmoi.io/docs/reference/templates/functions/outputList.md b/assets/chezmoi.io/docs/reference/templates/functions/outputList.md new file mode 100644 index 00000000000..c346b4eb048 --- /dev/null +++ b/assets/chezmoi.io/docs/reference/templates/functions/outputList.md @@ -0,0 +1,18 @@ +# `outputList` *name* [*argList*] + +`outputList` returns the output of executing the command *name* with the *argList*. +*arg*s. If executing the command returns an error then template execution exits +with an error. The execution occurs every time that the template is executed. It +is the user's responsibility to ensure that executing the command is both +idempotent and fast. + +This differs from [`output`](output.md) in that it allows for the *args* to be +created programmatically. + +!!! example + + ``` + {{- $args := (list "config" "current-context") }} + current-context: {{ outputList "kubectl" $args | trim }} + ``` + diff --git a/assets/chezmoi.io/mkdocs.yml b/assets/chezmoi.io/mkdocs.yml index e4074107529..92368cc99cb 100644 --- a/assets/chezmoi.io/mkdocs.yml +++ b/assets/chezmoi.io/mkdocs.yml @@ -224,6 +224,7 @@ nav: - lstat: reference/templates/functions/lstat.md - mozillaInstallHash: reference/templates/functions/mozillaInstallHash.md - output: reference/templates/functions/output.md + - outputList: reference/templates/functions/outputList.md - pruneEmptyDicts: reference/templates/functions/pruneEmptyDicts.md - quoteList: reference/templates/functions/quoteList.md - replaceAllRegex: reference/templates/functions/replaceAllRegex.md diff --git a/internal/cmd/config.go b/internal/cmd/config.go index bcb46dc9edb..0ff0e14369d 100644 --- a/internal/cmd/config.go +++ b/internal/cmd/config.go @@ -501,6 +501,7 @@ func newConfig(options ...configOption) (*Config, error) { "onepasswordSDKItemsGet": c.onepasswordSDKItemsGet, "onepasswordSDKSecretsResolve": c.onepasswordSDKSecretsResolve, "output": c.outputTemplateFunc, + "outputList": c.outputListTemplateFunc, "pass": c.passTemplateFunc, "passFields": c.passFieldsTemplateFunc, "passRaw": c.passRawTemplateFunc, diff --git a/internal/cmd/templatefuncs.go b/internal/cmd/templatefuncs.go index c60ee9bf91e..9dee8136115 100644 --- a/internal/cmd/templatefuncs.go +++ b/internal/cmd/templatefuncs.go @@ -340,6 +340,16 @@ func (c *Config) outputTemplateFunc(name string, args ...string) string { return string(output) } +func (c *Config) outputListTemplateFunc(name string, args []any) string { + slice, err := anyToStringSlice(args) + + if err != nil { + panic(fmt.Errorf("args list: %w", err)) + } + + return c.outputTemplateFunc(name, slice...) +} + func (c *Config) pruneEmptyDictsTemplateFunc(dict map[string]any) map[string]any { pruneEmptyMaps(dict) return dict diff --git a/internal/cmd/testdata/scripts/templatefuncs.txtar b/internal/cmd/testdata/scripts/templatefuncs.txtar index bbfd45d00b5..d9540041b42 100644 --- a/internal/cmd/testdata/scripts/templatefuncs.txtar +++ b/internal/cmd/testdata/scripts/templatefuncs.txtar @@ -138,6 +138,10 @@ stdout 2656FF1E876E9973 [unix] exec chezmoi execute-template '{{ $red := output "generate-color-formats" "#ff0000" | fromJson }}{{ $red.rgb.r }}' [unix] stdout '^255$' +# test the outputList and fromJson template functions +[unix] exec chezmoi execute-template '{{ $red := outputList "generate-color-formats" (list "#ff0000" ) | fromJson }}{{ $red.rgb.r }}' +[unix] stdout '^255$' + # test that the output function returns an error if the command fails [unix] ! exec chezmoi execute-template '{{ output "false" }}' [unix] stderr 'error calling output: .*/false: exit status 1'