diff --git a/internal/status/checksum.go b/internal/status/checksum.go index 44331047..653a8e35 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,20 @@ 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 err != nil { + return false, nil + } + if len(generates) == 0 { + return false, nil + } + } + } + return oldMd5 == newMd5, nil } @@ -50,21 +65,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..b46f7616 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,42 @@ 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 { + continue + } + if info.IsDir() { + continue + } + files = append(files, f) + } + sort.Strings(files) + 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