mirror of
https://github.com/magefile/mage.git
synced 2026-10-24 06:19:18 +03:00
* Add mg.Target This function allows specifying files/directories as targets and returns true when the targets are met and false otherwise. Targets are met if the ModTime of src is older than any ModTime of any of the specified targets. For recursive checks of directory with its file contents set recusive argument to true
123 lines
2.4 KiB
Go
123 lines
2.4 KiB
Go
package target
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
// Path reports if any of the sources have been modified more recently
|
|
// than the destination. Path does not descend into directories, it literally
|
|
// just checks the modtime of each thing you pass to it.
|
|
func Path(dst string, sources ...string) (bool, error) {
|
|
stat, err := os.Stat(dst)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
srcTime := stat.ModTime()
|
|
dt, err := loadTargets(sources)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
t := dt.modTime()
|
|
if t.After(srcTime) {
|
|
return true, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
// Dir reports whether any of the sources have been modified
|
|
// more recently than the destination. If a source or destination is
|
|
// a directory, modtimes of files under those directories are compared
|
|
// instead.
|
|
func Dir(dst string, sources ...string) (bool, error) {
|
|
stat, err := os.Stat(dst)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
srcTime := stat.ModTime()
|
|
if stat.IsDir() {
|
|
srcTime, err = calDirModTimeRecursive(stat)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
dt, err := loadTargets(sources)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
t, err := dt.modTimeDir()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if t.After(srcTime) {
|
|
return true, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func calDirModTimeRecursive(dir os.FileInfo) (time.Time, error) {
|
|
t := dir.ModTime()
|
|
ferr := filepath.Walk(dir.Name(), func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if info.ModTime().After(t) {
|
|
t = info.ModTime()
|
|
}
|
|
return nil
|
|
})
|
|
if ferr != nil {
|
|
return time.Time{}, ferr
|
|
}
|
|
return t, nil
|
|
}
|
|
|
|
type depTargets struct {
|
|
src []os.FileInfo
|
|
hasdir bool
|
|
latest time.Time
|
|
}
|
|
|
|
func loadTargets(targets []string) (*depTargets, error) {
|
|
d := &depTargets{}
|
|
for _, v := range targets {
|
|
stat, err := os.Stat(v)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if stat.IsDir() {
|
|
d.hasdir = true
|
|
}
|
|
d.src = append(d.src, stat)
|
|
if stat.ModTime().After(d.latest) {
|
|
d.latest = stat.ModTime()
|
|
}
|
|
}
|
|
return d, nil
|
|
}
|
|
|
|
func (d *depTargets) modTime() time.Time {
|
|
return d.latest
|
|
}
|
|
|
|
func (d *depTargets) modTimeDir() (time.Time, error) {
|
|
if !d.hasdir {
|
|
return d.latest, nil
|
|
}
|
|
var err error
|
|
for _, i := range d.src {
|
|
t := i.ModTime()
|
|
if i.IsDir() {
|
|
t, err = calDirModTimeRecursive(i)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
}
|
|
if t.After(d.latest) {
|
|
d.latest = t
|
|
}
|
|
}
|
|
return d.latest, nil
|
|
}
|