Compare commits

...

15 Commits

Author SHA1 Message Date
Andrey Nering
b095ca5756 v3.2.1 2021-01-09 13:57:20 -03:00
Andrey Nering
4afc0e8ed0 Fixed some bugs and regressions regarding dynamic variables and directories
Closes #426
2021-01-09 13:51:06 -03:00
Andrey Nering
141b377b4e Partly revert 59d2733b88
Keep the old behavior on v2
2021-01-09 10:55:18 -03:00
Andrey Nering
402a478785 Update CHANGELOG 2021-01-09 10:46:53 -03:00
Andrey Nering
73680584f3 Upgrade github.com/go-task/slim-sprig 2021-01-07 13:56:07 -03:00
Andrey Nering
45dbbcd179 v3.2.0 2021-01-07 13:08:07 -03:00
Andrey Nering
83d25bfa00 Refactor: Fix import order
It should be: stdlib > libs > app
2021-01-07 11:48:33 -03:00
Andrey Nering
299e27af15 Fix build 2021-01-07 11:39:36 -03:00
Andrey Nering
ec4cd5ed48 Fix .task directory location
Closes #247
2021-01-07 11:36:09 -03:00
Andrey Nering
59d2733b88 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
2021-01-07 11:26:11 -03:00
Andrey Nering
cbdd088188 Remove manual event trigger 2021-01-05 11:36:30 -03:00
Andrey Nering
2d52485d7b Watch: Clear vars cache between runs
Closes #365
2021-01-05 11:19:34 -03:00
Andrey Nering
d830178ef8 Do more watch fixes
This improves the work done on #423
2021-01-05 10:48:04 -03:00
James Wendel
049984b4cc Update watch.go 2021-01-03 21:26:09 -07:00
James Wendel
d261a986ab Update watch.go
Watch: Stop removing and addings files all the time.
2021-01-03 17:08:16 -07:00
26 changed files with 228 additions and 84 deletions

View File

@@ -1,5 +1,25 @@
# Changelog # Changelog
## v3.2.1
- 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).
## v3.2.0
- Fix the `.task` directory being created in the task directory instead of the
Taskfile directory
([#247](https://github.com/go-task/task/issues/247)).
- 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)).
## v3.1.0 ## v3.1.0
- Fix a bug when the checksum up-to-date resolution is used by a task - Fix a bug when the checksum up-to-date resolution is used by a task

View File

@@ -4,10 +4,10 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/go-task/task/v3/args" "github.com/go-task/task/v3/args"
"github.com/go-task/task/v3/taskfile" "github.com/go-task/task/v3/taskfile"
"github.com/stretchr/testify/assert"
) )
func TestArgsV3(t *testing.T) { func TestArgsV3(t *testing.T) {

View File

@@ -9,12 +9,12 @@ import (
"path/filepath" "path/filepath"
"syscall" "syscall"
"github.com/spf13/pflag"
"github.com/go-task/task/v3" "github.com/go-task/task/v3"
"github.com/go-task/task/v3/args" "github.com/go-task/task/v3/args"
"github.com/go-task/task/v3/internal/logger" "github.com/go-task/task/v3/internal/logger"
"github.com/go-task/task/v3/taskfile" "github.com/go-task/task/v3/taskfile"
"github.com/spf13/pflag"
) )
var ( var (

2
go.mod
View File

@@ -2,7 +2,7 @@ module github.com/go-task/task/v3
require ( require (
github.com/fatih/color v1.7.0 github.com/fatih/color v1.7.0
github.com/go-task/slim-sprig v0.0.0-20200516131648-f9bac4e523eb github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/mattn/go-colorable v0.1.2 // indirect github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-zglob v0.0.1 github.com/mattn/go-zglob v0.0.1

4
go.sum
View File

@@ -8,8 +8,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/go-task/slim-sprig v0.0.0-20200516131648-f9bac4e523eb h1:/qbv1F67s6ehqX9mG23cJOeca3FWpOVKgtPfPUMAi0k= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20200516131648-f9bac4e523eb/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=

View File

@@ -8,5 +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()
} }

View File

@@ -37,8 +37,12 @@ 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()} vr := varResolver{
c: c,
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)
@@ -63,7 +67,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, "")
if err != nil { if err != nil {
vr.err = err vr.err = err
return err return err
@@ -74,7 +78,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, _ string) (string, error) {
if v.Static != "" || v.Sh == "" { if v.Static != "" || v.Sh == "" {
return v.Static, nil return v.Static, nil
} }
@@ -92,7 +96,6 @@ 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,
Stdout: &stdout, Stdout: &stdout,
Stderr: c.Logger.Stderr, Stderr: c.Logger.Stderr,
} }
@@ -109,3 +112,11 @@ func (c *CompilerV2) HandleDynamicVar(v taskfile.Var) (string, error) {
return result, nil return result, nil
} }
// ResetCache clear the dymanic variables cache
func (c *CompilerV2) ResetCache() {
c.muDynamicCache.Lock()
defer c.muDynamicCache.Unlock()
c.dynamicCache = nil
}

