mirror of
https://github.com/go-task/task.git
synced 2025-11-25 22:32:55 +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:
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## Unreleased
|
## 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
|
- The watch feature (via the `--watch` flag) got a few different bug fixes and
|
||||||
should be more stable now
|
should be more stable now
|
||||||
([#423](https://github.com/go-task/task/pull/423), [#365](https://github.com/go-task/task/issues/365)).
|
([#423](https://github.com/go-task/task/pull/423), [#365](https://github.com/go-task/task/issues/365)).
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import (
|
|||||||
// E.g. variable merger, template processing, etc.
|
// E.g. variable merger, template processing, etc.
|
||||||
type Compiler interface {
|
type Compiler interface {
|
||||||
GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error)
|
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()
|
ResetCache()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -37,8 +38,20 @@ type CompilerV2 struct {
|
|||||||
// 4. Taskvars file variables
|
// 4. Taskvars file variables
|
||||||
// 5. Environment variables
|
// 5. Environment variables
|
||||||
func (c *CompilerV2) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) {
|
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})
|
vr.vars.Set("TASK", taskfile.Var{Static: t.Task})
|
||||||
|
|
||||||
for _, vars := range []*taskfile.Vars{c.Taskvars, c.TaskfileVars, call.Vars, t.Vars} {
|
for _, vars := range []*taskfile.Vars{c.Taskvars, c.TaskfileVars, call.Vars, t.Vars} {
|
||||||
for i := 0; i < c.Expansions; i++ {
|
for i := 0; i < c.Expansions; i++ {
|
||||||
vr.merge(vars)
|
vr.merge(vars)
|
||||||
@@ -49,6 +62,7 @@ func (c *CompilerV2) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
|
|||||||
|
|
||||||
type varResolver struct {
|
type varResolver struct {
|
||||||
c *CompilerV2
|
c *CompilerV2
|
||||||
|
dir string
|
||||||
vars *taskfile.Vars
|
vars *taskfile.Vars
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
@@ -63,7 +77,7 @@ func (vr *varResolver) merge(vars *taskfile.Vars) {
|
|||||||
Static: tr.Replace(v.Static),
|
Static: tr.Replace(v.Static),
|
||||||
Sh: tr.Replace(v.Sh),
|
Sh: tr.Replace(v.Sh),
|
||||||
}
|
}
|
||||||
static, err := vr.c.HandleDynamicVar(v)
|
static, err := vr.c.HandleDynamicVar(v, vr.dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
vr.err = err
|
vr.err = err
|
||||||
return err
|
return err
|
||||||
@@ -74,7 +88,7 @@ func (vr *varResolver) merge(vars *taskfile.Vars) {
|
|||||||
vr.err = tr.Err()
|
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 == "" {
|
if v.Static != "" || v.Sh == "" {
|
||||||
return v.Static, nil
|
return v.Static, nil
|
||||||
}
|
}
|
||||||
@@ -92,7 +106,7 @@ func (c *CompilerV2) HandleDynamicVar(v taskfile.Var) (string, error) {
|
|||||||
var stdout bytes.Buffer
|
var stdout bytes.Buffer
|
||||||
opts := &execext.RunCommandOptions{
|
opts := &execext.RunCommandOptions{
|
||||||
Command: v.Sh,
|
Command: v.Sh,
|
||||||
Dir: c.Dir,
|
Dir: dir,
|
||||||
Stdout: &stdout,
|
Stdout: &stdout,
|
||||||
Stderr: c.Logger.Stderr,
|
Stderr: c.Logger.Stderr,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -31,6 +32,13 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
|
|||||||
result := compiler.GetEnviron()
|
result := compiler.GetEnviron()
|
||||||
result.Set("TASK", taskfile.Var{Static: t.Task})
|
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 {
|
rangeFunc := func(k string, v taskfile.Var) error {
|
||||||
tr := templater.Templater{Vars: result, RemoveNoValue: true}
|
tr := templater.Templater{Vars: result, RemoveNoValue: true}
|
||||||
v = taskfile.Var{
|
v = taskfile.Var{
|
||||||
@@ -40,7 +48,7 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
|
|||||||
if err := tr.Err(); err != nil {
|
if err := tr.Err(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
static, err := c.HandleDynamicVar(v)
|
static, err := c.HandleDynamicVar(v, dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -61,7 +69,7 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
|
|||||||
return result, nil
|
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 == "" {
|
if v.Static != "" || v.Sh == "" {
|
||||||
return v.Static, nil
|
return v.Static, nil
|
||||||
}
|
}
|
||||||
@@ -79,7 +87,7 @@ func (c *CompilerV3) HandleDynamicVar(v taskfile.Var) (string, error) {
|
|||||||
var stdout bytes.Buffer
|
var stdout bytes.Buffer
|
||||||
opts := &execext.RunCommandOptions{
|
opts := &execext.RunCommandOptions{
|
||||||
Command: v.Sh,
|
Command: v.Sh,
|
||||||
Dir: c.Dir,
|
Dir: dir,
|
||||||
Stdout: &stdout,
|
Stdout: &stdout,
|
||||||
Stderr: c.Logger.Stderr,
|
Stderr: c.Logger.Stderr,
|
||||||
}
|
}
|
||||||
|
|||||||
19
task_test.go
19
task_test.go
@@ -303,16 +303,15 @@ func TestPrecondition(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerates(t *testing.T) {
|
func TestGenerates(t *testing.T) {
|
||||||
|
const dir = "testdata/generates"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
srcTask = "sub/src.txt"
|
srcTask = "sub/src.txt"
|
||||||
relTask = "rel.txt"
|
relTask = "rel.txt"
|
||||||
absTask = "abs.txt"
|
absTask = "sub/abs.txt"
|
||||||
fileWithSpaces = "my text file.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)
|
var srcFile = filepath.Join(dir, srcTask)
|
||||||
|
|
||||||
for _, task := range []string{srcTask, relTask, absTask, fileWithSpaces} {
|
for _, task := range []string{srcTask, relTask, absTask, fileWithSpaces} {
|
||||||
@@ -800,6 +799,18 @@ func TestWhenDirAttributeItCreatesMissingAndRunsInThatDir(t *testing.T) {
|
|||||||
_ = os.RemoveAll(toBeCreated)
|
_ = 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) {
|
func TestDisplaysErrorOnUnsupportedVersion(t *testing.T) {
|
||||||
e := task.Executor{
|
e := task.Executor{
|
||||||
Dir: "testdata/version/v1",
|
Dir: "testdata/version/v1",
|
||||||
|
|||||||
1
testdata/dir/dynamic_var/.gitignore
vendored
Normal file
1
testdata/dir/dynamic_var/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
subdirectory/dir.txt
|
||||||
11
testdata/dir/dynamic_var/Taskfile.yml
vendored
Normal file
11
testdata/dir/dynamic_var/Taskfile.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
cmds:
|
||||||
|
- echo '{{.FOLDER}}' > dir.txt
|
||||||
|
dir: subdirectory
|
||||||
|
vars:
|
||||||
|
FOLDER:
|
||||||
|
sh: basename $(pwd)
|
||||||
|
silent: true
|
||||||
1
testdata/dir/dynamic_var/subdirectory/dir.txt
vendored
Normal file
1
testdata/dir/dynamic_var/subdirectory/dir.txt
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
subdirectory
|
||||||
2
testdata/generates/Taskfile.yml
vendored
2
testdata/generates/Taskfile.yml
vendored
@@ -4,7 +4,7 @@ vars:
|
|||||||
BUILD_DIR: $pwd
|
BUILD_DIR: $pwd
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
abs.txt:
|
sub/abs.txt:
|
||||||
desc: generates dest file based on absolute paths
|
desc: generates dest file based on absolute paths
|
||||||
deps:
|
deps:
|
||||||
- sub/src.txt
|
- sub/src.txt
|
||||||
|
|||||||
@@ -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(e.Taskfile.Env))
|
||||||
new.Env.Merge(r.ReplaceVars(origTask.Env))
|
new.Env.Merge(r.ReplaceVars(origTask.Env))
|
||||||
err = new.Env.Range(func(k string, v taskfile.Var) error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user