Home

tmpl @d02502078f5c143f365e07447af8ca4f0a5f178c - refs - log -
-
https://git.jolheiser.com/tmpl.git
Template automation
tmpl / registry / prompt.go
- raw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package registry

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"go.jolheiser.com/tmpl/config"

	"github.com/AlecAivazis/survey/v2"
)

func prompt(dir string, defaults bool) (templatePrompts, error) {
	templatePath := filepath.Join(dir, "tmpl.yaml")
	fi, err := os.Open(templatePath)
	if err != nil {
		return nil, err
	}
	defer fi.Close()

	cfg, err := config.Load(fi)
	if err != nil {
		return nil, err
	}

	prompts := make(templatePrompts, 0, len(cfg.Prompts))
	for _, prompt := range cfg.Prompts {
		tp := templatePrompt{
			Prompt: prompt,
		}
		if tp.Label == "" {
			tp.Label = tp.ID
		}
		prompts = append(prompts, tp)
	}

	for idx, prompt := range prompts {
		// Check for env variable
		envKey := strings.ToUpper(prompt.ID)
		if e, ok := os.LookupEnv(fmt.Sprintf("TMPL_VAR_%s", envKey)); ok {
			prompts[idx].Value = e
			os.Setenv(fmt.Sprintf("TMPL_PROMPT_%s", envKey), e)
			continue
		}

		// Check if we are using defaults
		if defaults {
			val := os.ExpandEnv(prompt.Default)
			prompts[idx].Value = val
			os.Setenv(fmt.Sprintf("TMPL_PROMPT_%s", envKey), val)
			continue
		}

		// Otherwise, prompt
		var p survey.Prompt
		if len(prompt.Options) > 0 {
			opts := make([]string, 0, len(prompt.Options))
			for idy, opt := range prompt.Options {
				opts[idy] = os.ExpandEnv(opt)
			}
			p = &survey.Select{
				Message: prompt.Label,
				Options: opts,
				Help:    prompt.Help,
			}
		} else {
			p = &survey.Input{
				Message: prompt.Label,
				Default: os.ExpandEnv(prompt.Default),
				Help:    prompt.Help,
			}
		}

		var a string
		if err := survey.AskOne(p, &a); err != nil {
			return nil, err
		}
		prompts[idx].Value = a
		os.Setenv(fmt.Sprintf("TMPL_PROMPT_%s", envKey), a)
	}

	return prompts, nil
}

type templatePrompt struct {
	config.Prompt
	Value string
}

type templatePrompts []templatePrompt

// ToMap converts a slice to templatePrompt into a suitable template context
func (t templatePrompts) ToMap() map[string]any {
	m := make(map[string]any)
	for _, p := range t {
		m[p.ID] = p.Value
	}
	return m
}

// ToFuncMap converts a slice of templatePrompt into a suitable template.FuncMap
func (t templatePrompts) ToFuncMap() template.FuncMap {
	m := make(map[string]any)
	for k, v := range t.ToMap() {
		vv := v // Enclosure
		m[k] = func() any {
			return vv
		}
	}
	return m
}