View File

@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"path/filepath"
"strings" "strings"
"sync" "sync"
@@ -31,22 +32,27 @@ 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})
rangeFunc := func(k string, v taskfile.Var) error { getRangeFunc := func(dir string) func(k string, v taskfile.Var) error {
tr := templater.Templater{Vars: result, RemoveNoValue: true} return func(k string, v taskfile.Var) error {
v = taskfile.Var{ tr := templater.Templater{Vars: result, RemoveNoValue: true}
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)
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 { if err := c.TaskfileVars.Range(rangeFunc); err != nil {
return nil, err return nil, err
@@ -54,14 +60,27 @@ func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
if err := call.Vars.Range(rangeFunc); err != nil { if err := call.Vars.Range(rangeFunc); err != nil {
return nil, err 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 return nil, err
} }
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
} }
@@ -76,10 +95,15 @@ func (c *CompilerV3) HandleDynamicVar(v taskfile.Var) (string, error) {
return result, nil 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 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,
} }
@@ -96,3 +120,11 @@ func (c *CompilerV3) HandleDynamicVar(v taskfile.Var) (string, error) {
return result, nil return result, nil
} }
// ResetCache clear the dymanic variables cache
func (c *CompilerV3) ResetCache() {
c.muDynamicCache.Lock()
defer c.muDynamicCache.Unlock()
c.dynamicCache = nil
}

View File

@@ -6,9 +6,9 @@ import (
"io" "io"
"testing" "testing"
"github.com/go-task/task/v3/internal/output"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/go-task/task/v3/internal/output"
) )
func TestInterleaved(t *testing.T) { func TestInterleaved(t *testing.T) {

View File

@@ -14,7 +14,8 @@ import (
// Checksum validades if a task is up to date by calculating its source // Checksum validades if a task is up to date by calculating its source
// files checksum // files checksum
type Checksum struct { type Checksum struct {
Dir string BaseDir string
TaskDir string
Task string Task string
Sources []string Sources []string
Generates []string Generates []string
@@ -32,7 +33,7 @@ func (c *Checksum) IsUpToDate() (bool, error) {
data, _ := ioutil.ReadFile(checksumFile) data, _ := ioutil.ReadFile(checksumFile)
oldMd5 := strings.TrimSpace(string(data)) oldMd5 := strings.TrimSpace(string(data))
sources, err := globs(c.Dir, c.Sources) sources, err := globs(c.TaskDir, c.Sources)
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -43,7 +44,7 @@ func (c *Checksum) IsUpToDate() (bool, error) {
} }
if !c.Dry { if !c.Dry {
_ = os.MkdirAll(filepath.Join(c.Dir, ".task", "checksum"), 0755) _ = os.MkdirAll(filepath.Join(c.BaseDir, ".task", "checksum"), 0755)
if err = ioutil.WriteFile(checksumFile, []byte(newMd5+"\n"), 0644); err != nil { if err = ioutil.WriteFile(checksumFile, []byte(newMd5+"\n"), 0644); err != nil {
return false, err return false, err
} }
@@ -52,7 +53,7 @@ func (c *Checksum) IsUpToDate() (bool, error) {
if len(c.Generates) > 0 { if len(c.Generates) > 0 {
// For each specified 'generates' field, check whether the files actually exist // For each specified 'generates' field, check whether the files actually exist
for _, g := range c.Generates { for _, g := range c.Generates {
generates, err := glob(c.Dir, g) generates, err := glob(c.TaskDir, g)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return false, nil return false, nil
} }
@@ -107,7 +108,7 @@ func (*Checksum) Kind() string {
} }
func (c *Checksum) checksumFilePath() string { func (c *Checksum) checksumFilePath() string {
return filepath.Join(c.Dir, ".task", "checksum", c.normalizeFilename(c.Task)) return filepath.Join(c.BaseDir, ".task", "checksum", c.normalizeFilename(c.Task))
} }
var checksumFilenameRegexp = regexp.MustCompile("[^A-z0-9]") var checksumFilenameRegexp = regexp.MustCompile("[^A-z0-9]")

View File

@@ -5,9 +5,9 @@ import (
"path/filepath" "path/filepath"
"sort" "sort"
"github.com/go-task/task/v3/internal/execext"
"github.com/mattn/go-zglob" "github.com/mattn/go-zglob"
"github.com/go-task/task/v3/internal/execext"
) )
func globs(dir string, globs []string) ([]string, error) { func globs(dir string, globs []string) ([]string, error) {

View File

@@ -5,11 +5,11 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/go-task/task/v3/internal/logger" "github.com/go-task/task/v3/internal/logger"
"github.com/go-task/task/v3/internal/summary" "github.com/go-task/task/v3/internal/summary"
"github.com/go-task/task/v3/taskfile" "github.com/go-task/task/v3/taskfile"
"github.com/stretchr/testify/assert"
) )
func TestPrintsDependenciesIfPresent(t *testing.T) { func TestPrintsDependenciesIfPresent(t *testing.T) {

View File

@@ -76,7 +76,8 @@ func (e *Executor) timestampChecker(t *taskfile.Task) status.Checker {
func (e *Executor) checksumChecker(t *taskfile.Task) status.Checker { func (e *Executor) checksumChecker(t *taskfile.Task) status.Checker {
return &status.Checksum{ return &status.Checksum{
Dir: t.Dir, BaseDir: e.Dir,
TaskDir: t.Dir,
Task: t.Name(), Task: t.Name(),
Sources: t.Sources, Sources: t.Sources,
Generates: t.Generates, Generates: t.Generates,

View File

@@ -11,10 +11,10 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/go-task/task/v3" "github.com/go-task/task/v3"
"github.com/go-task/task/v3/taskfile" "github.com/go-task/task/v3/taskfile"
"github.com/stretchr/testify/assert"
) )
// fileContentTest provides a basic reusable test-case for running a Taskfile // fileContentTest provides a basic reusable test-case for running a Taskfile
@@ -303,6 +303,8 @@ 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"
@@ -310,9 +312,6 @@ func TestGenerates(t *testing.T) {
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,21 @@ 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/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)
}
func TestDisplaysErrorOnUnsupportedVersion(t *testing.T) { func TestDisplaysErrorOnUnsupportedVersion(t *testing.T) {
e := task.Executor{ e := task.Executor{
Dir: "testdata/version/v1", Dir: "testdata/version/v1",

View File

@@ -3,10 +3,10 @@ package taskfile_test
import ( import (
"testing" "testing"
"github.com/go-task/task/v3/taskfile"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/go-task/task/v3/taskfile"
) )
func TestPreconditionParse(t *testing.T) { func TestPreconditionParse(t *testing.T) {

View File

@@ -7,11 +7,11 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"github.com/go-task/task/v3/internal/templater"
"github.com/go-task/task/v3/taskfile"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/go-task/task/v3/internal/templater"
"github.com/go-task/task/v3/taskfile"
) )
var ( var (
@@ -97,6 +97,17 @@ func Taskfile(dir string, entrypoint string) (*taskfile.Taskfile, error) {
} }
if includedTask.AdvancedImport { 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 { for _, task := range includedTaskfile.Tasks {
if !filepath.IsAbs(task.Dir) { if !filepath.IsAbs(task.Dir) {
task.Dir = filepath.Join(includedTask.Dir, task.Dir) task.Dir = filepath.Join(includedTask.Dir, task.Dir)

View File

@@ -6,9 +6,9 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"github.com/go-task/task/v3/taskfile"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/go-task/task/v3/taskfile"
) )
// Taskvars reads a Taskvars for a given directory // Taskvars reads a Taskvars for a given directory

View File

@@ -3,10 +3,10 @@ package taskfile_test
import ( import (
"testing" "testing"
"github.com/go-task/task/v3/taskfile"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/go-task/task/v3/taskfile"
) )
func TestCmdParse(t *testing.T) { func TestCmdParse(t *testing.T) {

View File

@@ -98,6 +98,7 @@ type Var struct {
Static string Static string
Live interface{} Live interface{}
Sh string Sh string
Dir string
} }
// UnmarshalYAML implements yaml.Unmarshaler interface. // UnmarshalYAML implements yaml.Unmarshaler interface.

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

@@ -0,0 +1 @@
*.txt

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

@@ -0,0 +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 '{{.TASK_DIR}}' > from_root_taskfile.txt
dir: subdirectory
vars:
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)

View File

@@ -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)

View File

@@ -1,7 +1,8 @@
version: '3' version: '3'
vars: vars:
BUILD_DIR: $pwd BUILD_DIR:
sh: pwd
tasks: tasks:
abs.txt: abs.txt:

0
testdata/generates/sub/.keep vendored Normal file
View File

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(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
} }

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"os" "os"
"os/signal" "os/signal"
"path/filepath"
"strings" "strings"
"syscall" "syscall"
"time" "time"
@@ -14,10 +15,7 @@ import (
"github.com/radovskyb/watcher" "github.com/radovskyb/watcher"
) )
var watchIgnoredDirs = []string{ const watchInterval = 5 * time.Second
".git",
"node_modules",
}
// watchTasks start watching the given tasks // watchTasks start watching the given tasks
func (e *Executor) watchTasks(calls ...taskfile.Call) error { func (e *Executor) watchTasks(calls ...taskfile.Call) error {
@@ -40,9 +38,6 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
w := watcher.New() w := watcher.New()
defer w.Close() defer w.Close()
w.SetMaxEvents(1) w.SetMaxEvents(1)
if err := w.Ignore(watchIgnoredDirs...); err != nil {
return err
}
closeOnInterrupt(w) closeOnInterrupt(w)
@@ -54,6 +49,9 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
cancel() cancel()
ctx, cancel = context.WithCancel(context.Background()) ctx, cancel = context.WithCancel(context.Background())
e.Compiler.ResetCache()
for _, c := range calls { for _, c := range calls {
c := c c := c
go func() { go func() {
@@ -65,9 +63,6 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
case err := <-w.Error: case err := <-w.Error:
switch err { switch err {
case watcher.ErrWatchedFileDeleted: case watcher.ErrWatchedFileDeleted:
go func() {
w.TriggerEvent(watcher.Remove, nil)
}()
default: default:
e.Logger.Errf(logger.Red, "%v", err) e.Logger.Errf(logger.Red, "%v", err)
} }
@@ -79,16 +74,16 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
}() }()
go func() { go func() {
// re-register each second because we can have new files // re-register every 5 seconds because we can have new files, but this process is expensive to run
for { for {
if err := e.registerWatchedFiles(w, calls...); err != nil { if err := e.registerWatchedFiles(w, calls...); err != nil {
e.Logger.Errf(logger.Red, "%v", err) e.Logger.Errf(logger.Red, "%v", err)
} }
time.Sleep(time.Second) time.Sleep(watchInterval)
} }
}() }()
return w.Start(time.Second) return w.Start(watchInterval)
} }
func isContextError(err error) bool { func isContextError(err error) bool {
@@ -109,16 +104,7 @@ func closeOnInterrupt(w *watcher.Watcher) {
} }
func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Call) error { func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Call) error {
oldWatchedFiles := make(map[string]struct{}) watchedFiles := w.WatchedFiles()
for f := range w.WatchedFiles() {
oldWatchedFiles[f] = struct{}{}
}
for f := range oldWatchedFiles {
if err := w.Remove(f); err != nil {
return err
}
}
var registerTaskFiles func(taskfile.Call) error var registerTaskFiles func(taskfile.Call) error
registerTaskFiles = func(c taskfile.Call) error { registerTaskFiles = func(c taskfile.Call) error {
@@ -146,12 +132,20 @@ func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Ca
return err return err
} }
for _, f := range files { for _, f := range files {
if _, ok := oldWatchedFiles[f]; ok { absFile, err := filepath.Abs(f)
continue if err != nil {
}
if err := w.Add(f); err != nil {
return err return err
} }
if shouldIgnoreFile(absFile) {
continue
}
if _, ok := watchedFiles[absFile]; ok {
continue
}
if err := w.Add(absFile); err != nil {
return err
}
e.Logger.VerboseOutf(logger.Green, "task: watching new file: %v", absFile)
} }
} }
return nil return nil
@@ -164,3 +158,7 @@ func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Ca
} }
return nil return nil
} }
func shouldIgnoreFile(path string) bool {
return strings.Contains(path, "/.git") || strings.Contains(path, "/.task") || strings.Contains(path, "/node_modules")
}