summaryrefslogtreecommitdiffstats
path: root/pkg/gui/services/custom_commands/resolver.go
blob: 4702d36c4cf99a1f08e308642c1d49d1d19c47f8 (plain)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
package custom_commands

import (
	"bytes"
	"text/template"

	"github.com/jesseduffield/lazygit/pkg/common"
	"github.com/jesseduffield/lazygit/pkg/config"
)

// takes a prompt that is defined in terms of template strings and resolves the templates to contain actual values
type Resolver struct {
	c *common.Common
}

func NewResolver(c *common.Common) *Resolver {
	return &Resolver{c: c}
}

func (self *Resolver) resolvePrompt(
	prompt *config.CustomCommandPrompt,
	resolveTemplate func(string) (string, error),
) (*config.CustomCommandPrompt, error) {
	var err error
	result := &config.CustomCommandPrompt{
		ValueFormat: prompt.ValueFormat,
		LabelFormat: prompt.LabelFormat,
	}

	result.Title, err = resolveTemplate(prompt.Title)
	if err != nil {
		return nil, err
	}

	result.InitialValue, err = resolveTemplate(prompt.InitialValue)
	if err != nil {
		return nil, err
	}

	result.Body, err = resolveTemplate(prompt.Body)
	if err != nil {
		return nil, err
	}

	result.Command, err = resolveTemplate(prompt.Command)
	if err != nil {
		return nil, err
	}

	result.Filter, err = resolveTemplate(prompt.Filter)
	if err != nil {
		return nil, err
	}

	if prompt.Type == "menu" {
		result.Options, err = self.resolveMenuOptions(prompt, resolveTemplate)
		if err != nil {
			return nil, err
		}
	}

	return result, nil
}

func (self *Resolver) resolveMenuOptions(prompt *config.CustomCommandPrompt, resolveTemplate func(string) (string, error)) ([]config.CustomCommandMenuOption, error) {
	newOptions := make([]config.CustomCommandMenuOption, 0, len(prompt.Options))
	for _, option := range prompt.Options {
		option := option
		newOption, err := self.resolveMenuOption(&option, resolveTemplate)
		if err != nil {
			return nil, err
		}
		newOptions = append(newOptions, *newOption)
	}

	return newOptions, nil
}

func (self *Resolver) resolveMenuOption(option *config.CustomCommandMenuOption, resolveTemplate func(string) (string, error)) (*config.CustomCommandMenuOption, error) {
	nameTemplate := option.Name
	if nameTemplate == "" {
		// this allows you to only pass values rather than bother with names/descriptions
		nameTemplate = option.Value
	}

	name, err := resolveTemplate(nameTemplate)
	if err != nil {
		return nil, err
	}

	description, err := resolveTemplate(option.Description)
	if err != nil {
		return nil, err
	}

	value, err := resolveTemplate(option.Value)
	if err != nil {
		return nil, err
	}

	return &config.CustomCommandMenuOption{
		Name:        name,
		Description: description,
		Value:       value,
	}, nil
}

type CustomCommandObject struct {
	// deprecated. Use Responses instead
	PromptResponses []string
	Form            map[string]string
}

func ResolveTemplate(templateStr string, object interface{}) (string, error) {
	tmpl, err := template.New("template").Parse(templateStr)
	if err != nil {
		return "", err
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, object); err != nil {
		return "", err
	}

	return buf.String(), nil
}