Skip to content

Commit 9619c7f

Browse files
committed
simplify getVariables() and improve nested variables support
/cc @smyrman
1 parent 2508bed commit 9619c7f

File tree

2 files changed

+39
-73
lines changed

2 files changed

+39
-73
lines changed

task_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,27 @@ func TestVars(t *testing.T) {
7272
Target: "default",
7373
TrimSpace: true,
7474
Files: map[string]string{
75-
// hello task:
7675
"foo.txt": "foo",
7776
"bar.txt": "bar",
7877
"baz.txt": "baz",
7978
"tmpl_foo.txt": "foo",
80-
"tmpl_bar.txt": "<no value>",
79+
"tmpl_bar.txt": "bar",
8180
"tmpl_foo2.txt": "foo2",
8281
"tmpl_bar2.txt": "bar2",
8382
"shtmpl_foo.txt": "foo",
8483
"shtmpl_foo2.txt": "foo2",
85-
"nestedtmpl_foo.txt": "{{.FOO}}",
84+
"nestedtmpl_foo.txt": "<no value>",
8685
"nestedtmpl_foo2.txt": "foo2",
8786
"foo2.txt": "foo2",
8887
"bar2.txt": "bar2",
8988
"baz2.txt": "baz2",
9089
"tmpl2_foo.txt": "<no value>",
9190
"tmpl2_foo2.txt": "foo2",
9291
"tmpl2_bar.txt": "<no value>",
93-
"tmpl2_bar2.txt": "<no value>",
92+
"tmpl2_bar2.txt": "bar2",
9493
"shtmpl2_foo.txt": "<no value>",
9594
"shtmpl2_foo2.txt": "foo2",
96-
"nestedtmpl2_foo2.txt": "{{.FOO2}}",
95+
"nestedtmpl2_foo2.txt": "<no value>",
9796
"override.txt": "bar",
9897
},
9998
}

variables.go

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

8787
// getVariables returns fully resolved variables following the priority order:
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
88+
// 1. Task variables
89+
// 2. Call variables
90+
// 3. Taskvars file variables
91+
// 4. Environment variables
9492
func (e *Executor) getVariables(call Call) (Vars, error) {
9593
t, ok := e.Tasks[call.Task]
9694
if !ok {
97-
return nil, &taskNotFoundError{call.Task}
98-
}
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+
}
99106

100-
merge := func(dest Vars, srcs ...Vars) {
101-
for _, src := range srcs {
102-
for k, v := range src {
103-
dest[k] = v
104-
}
105-
}
106-
}
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-
}
113-
}
114-
lst := make([]string, 0, len(m))
115-
for k := range m {
116-
lst = append(lst, k)
117-
}
118-
return lst
119-
}
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
107+
type varResolver struct {
108+
e *Executor
109+
vars Vars
110+
err error
111+
}
112+
113+
func (vr *varResolver) merge(vars Vars) {
114+
if vr.err != nil {
115+
return
130116
}
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}
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),
139122
}
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
123+
static, err := vr.e.handleShVar(v)
124+
if err != nil {
125+
vr.err = err
126+
return
148127
}
149-
return resolveShell(dest, updatedKeys)
128+
vr.vars[k] = Var{Static: static}
150129
}
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
130+
vr.err = r.err
164131
}
165132

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

0 commit comments

Comments
 (0)