2017-02-27 21:44:08 +02:00
|
|
|
package task
|
|
|
|
|
|
|
|
import (
|
2017-07-16 21:15:29 +02:00
|
|
|
"context"
|
2017-09-16 16:44:13 +02:00
|
|
|
"fmt"
|
2017-02-27 21:44:08 +02:00
|
|
|
|
2020-08-16 20:48:19 +02:00
|
|
|
"github.com/go-task/task/v3/internal/execext"
|
|
|
|
"github.com/go-task/task/v3/internal/logger"
|
|
|
|
"github.com/go-task/task/v3/internal/status"
|
2020-08-19 10:59:58 +02:00
|
|
|
"github.com/go-task/task/v3/taskfile"
|
2017-02-27 21:44:08 +02:00
|
|
|
)
|
|
|
|
|
2017-12-27 01:43:52 +02:00
|
|
|
// Status returns an error if any the of given tasks is not up-to-date
|
2019-02-09 14:16:13 +02:00
|
|
|
func (e *Executor) Status(ctx context.Context, calls ...taskfile.Call) error {
|
2017-12-27 01:43:52 +02:00
|
|
|
for _, call := range calls {
|
2018-10-06 22:55:23 +02:00
|
|
|
t, err := e.CompiledTask(call)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2017-12-27 01:43:52 +02:00
|
|
|
}
|
2019-02-09 14:41:19 +02:00
|
|
|
isUpToDate, err := e.isTaskUpToDate(ctx, t)
|
2017-12-27 01:43:52 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !isUpToDate {
|
2020-06-03 22:19:12 +02:00
|
|
|
return fmt.Errorf(`task: Task "%s" is not up-to-date`, t.Name())
|
2017-12-27 01:43:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-02-09 14:41:19 +02:00
|
|
|
func (e *Executor) isTaskUpToDate(ctx context.Context, t *taskfile.Task) (bool, error) {
|
2021-07-11 02:58:03 +02:00
|
|
|
if len(t.Status) == 0 && len(t.Sources) == 0 {
|
|
|
|
return false, nil
|
|
|
|
}
|
2021-04-20 15:04:21 +02:00
|
|
|
|
2017-07-16 21:15:29 +02:00
|
|
|
if len(t.Status) > 0 {
|
2021-04-20 15:04:21 +02:00
|
|
|
isUpToDate, err := e.isTaskUpToDateStatus(ctx, t)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
if !isUpToDate {
|
|
|
|
return false, nil
|
|
|
|
}
|
2017-07-16 21:15:29 +02:00
|
|
|
}
|
2017-09-16 16:44:13 +02:00
|
|
|
|
2021-04-20 15:04:21 +02:00
|
|
|
if len(t.Sources) > 0 {
|
|
|
|
checker, err := e.getStatusChecker(t)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
isUpToDate, err := checker.IsUpToDate()
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
if !isUpToDate {
|
|
|
|
return false, nil
|
|
|
|
}
|
2017-09-16 16:44:13 +02:00
|
|
|
}
|
|
|
|
|
2021-07-11 02:58:03 +02:00
|
|
|
return true, nil
|
2017-09-16 16:44:13 +02:00
|
|
|
}
|
|
|
|
|
2019-02-09 14:41:19 +02:00
|
|
|
func (e *Executor) statusOnError(t *taskfile.Task) error {
|
|
|
|
checker, err := e.getStatusChecker(t)
|
2017-09-16 16:44:13 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return checker.OnError()
|
|
|
|
}
|
|
|
|
|
2019-02-09 14:41:19 +02:00
|
|
|
func (e *Executor) getStatusChecker(t *taskfile.Task) (status.Checker, error) {
|
2019-09-09 03:26:24 +02:00
|
|
|
method := t.Method
|
|
|
|
if method == "" {
|
|
|
|
method = e.Taskfile.Method
|
|
|
|
}
|
|
|
|
switch method {
|
2019-09-09 03:51:56 +02:00
|
|
|
case "timestamp":
|
2019-09-14 23:04:41 +02:00
|
|
|
return e.timestampChecker(t), nil
|
2017-09-16 16:44:13 +02:00
|
|
|
case "checksum":
|
2019-09-14 23:04:41 +02:00
|
|
|
return e.checksumChecker(t), nil
|
2017-09-16 16:44:13 +02:00
|
|
|
case "none":
|
|
|
|
return status.None{}, nil
|
|
|
|
default:
|
2019-09-09 03:26:24 +02:00
|
|
|
return nil, fmt.Errorf(`task: invalid method "%s"`, method)
|
2017-09-16 16:44:13 +02:00
|
|
|
}
|
2017-07-16 21:15:29 +02:00
|
|
|
}
|
|
|
|
|
2019-09-14 23:04:41 +02:00
|
|
|
func (e *Executor) timestampChecker(t *taskfile.Task) status.Checker {
|
|
|
|
return &status.Timestamp{
|
|
|
|
Dir: t.Dir,
|
|
|
|
Sources: t.Sources,
|
|
|
|
Generates: t.Generates,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Executor) checksumChecker(t *taskfile.Task) status.Checker {
|
|
|
|
return &status.Checksum{
|
2021-01-07 16:36:09 +02:00
|
|
|
BaseDir: e.Dir,
|
|
|
|
TaskDir: t.Dir,
|
2021-01-04 00:22:38 +02:00
|
|
|
Task: t.Name(),
|
2019-09-14 23:04:41 +02:00
|
|
|
Sources: t.Sources,
|
|
|
|
Generates: t.Generates,
|
|
|
|
Dry: e.Dry,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-09 14:41:19 +02:00
|
|
|
func (e *Executor) isTaskUpToDateStatus(ctx context.Context, t *taskfile.Task) (bool, error) {
|
2017-07-16 21:15:29 +02:00
|
|
|
for _, s := range t.Status {
|
2018-09-01 16:02:23 +02:00
|
|
|
err := execext.RunCommand(ctx, &execext.RunCommandOptions{
|
2017-07-16 21:15:29 +02:00
|
|
|
Command: s,
|
2017-07-31 00:45:01 +02:00
|
|
|
Dir: t.Dir,
|
2018-02-17 18:22:18 +02:00
|
|
|
Env: getEnviron(t),
|
2017-07-16 21:15:29 +02:00
|
|
|
})
|
|
|
|
if err != nil {
|
2019-06-16 03:47:15 +02:00
|
|
|
e.Logger.VerboseOutf(logger.Yellow, "task: status command %s exited non-zero: %s", s, err)
|
2017-07-16 21:15:29 +02:00
|
|
|
return false, nil
|
|
|
|
}
|
2019-06-16 03:47:15 +02:00
|
|
|
e.Logger.VerboseOutf(logger.Yellow, "task: status command %s exited zero", s)
|
2017-07-16 21:15:29 +02:00
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
}
|