diff --git a/config/config.go b/config/config.go index fa7eb12..5ac08fd 100644 --- a/config/config.go +++ b/config/config.go @@ -14,13 +14,25 @@ type Config struct { Prompts []Prompt `yaml:"prompts"` } +// PromptType is a type of prompt +type PromptType string + +const ( + PromptTypeInput PromptType = "input" + PromptTypeMultiline PromptType = "multi" + PromptTypeEditor PromptType = "editor" + PromptTypeConfirm PromptType = "confirm" + PromptTypeSelect PromptType = "select" +) + // Prompt is a tmpl prompt type Prompt struct { - ID string `yaml:"id"` - Label string `yaml:"label"` - Help string `yaml:"help"` - Default string `yaml:"default"` - Options []string `yaml:"options"` + ID string `yaml:"id"` + Label string `yaml:"label"` + Help string `yaml:"help"` + Default string `yaml:"default"` + Options []string `yaml:"options"` + Type PromptType `yaml:"type"` } // Load loads a tmpl config diff --git a/registry/prompt.go b/registry/prompt.go index 9f731eb..73d733d 100644 --- a/registry/prompt.go +++ b/registry/prompt.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "strconv" "strings" "text/template" @@ -55,7 +56,8 @@ func prompt(dir string, defaults bool) (templatePrompts, error) { // Otherwise, prompt var p survey.Prompt - if len(prompt.Options) > 0 { + switch prompt.Type { + case config.PromptTypeSelect: opts := make([]string, 0, len(prompt.Options)) for idy, opt := range prompt.Options { opts[idy] = os.ExpandEnv(opt) @@ -65,7 +67,26 @@ func prompt(dir string, defaults bool) (templatePrompts, error) { Options: opts, Help: prompt.Help, } - } else { + case config.PromptTypeConfirm: + def, _ := strconv.ParseBool(os.ExpandEnv(prompt.Default)) + p = &survey.Confirm{ + Message: prompt.Label, + Help: prompt.Help, + Default: def, + } + case config.PromptTypeMultiline: + p = &survey.Multiline{ + Message: prompt.Label, + Default: os.ExpandEnv(prompt.Default), + Help: prompt.Help, + } + case config.PromptTypeEditor: + p = &survey.Editor{ + Message: prompt.Label, + Default: os.ExpandEnv(prompt.Default), + Help: prompt.Help, + } + default: p = &survey.Input{ Message: prompt.Label, Default: os.ExpandEnv(prompt.Default), @@ -73,12 +94,13 @@ func prompt(dir string, defaults bool) (templatePrompts, error) { } } - var a string - if err := survey.AskOne(p, &a); err != nil { - return nil, err + m := make(map[string]any) + if err := survey.AskOne(p, &m); err != nil { + return nil, fmt.Errorf("could not complete prompt: %w", err) } + a := m[""] prompts[idx].Value = a - os.Setenv(fmt.Sprintf("TMPL_PROMPT_%s", envKey), a) + os.Setenv(fmt.Sprintf("TMPL_PROMPT_%s", envKey), fmt.Sprint(a)) } return prompts, nil @@ -86,7 +108,7 @@ func prompt(dir string, defaults bool) (templatePrompts, error) { type templatePrompt struct { config.Prompt - Value string + Value any } type templatePrompts []templatePrompt diff --git a/registry/registry.go b/registry/registry.go index a0f40ae..9a9dd0b 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -2,7 +2,6 @@ package registry import ( "errors" - "io/ioutil" "os" "path/filepath" "strings" @@ -223,7 +222,7 @@ func create(regFile string) error { } func download(cloneURL, branch, dest string) error { - tmp, err := ioutil.TempDir(os.TempDir(), "tmpl") + tmp, err := os.MkdirTemp(os.TempDir(), "tmpl") if err != nil { return err } diff --git a/registry/registry_test.go b/registry/registry_test.go index eb99ce1..45c12e4 100644 --- a/registry/registry_test.go +++ b/registry/registry_test.go @@ -3,7 +3,6 @@ package registry import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -67,7 +66,7 @@ func testGetFail(t *testing.T) { func setupTemplate() { var err error - tmplDir, err = ioutil.TempDir(os.TempDir(), "tmpl-setup") + tmplDir, err = os.MkdirTemp(os.TempDir(), "tmpl-setup") if err != nil { panic(err) } @@ -115,7 +114,7 @@ func setupTemplate() { func setupRegistry() { var err error - regDir, err = ioutil.TempDir(os.TempDir(), "tmpl-reg") + regDir, err = os.MkdirTemp(os.TempDir(), "tmpl-reg") if err != nil { panic(err) } diff --git a/registry/template.go b/registry/template.go index 39ca612..239b02c 100644 --- a/registry/template.go +++ b/registry/template.go @@ -3,7 +3,6 @@ package registry import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -36,7 +35,7 @@ func (t *Template) ArchivePath() string { // Execute runs the Template and copies to dest func (t *Template) Execute(dest string, defaults, overwrite bool) error { - tmp, err := ioutil.TempDir(os.TempDir(), "tmpl") + tmp, err := os.MkdirTemp(os.TempDir(), "tmpl") if err != nil { return err } @@ -62,7 +61,7 @@ func (t *Template) Execute(dest string, defaults, overwrite bool) error { return nil } - contents, err := ioutil.ReadFile(walkPath) + contents, err := os.ReadFile(walkPath) if err != nil { return err } diff --git a/registry/template_test.go b/registry/template_test.go index 138d84d..c2af0bf 100644 --- a/registry/template_test.go +++ b/registry/template_test.go @@ -1,7 +1,6 @@ package registry import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -51,7 +50,7 @@ func testExecute(t *testing.T) { // Check contents of file testPath := filepath.Join(destDir, "TEST") - contents, err := ioutil.ReadFile(testPath) + contents, err := os.ReadFile(testPath) assert.NoErr(err) // Should be able to read TEST file assert.Equal(string(contents), tmplGold) // Template should match golden file @@ -66,7 +65,7 @@ func testExecute(t *testing.T) { assert.True(err != nil) // .tmplkeep file should NOT be retained // Change file to test non-overwrite - err = ioutil.WriteFile(testPath, []byte(tmplNewGold), os.ModePerm) + err = os.WriteFile(testPath, []byte(tmplNewGold), os.ModePerm) assert.NoErr(err) // Writing file should succeed err = tmpl.Execute(destDir, true, false) diff --git a/schema/tmpl.json b/schema/tmpl.json index a8fdb7f..f88ce46 100644 --- a/schema/tmpl.json +++ b/schema/tmpl.json @@ -43,8 +43,32 @@ "items": { "type": "string" } + }, + "type": { + "description": "The type of prompt", + "type": "string", + "enum": ["input", "multi", "select", "confirm", "editor"] } - } + }, + "anyOf": [ + { + "properties": { + "type": { + "const": "select" + } + }, + "required": ["options"] + }, + { + "properties": { + "type": { + "not": { + "const": "select" + } + } + } + } + ] } } }