diff --git a/compiler.go b/compiler.go index 311fd58423..2345181b65 100644 --- a/compiler.go +++ b/compiler.go @@ -95,13 +95,17 @@ func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (* if t != nil { // NOTE(@andreynering): We're manually joining these paths here because // this is the raw task, not the compiled one. - cache := &templater.Cache{Vars: result} - dir := templater.Replace(t.Dir, cache) - if err := cache.Err(); err != nil { - return nil, err + // Resolve t.Dir lazily so that template variables (e.g. dir: '{{.VAR}}') + // can reference taskfile-level vars that are processed before task vars. + taskRangeFunc = func(k string, v ast.Var) error { + cache := &templater.Cache{Vars: result} + dir := templater.Replace(t.Dir, cache) + if err := cache.Err(); err != nil { + return err + } + dir = filepathext.SmartJoin(c.Dir, dir) + return getRangeFunc(dir)(k, v) } - dir = filepathext.SmartJoin(c.Dir, dir) - taskRangeFunc = getRangeFunc(dir) } for k, v := range c.TaskfileEnv.All() { @@ -157,15 +161,16 @@ func (c *Compiler) HandleDynamicVar(v ast.Var, dir string, e []string) (string, if c.dynamicCache == nil { c.dynamicCache = make(map[string]string, 30) } - if result, ok := c.dynamicCache[*v.Sh]; ok { - return result, nil - } - // NOTE(@andreynering): If a var have a specific dir, use this instead if v.Dir != "" { dir = v.Dir } + cacheKey := dir + "|" + *v.Sh + if result, ok := c.dynamicCache[cacheKey]; ok { + return result, nil + } + var stdout bytes.Buffer opts := &execext.RunCommandOptions{ Command: *v.Sh, @@ -183,7 +188,7 @@ func (c *Compiler) HandleDynamicVar(v ast.Var, dir string, e []string) (string, result := strings.TrimSuffix(stdout.String(), "\r\n") result = strings.TrimSuffix(result, "\n") - c.dynamicCache[*v.Sh] = result + c.dynamicCache[cacheKey] = result c.Logger.VerboseErrf(logger.Magenta, "task: dynamic variable: %q result: %q\n", *v.Sh, result) return result, nil diff --git a/taskfile/ast/taskfile.go b/taskfile/ast/taskfile.go index 4e3a3e4255..b1ba35aaa9 100644 --- a/taskfile/ast/taskfile.go +++ b/taskfile/ast/taskfile.go @@ -69,7 +69,7 @@ func (t1 *Taskfile) Merge(t2 *Taskfile, include *Include) error { } t1.Vars.Merge(t2.Vars, include) t1.Env.Merge(t2.Env, include) - return t1.Tasks.Merge(t2.Tasks, include, t1.Vars) + return t1.Tasks.Merge(t2.Tasks, include, t2.Vars) } func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error { diff --git a/taskfile/ast/tasks.go b/taskfile/ast/tasks.go index 62aa53a6b4..9f8170430c 100644 --- a/taskfile/ast/tasks.go +++ b/taskfile/ast/tasks.go @@ -176,7 +176,9 @@ func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars) task.IncludeVars = NewVars() } task.IncludeVars.Merge(include.Vars, nil) - task.IncludedTaskfileVars = includedTaskfileVars.DeepCopy() + if task.IncludedTaskfileVars == nil || task.IncludedTaskfileVars.Len() == 0 { + task.IncludedTaskfileVars = includedTaskfileVars.DeepCopy() + } } if _, ok := t1.Get(taskName); ok {