1
0
mirror of https://github.com/go-task/task.git synced 2025-01-12 04:34:11 +02:00
task/status.go

133 lines
2.6 KiB
Go

package task
import (
"context"
"os"
"path/filepath"
"time"
"github.com/go-task/task/execext"
"github.com/mattn/go-zglob"
)
func (e *Executor) isTaskUpToDate(ctx context.Context, t *Task) (bool, error) {
if len(t.Status) > 0 {
return e.isUpToDateStatus(ctx, t)
}
return e.isUpToDateTimestamp(ctx, t)
}
func (e *Executor) isUpToDateStatus(ctx context.Context, t *Task) (bool, error) {
for _, s := range t.Status {
err := execext.RunCommand(&execext.RunCommandOptions{
Context: ctx,
Command: s,
Dir: e.getTaskDir(t),
Env: e.getEnviron(t),
})
if err != nil {
return false, nil
}
}
return true, nil
}
func (e *Executor) isUpToDateTimestamp(ctx context.Context, t *Task) (bool, error) {
if len(t.Sources) == 0 || len(t.Generates) == 0 {
return false, nil
}
dir := e.getTaskDir(t)
sourcesMaxTime, err := getPatternsMaxTime(dir, t.Sources)
if err != nil || sourcesMaxTime.IsZero() {
return false, nil
}
generatesMinTime, err := getPatternsMinTime(dir, t.Generates)
if err != nil || generatesMinTime.IsZero() {
return false, nil
}
return !generatesMinTime.Before(sourcesMaxTime), nil
}
func minTime(a, b time.Time) time.Time {
if !a.IsZero() && a.Before(b) {
return a
}
return b
}
func maxTime(a, b time.Time) time.Time {
if a.After(b) {
return a
}
return b
}
func getPatternsMinTime(dir string, patterns []string) (m time.Time, err error) {
for _, p := range patterns {
if !filepath.IsAbs(p) {
p = filepath.Join(dir, p)
}
mp, err := getPatternMinTime(p)
if err != nil {
return time.Time{}, err
}
m = minTime(m, mp)
}
return
}
func getPatternsMaxTime(dir string, patterns []string) (m time.Time, err error) {
for _, p := range patterns {
if !filepath.IsAbs(p) {
p = filepath.Join(dir, p)
}
mp, err := getPatternMaxTime(p)
if err != nil {
return time.Time{}, err
}
m = maxTime(m, mp)
}
return
}
func getPatternMinTime(pattern string) (minTime time.Time, err error) {
files, err := zglob.Glob(pattern)
if err != nil {
return time.Time{}, err
}
for _, f := range files {
info, err := os.Stat(f)
if err != nil {
return time.Time{}, err
}
modTime := info.ModTime()
if minTime.IsZero() || modTime.Before(minTime) {
minTime = modTime
}
}
return
}
func getPatternMaxTime(pattern string) (maxTime time.Time, err error) {
files, err := zglob.Glob(pattern)
if err != nil {
return time.Time{}, err
}
for _, f := range files {
info, err := os.Stat(f)
if err != nil {
return time.Time{}, err
}
modTime := info.ModTime()
if modTime.After(maxTime) {
maxTime = modTime
}
}
return
}