1
0
mirror of https://github.com/go-task/task.git synced 2024-12-04 10:24:45 +02:00

Make dynamic variables run on the right directory

It was always running in the main Taskfile dir, even when the variable was
declared in an included taskfile in another directory or when task had a
custom dir.

Closes #384
This commit is contained in:
Andrey Nering 2021-01-07 11:17:38 -03:00
parent cbdd088188
commit 59d2733b88
10 changed files with 64 additions and 14 deletions

View File

@ -2,6 +2,10 @@
## Unreleased
- Fix a bug where dynamic variables (those declared with `sh:`) were not
running in the task directory when the task has a custom dir or it was
in an included taskfile
([#384](https://github.com/go-task/task/issues/384)).
- The watch feature (via the `--watch` flag) got a few different bug fixes and
should be more stable now
([#423](https://github.com/go-task/task/pull/423), [#365](https://github.com/go-task/task/issues/365)).

View File

@ -8,6 +8,6 @@ import (
// E.g. variable merger, template processing, etc.
type Compiler interface {
GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error)
HandleDynamicVar(v taskfile.Var) (string, error)
HandleDynamicVar(v taskfile.Var, dir string) (string, error)
ResetCache()
}

View File

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"path/filepath"
"strings"
"sync"
@ -37,8 +38,20 @@ type CompilerV2 struct {
// 4. Taskvars file variables
// 5. Environment variables
func (c *CompilerV2) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) {
vr := varResolver{c: c, vars: compiler.GetEnviron()}
// 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)
}
vr := varResolver{
c: c,
dir: dir,
vars: compiler.GetEnviron(),
}
vr.vars.Set("TASK", taskfile.Var{Static: t.Task})
for _, vars := range []*taskfile.Vars{c.Taskvars, c.TaskfileVars, call.Vars, t.Vars} {
for i := 0; i < c.Expansions; i++ {
vr.merge(vars)
@ -49,6 +62,7 @@ func (c *CompilerV2) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
type varResolver struct {
c *CompilerV2
dir string
vars *taskfile.Vars
err error
}
@ -63,7 +77,7 @@ func (vr *varResolver) merge(vars *taskfile.Vars) {
Static: tr.Replace(v.Static),
Sh: tr.Replace(v.Sh),
}
static, err := vr.c.HandleDynamicVar(v)
static, err := vr.c.HandleDynamicVar(v, vr.dir)
if err != nil {
vr.err = err
return err
@ -74,7 +88,7 @@ func (vr *varResolver) merge(vars *taskfile.Vars) {
vr.err = tr.Err()
}
func (c *CompilerV2) HandleDynamicVar(v taskfile.Var) (string, error) {
func (c *CompilerV2) HandleDynamicVar(v taskfile.Var, dir string) (string, error) {
if v.Static != "" || v.Sh == "" {
return v.Static, nil
}
@ -92,7 +106,7 @@ func (c *CompilerV2) HandleDynamicVar(v taskfile.Var) (string, error) {
var stdout bytes.Buffer
opts := &execext.RunCommandOptions{
Command: v.Sh,
Dir: c.Dir,
Dir: dir,
Stdout: &stdout,
Stderr: c.Logger.Stderr,
}

View File

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"path/filepath"
"strings"
"sync"
@ -31,6 +32,13 @@ 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)
}
rangeFunc := func(k string, v taskfile.Var) error {
tr := templater.Templater{Vars: result, RemoveNoValue: true}
v = taskfile.Var{
@ -40,7 +48,7 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
if err := tr.Err(); err != nil {
return err
}
static, err := c.HandleDynamicVar(v)
static, err := c.HandleDynamicVar(v, dir)
if err != nil {
return err
}
@ -61,7 +69,7 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
return result, nil
}
func (c *CompilerV3) HandleDynamicVar(v taskfile.Var) (string, error) {
func (c *CompilerV3) HandleDynamicVar(v taskfile.Var, dir string) (string, error) {
if v.Static != "" || v.Sh == "" {
return v.Static, nil
}
@ -79,7 +87,7 @@ func (c *CompilerV3) HandleDynamicVar(v taskfile.Var) (string, error) {
var stdout bytes.Buffer
opts := &execext.RunCommandOptions{
Command: v.Sh,
Dir: c.Dir,
Dir: dir,
Stdout: &stdout,
Stderr: c.Logger.Stderr,
}

View File

@ -303,16 +303,15 @@ func TestPrecondition(t *testing.T) {
}
func TestGenerates(t *testing.T) {
const dir = "testdata/generates"
const (
srcTask = "sub/src.txt"
relTask = "rel.txt"
absTask = "abs.txt"
absTask = "sub/abs.txt"
fileWithSpaces = "my text file.txt"
)
// This test does not work with a relative dir.
dir, err := filepath.Abs("testdata/generates")
assert.NoError(t, err)
var srcFile = filepath.Join(dir, srcTask)
for _, task := range []string{srcTask, relTask, absTask, fileWithSpaces} {
@ -800,6 +799,18 @@ func TestWhenDirAttributeItCreatesMissingAndRunsInThatDir(t *testing.T) {
_ = os.RemoveAll(toBeCreated)
}
func TestDynamicVariablesShouldRunOnTheTaskDir(t *testing.T) {
tt := fileContentTest{
Dir: "testdata/dir/dynamic_var",
Target: "default",
TrimSpace: false,
Files: map[string]string{
"subdirectory/dir.txt": "subdirectory\n",
},
}
tt.Run(t)
}
func TestDisplaysErrorOnUnsupportedVersion(t *testing.T) {
e := task.Executor{
Dir: "testdata/version/v1",

1
testdata/dir/dynamic_var/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
subdirectory/dir.txt

11
testdata/dir/dynamic_var/Taskfile.yml vendored Normal file
View File

@ -0,0 +1,11 @@
version: '3'
tasks:
default:
cmds:
- echo '{{.FOLDER}}' > dir.txt
dir: subdirectory
vars:
FOLDER:
sh: basename $(pwd)
silent: true

View File

@ -0,0 +1 @@
subdirectory

View File

@ -4,7 +4,7 @@ vars:
BUILD_DIR: $pwd
tasks:
abs.txt:
sub/abs.txt:
desc: generates dest file based on absolute paths
deps:
- sub/src.txt

View File

@ -60,7 +60,7 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) {
new.Env.Merge(r.ReplaceVars(e.Taskfile.Env))
new.Env.Merge(r.ReplaceVars(origTask.Env))
err = new.Env.Range(func(k string, v taskfile.Var) error {
static, err := e.Compiler.HandleDynamicVar(v)
static, err := e.Compiler.HandleDynamicVar(v, new.Dir)
if err != nil {
return err
}