Skip to content

Commit

Permalink
feat: Add promptChoice and promptChoiceOnce template functions
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Aug 13, 2023
1 parent bc3dec5 commit 65c5c5b
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `promptChoice` *prompt* *choices* [*default*]

`promptChoice` prompts the user with *prompt* and *choices* and returns the user's response. *choices* must be a list of strings. If *default* is passed and the user's response is empty then it returns *default*.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# `promptChoiceOnce` *map* *path* *prompt* *choices* [*default*]

`promptChoiceOnce` returns the value of *map* at *path* if it exists and is a
string, otherwise it prompts the user for one of *choices* with *prompt* and an
optional *default* using `promptChoice`.
2 changes: 2 additions & 0 deletions assets/chezmoi.io/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ nav:
- exit: reference/templates/init-functions/exit.md
- promptBool: reference/templates/init-functions/promptBool.md
- promptBoolOnce: reference/templates/init-functions/promptBoolOnce.md
- promptChoice: reference/templates/init-functions/promptChoice.md
- promptChoiceOnce: reference/templates/init-functions/promptChoiceOnce.md
- promptInt: reference/templates/init-functions/promptInt.md
- promptIntOnce: reference/templates/init-functions/promptIntOnce.md
- promptString: reference/templates/init-functions/promptString.md
Expand Down
3 changes: 3 additions & 0 deletions internal/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,8 @@ func (c *Config) createConfigFile(
"exit": c.exitInitTemplateFunc,
"promptBool": c.promptBoolInteractiveTemplateFunc,
"promptBoolOnce": c.promptBoolOnceInteractiveTemplateFunc,
"promptChoice": c.promptChoiceInteractiveTemplateFunc,
"promptChoiceOnce": c.promptChoiceOnceInteractiveTemplateFunc,
"promptInt": c.promptIntInteractiveTemplateFunc,
"promptIntOnce": c.promptIntOnceInteractiveTemplateFunc,
"promptString": c.promptStringInteractiveTemplateFunc,
Expand Down Expand Up @@ -1395,6 +1397,7 @@ func (c *Config) gitAutoCommit(status *git.Status) error {
funcMap := maps.Clone(sprig.TxtFuncMap())
maps.Copy(funcMap, map[string]any{
"promptBool": c.promptBoolInteractiveTemplateFunc,
"promptChoice": c.promptChoiceInteractiveTemplateFunc,
"promptInt": c.promptIntInteractiveTemplateFunc,
"promptString": c.promptStringInteractiveTemplateFunc,
"targetRelPath": func(source string) string {
Expand Down
45 changes: 45 additions & 0 deletions internal/cmd/interactivetemplatefuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
type interactiveTemplateFuncsConfig struct {
forcePromptOnce bool
promptBool map[string]string
promptChoice map[string]string
promptDefaults bool
promptInt map[string]int
promptString map[string]string
Expand All @@ -35,6 +36,12 @@ func (c *Config) addInteractiveTemplateFuncFlags(flags *pflag.FlagSet) {
c.interactiveTemplateFuncs.promptBool,
"Populate promptBool",
)
flags.StringToStringVar(
&c.interactiveTemplateFuncs.promptChoice,
"promptChoice",
c.interactiveTemplateFuncs.promptChoice,
"Populate promptChoice",
)
flags.StringToIntVar(
&c.interactiveTemplateFuncs.promptInt,
"promptInt",
Expand Down Expand Up @@ -101,6 +108,44 @@ func (c *Config) promptBoolOnceInteractiveTemplateFunc(
return c.promptBoolInteractiveTemplateFunc(prompt, args...)
}

func (c *Config) promptChoiceInteractiveTemplateFunc(prompt string, choices []string, args ...string) string {
if len(args) > 1 {
err := fmt.Errorf("want 2 or 3 arguments, got %d", len(args)+2)
panic(err)
}

if valueStr, ok := c.interactiveTemplateFuncs.promptChoice[prompt]; ok {
return valueStr
}

value, err := c.promptChoice(prompt, choices, args...)
if err != nil {
panic(err)
}
return value
}

func (c *Config) promptChoiceOnceInteractiveTemplateFunc(m map[string]any, path any, prompt string, choices []string, args ...string) string {
if len(args) > 1 {
err := fmt.Errorf("want 4 or 5 arguments, got %d", len(args)+4)
panic(err)
}

nestedMap, lastKey, err := nestedMapAtPath(m, path)
if err != nil {
panic(err)
}
if !c.interactiveTemplateFuncs.forcePromptOnce {
if value, ok := nestedMap[lastKey]; ok {
if valueStr, ok := value.(string); ok {
return valueStr
}
}
}

return c.promptChoiceInteractiveTemplateFunc(prompt, choices, args...)
}

func (c *Config) promptIntInteractiveTemplateFunc(prompt string, args ...int64) int64 {
if len(args) > 1 {
err := fmt.Errorf("want 1 or 2 arguments, got %d", len(args)+1)
Expand Down

0 comments on commit 65c5c5b

Please sign in to comment.