diff --git a/compiler.go b/compiler.go index 348a072898..960cfe15d4 100644 --- a/compiler.go +++ b/compiler.go @@ -90,19 +90,6 @@ func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (* } rangeFunc := getRangeFunc(c.Dir) - var taskRangeFunc func(k string, v ast.Var) error - 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 - } - dir = filepathext.SmartJoin(c.Dir, dir) - taskRangeFunc = getRangeFunc(dir) - } - for k, v := range c.TaskfileEnv.All() { if err := rangeFunc(k, v); err != nil { return nil, err @@ -113,31 +100,48 @@ func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (* return nil, err } } + if t != nil { for k, v := range t.IncludeVars.All() { if err := rangeFunc(k, v); err != nil { return nil, err } } + + // Calculate the t.Dir now based on values saved during AST parsing + // and then get a Task RangeFunc. + dir := c.Dir + if len(t.Dir) == 0 { + // Use the saved include task.Dir. + t.Dir = t.IncludeTaskDir + } else { + cache := &templater.Cache{Vars: result} + taskDir := templater.Replace(t.Dir, cache) + if err := cache.Err(); err != nil { + return nil, err + } + t.Dir = filepathext.SmartJoin(t.IncludeDir, taskDir) + // Update dir (esp. if taskDir is a relative path). + dir = filepathext.SmartJoin(c.Dir, taskDir) + } + taskRangeFunc := getRangeFunc(dir) + for k, v := range t.IncludedTaskfileVars.All() { if err := taskRangeFunc(k, v); err != nil { return nil, err } } - } - - if t == nil || call == nil { - return result, nil - } - - for k, v := range call.Vars.All() { - if err := rangeFunc(k, v); err != nil { - return nil, err + if call != nil { + for k, v := range call.Vars.All() { + if err := rangeFunc(k, v); err != nil { + return nil, err + } + } } - } - for k, v := range t.Vars.All() { - if err := taskRangeFunc(k, v); err != nil { - return nil, err + for k, v := range t.Vars.All() { + if err := taskRangeFunc(k, v); err != nil { + return nil, err + } } } diff --git a/taskfile/ast/task.go b/taskfile/ast/task.go index 7c49e9a32c..069b553b77 100644 --- a/taskfile/ast/task.go +++ b/taskfile/ast/task.go @@ -44,6 +44,8 @@ type Task struct { Location *Location // Populated during merging Namespace string + IncludeDir string + IncludeTaskDir string IncludeVars *Vars IncludedTaskfileVars *Vars diff --git a/taskfile/ast/tasks.go b/taskfile/ast/tasks.go index dd499b85c7..55fa4e838a 100644 --- a/taskfile/ast/tasks.go +++ b/taskfile/ast/tasks.go @@ -11,7 +11,6 @@ import ( "gopkg.in/yaml.v3" "github.com/go-task/task/v3/errors" - "github.com/go-task/task/v3/internal/filepathext" "github.com/go-task/task/v3/internal/sort" ) @@ -171,7 +170,14 @@ func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars) } if include.AdvancedImport { - task.Dir = filepathext.SmartJoin(include.Dir, task.Dir) + // Save the include.Dir and task.Dir so that the final task.dir can + // be calculated when the task is compiled (and templating is available). + task.IncludeDir = include.Dir + task.IncludeTaskDir = task.Dir + // If task.dir is not set then use the include.dir. + if len(task.Dir) == 0 { + task.Dir = include.Dir + } if task.IncludeVars == nil { task.IncludeVars = NewVars() }