diff --git a/CHANGELOG.md b/CHANGELOG.md index afce7f5e..321c223f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Fixed some bugs and regressions regarding dynamic variables and directories + ([#426](https://github.com/go-task/task/issues/426)). - The [slim-sprig](https://github.com/go-task/slim-sprig) package was updated with the upstream [sprig](https://github.com/Masterminds/sprig). diff --git a/internal/compiler/v3/compiler_v3.go b/internal/compiler/v3/compiler_v3.go index 1c0e2d5b..9530dd8f 100644 --- a/internal/compiler/v3/compiler_v3.go +++ b/internal/compiler/v3/compiler_v3.go @@ -32,29 +32,27 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi result := compiler.GetEnviron() result.Set("TASK", taskfile.Var{Static: t.Task}) - // NOTE(@andreynering): We're manually joining these paths here because - // this is the raw task, not the compiled one. - dir := t.Dir - if !filepath.IsAbs(dir) { - dir = filepath.Join(c.Dir, dir) - } + getRangeFunc := func(dir string) func(k string, v taskfile.Var) error { + return func(k string, v taskfile.Var) error { + tr := templater.Templater{Vars: result, RemoveNoValue: true} - rangeFunc := func(k string, v taskfile.Var) error { - tr := templater.Templater{Vars: result, RemoveNoValue: true} - v = taskfile.Var{ - Static: tr.Replace(v.Static), - Sh: tr.Replace(v.Sh), + v = taskfile.Var{ + Static: tr.Replace(v.Static), + Sh: tr.Replace(v.Sh), + Dir: v.Dir, + } + if err := tr.Err(); err != nil { + return err + } + static, err := c.HandleDynamicVar(v, dir) + if err != nil { + return err + } + result.Set(k, taskfile.Var{Static: static}) + return nil } - if err := tr.Err(); err != nil { - return err - } - static, err := c.HandleDynamicVar(v, dir) - if err != nil { - return err - } - result.Set(k, taskfile.Var{Static: static}) - return nil } + rangeFunc := getRangeFunc(c.Dir) if err := c.TaskfileVars.Range(rangeFunc); err != nil { return nil, err @@ -62,7 +60,20 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi if err := call.Vars.Range(rangeFunc); err != nil { return nil, err } - if err := t.Vars.Range(rangeFunc); err != nil { + + // NOTE(@andreynering): We're manually joining these paths here because + // this is the raw task, not the compiled one. + tr := templater.Templater{Vars: result, RemoveNoValue: true} + dir := tr.Replace(t.Dir) + if err := tr.Err(); err != nil { + return nil, err + } + if !filepath.IsAbs(dir) { + dir = filepath.Join(c.Dir, dir) + } + taskRangeFunc := getRangeFunc(dir) + + if err := t.Vars.Range(taskRangeFunc); err != nil { return nil, err } @@ -84,6 +95,11 @@ func (c *CompilerV3) HandleDynamicVar(v taskfile.Var, dir string) (string, error return result, nil } + // NOTE(@andreynering): If a var have a specific dir, use this instead + if v.Dir != "" { + dir = v.Dir + } + var stdout bytes.Buffer opts := &execext.RunCommandOptions{ Command: v.Sh, diff --git a/task_test.go b/task_test.go index dbfc64b9..1b131921 100644 --- a/task_test.go +++ b/task_test.go @@ -308,7 +308,7 @@ func TestGenerates(t *testing.T) { const ( srcTask = "sub/src.txt" relTask = "rel.txt" - absTask = "sub/abs.txt" + absTask = "abs.txt" fileWithSpaces = "my text file.txt" ) @@ -805,7 +805,10 @@ func TestDynamicVariablesShouldRunOnTheTaskDir(t *testing.T) { Target: "default", TrimSpace: false, Files: map[string]string{ - "subdirectory/dir.txt": "subdirectory\n", + "subdirectory/from_root_taskfile.txt": "subdirectory\n", + "subdirectory/from_included_taskfile.txt": "subdirectory\n", + "subdirectory/from_included_taskfile_task.txt": "subdirectory\n", + "subdirectory/from_interpolated_dir.txt": "subdirectory\n", }, } tt.Run(t) diff --git a/taskfile/read/taskfile.go b/taskfile/read/taskfile.go index c6171227..e7fa6ba2 100644 --- a/taskfile/read/taskfile.go +++ b/taskfile/read/taskfile.go @@ -97,6 +97,17 @@ func Taskfile(dir string, entrypoint string) (*taskfile.Taskfile, error) { } if includedTask.AdvancedImport { + for k, v := range includedTaskfile.Vars.Mapping { + o := v + o.Dir = filepath.Join(dir, includedTask.Dir) + includedTaskfile.Vars.Mapping[k] = o + } + for k, v := range includedTaskfile.Env.Mapping { + o := v + o.Dir = filepath.Join(dir, includedTask.Dir) + includedTaskfile.Env.Mapping[k] = o + } + for _, task := range includedTaskfile.Tasks { if !filepath.IsAbs(task.Dir) { task.Dir = filepath.Join(includedTask.Dir, task.Dir) diff --git a/taskfile/var.go b/taskfile/var.go index e552c94a..bd7ea28f 100644 --- a/taskfile/var.go +++ b/taskfile/var.go @@ -98,6 +98,7 @@ type Var struct { Static string Live interface{} Sh string + Dir string } // UnmarshalYAML implements yaml.Unmarshaler interface. diff --git a/testdata/dir/dynamic_var/.gitignore b/testdata/dir/dynamic_var/.gitignore index 5e4f4543..2211df63 100644 --- a/testdata/dir/dynamic_var/.gitignore +++ b/testdata/dir/dynamic_var/.gitignore @@ -1 +1 @@ -subdirectory/dir.txt +*.txt diff --git a/testdata/dir/dynamic_var/Taskfile.yml b/testdata/dir/dynamic_var/Taskfile.yml index 9a2d8cd6..81824024 100644 --- a/testdata/dir/dynamic_var/Taskfile.yml +++ b/testdata/dir/dynamic_var/Taskfile.yml @@ -1,11 +1,33 @@ version: '3' +includes: + sub: + taskfile: subdirectory + dir: subdirectory + +vars: + DIRECTORY: subdirectory + tasks: default: + - task: from-root-taskfile + - task: sub:from-included-taskfile + - task: sub:from-included-taskfile-task + - task: from-interpolated-dir + + from-root-taskfile: cmds: - - echo '{{.FOLDER}}' > dir.txt + - echo '{{.TASK_DIR}}' > from_root_taskfile.txt dir: subdirectory vars: - FOLDER: + TASK_DIR: sh: basename $(pwd) silent: true + + from-interpolated-dir: + cmds: + - echo '{{.INTERPOLATED_DIR}}' > from_interpolated_dir.txt + dir: '{{.DIRECTORY}}' + vars: + INTERPOLATED_DIR: + sh: basename $(pwd) diff --git a/testdata/dir/dynamic_var/subdirectory/Taskfile.yml b/testdata/dir/dynamic_var/subdirectory/Taskfile.yml new file mode 100644 index 00000000..9ca02611 --- /dev/null +++ b/testdata/dir/dynamic_var/subdirectory/Taskfile.yml @@ -0,0 +1,19 @@ +version: '3' + +vars: + TASKFILE_DIR: + sh: basename $(pwd) + +tasks: + from-included-taskfile: + cmds: + - echo '{{.TASKFILE_DIR}}' > from_included_taskfile.txt + silent: true + + from-included-taskfile-task: + cmds: + - echo '{{.TASKFILE_TASK_DIR}}' > from_included_taskfile_task.txt + silent: true + vars: + TASKFILE_TASK_DIR: + sh: basename $(pwd) diff --git a/testdata/dir/dynamic_var/subdirectory/dir.txt b/testdata/dir/dynamic_var/subdirectory/dir.txt deleted file mode 100644 index bcba6aa2..00000000 --- a/testdata/dir/dynamic_var/subdirectory/dir.txt +++ /dev/null @@ -1 +0,0 @@ -subdirectory diff --git a/testdata/generates/Taskfile.yml b/testdata/generates/Taskfile.yml index e2f4a87b..217a9626 100644 --- a/testdata/generates/Taskfile.yml +++ b/testdata/generates/Taskfile.yml @@ -1,10 +1,11 @@ version: '3' vars: - BUILD_DIR: $pwd + BUILD_DIR: + sh: pwd tasks: - sub/abs.txt: + abs.txt: desc: generates dest file based on absolute paths deps: - sub/src.txt