diff --git a/CHANGELOG.md b/CHANGELOG.md index 9be6fb29..c599fc88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Fixed panic bug when assigning a global variable ([#229](https://github.com/go-task/task/issues/229), [#243](https://github.com/go-task/task/issues/234)). +- A task with `method: checksum` will now re-run if generated files are deleted + ([#228](https://github.com/go-task/task/pull/228), [#238](https://github.com/go-task/task/issues/238)). ## v2.6.0 - 2019-07-21 diff --git a/internal/status/checksum.go b/internal/status/checksum.go index 44331047..572d4650 100644 --- a/internal/status/checksum.go +++ b/internal/status/checksum.go @@ -14,10 +14,11 @@ import ( // Checksum validades if a task is up to date by calculating its source // files checksum type Checksum struct { - Dir string - Task string - Sources []string - Dry bool + Dir string + Task string + Sources []string + Generates []string + Dry bool } // IsUpToDate implements the Checker interface @@ -27,7 +28,7 @@ func (c *Checksum) IsUpToDate() (bool, error) { data, _ := ioutil.ReadFile(checksumFile) oldMd5 := strings.TrimSpace(string(data)) - sources, err := glob(c.Dir, c.Sources) + sources, err := globs(c.Dir, c.Sources) if err != nil { return false, err } @@ -43,6 +44,23 @@ func (c *Checksum) IsUpToDate() (bool, error) { return false, err } } + + if len(c.Generates) > 0 { + // For each specified 'generates' field, check whether the files actually exist + for _, g := range c.Generates { + generates, err := glob(c.Dir, g) + if os.IsNotExist(err) { + return false, nil + } + if err != nil { + return false, err + } + if len(generates) == 0 { + return false, nil + } + } + } + return oldMd5 == newMd5, nil } @@ -50,21 +68,14 @@ func (c *Checksum) checksum(files ...string) (string, error) { h := md5.New() for _, f := range files { + // also sum the filename, so checksum changes for renaming a file + if _, err := io.Copy(h, strings.NewReader(filepath.Base(f))); err != nil { + return "", err + } f, err := os.Open(f) if err != nil { return "", err } - info, err := f.Stat() - if err != nil { - return "", err - } - if info.IsDir() { - continue - } - // also sum the filename, so checksum changes for renaming a file - if _, err = io.Copy(h, strings.NewReader(info.Name())); err != nil { - return "", err - } if _, err = io.Copy(h, f); err != nil { return "", err } diff --git a/internal/status/glob.go b/internal/status/glob.go index 305e0f9b..a70f663d 100644 --- a/internal/status/glob.go +++ b/internal/status/glob.go @@ -1,6 +1,7 @@ package status import ( + "os" "path/filepath" "sort" @@ -9,21 +10,41 @@ import ( "github.com/mattn/go-zglob" ) -func glob(dir string, globs []string) (files []string, err error) { +func globs(dir string, globs []string) ([]string, error) { + files := make([]string, 0) for _, g := range globs { - if !filepath.IsAbs(g) { - g = filepath.Join(dir, g) - } - g, err = execext.Expand(g) - if err != nil { - return nil, err - } - f, err := zglob.Glob(g) + f, err := glob(dir, g) if err != nil { continue } files = append(files, f...) } sort.Strings(files) - return + return files, nil +} + +func glob(dir string, g string) ([]string, error) { + files := make([]string, 0) + if !filepath.IsAbs(g) { + g = filepath.Join(dir, g) + } + g, err := execext.Expand(g) + if err != nil { + return nil, err + } + fs, err := zglob.Glob(g) + if err != nil { + return nil, err + } + for _, f := range fs { + info, err := os.Stat(f) + if err != nil { + return nil, err + } + if info.IsDir() { + continue + } + files = append(files, f) + } + return files, nil } diff --git a/internal/status/timestamp.go b/internal/status/timestamp.go index 62b9aafb..fcc52f6a 100644 --- a/internal/status/timestamp.go +++ b/internal/status/timestamp.go @@ -19,11 +19,11 @@ func (t *Timestamp) IsUpToDate() (bool, error) { return false, nil } - sources, err := glob(t.Dir, t.Sources) + sources, err := globs(t.Dir, t.Sources) if err != nil { return false, nil } - generates, err := glob(t.Dir, t.Generates) + generates, err := globs(t.Dir, t.Generates) if err != nil { return false, nil } diff --git a/status.go b/status.go index 7ebb5f84..51d0e4cb 100644 --- a/status.go +++ b/status.go @@ -58,10 +58,11 @@ func (e *Executor) getStatusChecker(t *taskfile.Task) (status.Checker, error) { }, nil case "checksum": return &status.Checksum{ - Dir: t.Dir, - Task: t.Task, - Sources: t.Sources, - Dry: e.Dry, + Dir: t.Dir, + Task: t.Task, + Sources: t.Sources, + Generates: t.Generates, + Dry: e.Dry, }, nil case "none": return status.None{}, nil