Skip to content

Commit dfd890c

Browse files
committed
Revert "simplify getVariables() and improve nested variables support"
This reverts commit 9619c7f.
1 parent 7457b36 commit dfd890c

File tree

2 files changed

+73
-39
lines changed

2 files changed

+73
-39
lines changed

task_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,27 +72,28 @@ func TestVars(t *testing.T) {
7272
Target: "default",
7373
TrimSpace: true,
7474
Files: map[string]string{
75+
// hello task:
7576
"foo.txt": "foo",
7677
"bar.txt": "bar",
7778
"baz.txt": "baz",
7879
"tmpl_foo.txt": "foo",
79-
"tmpl_bar.txt": "bar",
80+
"tmpl_bar.txt": "<no value>",
8081
"tmpl_foo2.txt": "foo2",
8182
"tmpl_bar2.txt": "bar2",
8283
"shtmpl_foo.txt": "foo",
8384
"shtmpl_foo2.txt": "foo2",
84-
"nestedtmpl_foo.txt": "<no value>",
85+
"nestedtmpl_foo.txt": "{{.FOO}}",
8586
"nestedtmpl_foo2.txt": "foo2",
8687
"foo2.txt": "foo2",
8788
"bar2.txt": "bar2",
8889
"baz2.txt": "baz2",
8990
"tmpl2_foo.txt": "<no value>",
9091
"tmpl2_foo2.txt": "foo2",
9192
"tmpl2_bar.txt": "<no value>",
92-
"tmpl2_bar2.txt": "bar2",
93+
"tmpl2_bar2.txt": "<no value>",
9394
"shtmpl2_foo.txt": "<no value>",
9495
"shtmpl2_foo2.txt": "foo2",
95-
"nestedtmpl2_foo2.txt": "<no value>",
96+
"nestedtmpl2_foo2.txt": "{{.FOO2}}",
9697
"override.txt": "bar",
9798
},
9899
}

variables.go

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -85,49 +85,82 @@ func (v *Var) UnmarshalYAML(unmarshal func(interface{}) error) error {
8585
}
8686

8787
// getVariables returns fully resolved variables following the priority order:
88-
// 1. Task variables
89-
// 2. Call variables
90-
// 3. Taskvars file variables
91-
// 4. Environment variables
88+
// 1. Call variables (should already have been resolved)
89+
// 2. Environment (should not need to be resolved)
90+
// 3. Task variables, resolved with access to:
91+
// - call, taskvars and environment variables
92+
// 4. Taskvars variables, resolved with access to:
93+
// - environment variables
9294
func (e *Executor) getVariables(call Call) (Vars, error) {
9395
t, ok := e.Tasks[call.Task]
9496
if !ok {
95-
return nil, &taskNotFoundError{taskName: call.Task}
96-
}
97-
vr := varResolver{e: e, vars: getEnvironmentVariables()}
98-
vr.merge(e.taskvars)
99-
vr.merge(e.taskvars)
100-
vr.merge(call.Vars)
101-
vr.merge(call.Vars)
102-
vr.merge(t.Vars)
103-
vr.merge(t.Vars)
104-
return vr.vars, vr.err
105-
}
106-
107-
type varResolver struct {
108-
e *Executor
109-
vars Vars
110-
err error
111-
}
97+
return nil, &taskNotFoundError{call.Task}
98+
}
11299

113-
func (vr *varResolver) merge(vars Vars) {
114-
if vr.err != nil {
115-
return
100+
merge := func(dest Vars, srcs ...Vars) {
101+
for _, src := range srcs {
102+
for k, v := range src {
103+
dest[k] = v
104+
}
105+
}
116106
}
117-
r := varReplacer{vars: vr.vars}
118-
for k, v := range vars {
119-
v = Var{
120-
Static: r.replace(v.Static),
121-
Sh: r.replace(v.Sh),
107+
varsKeys := func(srcs ...Vars) []string {
108+
m := make(map[string]struct{})
109+
for _, src := range srcs {
110+
for k := range src {
111+
m[k] = struct{}{}
112+
}
122113
}
123-
static, err := vr.e.handleShVar(v)
124-
if err != nil {
125-
vr.err = err
126-
return
114+
lst := make([]string, 0, len(m))
115+
for k := range m {
116+
lst = append(lst, k)
127117
}
128-
vr.vars[k] = Var{Static: static}
118+
return lst
129119
}
130-
vr.err = r.err
120+
replaceVars := func(dest Vars, keys []string) error {
121+
r := varReplacer{vars: dest}
122+
for _, k := range keys {
123+
v := dest[k]
124+
dest[k] = Var{
125+
Static: r.replace(v.Static),
126+
Sh: r.replace(v.Sh),
127+
}
128+
}
129+
return r.err
130+
}
131+
resolveShell := func(dest Vars, keys []string) error {
132+
for _, k := range keys {
133+
v := dest[k]
134+
static, err := e.handleShVar(v)
135+
if err != nil {
136+
return err
137+
}
138+
dest[k] = Var{Static: static}
139+
}
140+
return nil
141+
}
142+
update := func(dest Vars, srcs ...Vars) error {
143+
merge(dest, srcs...)
144+
// updatedKeys ensures template evaluation is run only once.
145+
updatedKeys := varsKeys(srcs...)
146+
if err := replaceVars(dest, updatedKeys); err != nil {
147+
return err
148+
}
149+
return resolveShell(dest, updatedKeys)
150+
}
151+
152+
// Resolve taskvars variables to "result" with environment override variables.
153+
override := getEnvironmentVariables()
154+
result := make(Vars, len(e.taskvars)+len(t.Vars)+len(override))
155+
if err := update(result, e.taskvars, override); err != nil {
156+
return nil, err
157+
}
158+
// Resolve task variables to "result" with environment and call override variables.
159+
merge(override, call.Vars)
160+
if err := update(result, t.Vars, override); err != nil {
161+
return nil, err
162+
}
163+
return result, nil
131164
}
132165

133166
func (e *Executor) handleShVar(v Var) (string, error) {

0 commit comments

Comments
 (0)