mirror of
https://github.com/go-task/task.git
synced 2025-02-03 13:22:11 +02:00
accept setting dir of execution and improve tests
One test is not yet migrated. First we should have specific Stdin, Stdout and Stderr for executor.
This commit is contained in:
parent
7e06ba1728
commit
81e0f170ef
7
file.go
7
file.go
@ -2,6 +2,7 @@ package task
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mattn/go-zglob"
|
"github.com/mattn/go-zglob"
|
||||||
@ -20,8 +21,9 @@ func maxTime(a, b time.Time) time.Time {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPatternsMinTime(patterns []string) (m time.Time, err error) {
|
func getPatternsMinTime(dir string, patterns []string) (m time.Time, err error) {
|
||||||
for _, p := range patterns {
|
for _, p := range patterns {
|
||||||
|
p = filepath.Join(dir, p)
|
||||||
mp, err := getPatternMinTime(p)
|
mp, err := getPatternMinTime(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
@ -30,8 +32,9 @@ func getPatternsMinTime(patterns []string) (m time.Time, err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func getPatternsMaxTime(patterns []string) (m time.Time, err error) {
|
func getPatternsMaxTime(dir string, patterns []string) (m time.Time, err error) {
|
||||||
for _, p := range patterns {
|
for _, p := range patterns {
|
||||||
|
p = filepath.Join(dir, p)
|
||||||
mp, err := getPatternMaxTime(p)
|
mp, err := getPatternMaxTime(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
@ -13,13 +14,15 @@ import (
|
|||||||
|
|
||||||
// ReadTaskfile parses Taskfile from the disk
|
// ReadTaskfile parses Taskfile from the disk
|
||||||
func (e *Executor) ReadTaskfile() error {
|
func (e *Executor) ReadTaskfile() error {
|
||||||
|
path := filepath.Join(e.Dir, TaskFilePath)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
e.Tasks, err = e.readTaskfileData(TaskFilePath)
|
e.Tasks, err = e.readTaskfileData(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
osTasks, err := e.readTaskfileData(fmt.Sprintf("%s_%s", TaskFilePath, runtime.GOOS))
|
osTasks, err := e.readTaskfileData(fmt.Sprintf("%s_%s", path, runtime.GOOS))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case taskFileNotFound:
|
case taskFileNotFound:
|
||||||
|
76
task.go
76
task.go
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-task/task/execext"
|
"github.com/go-task/task/execext"
|
||||||
@ -21,6 +22,7 @@ const (
|
|||||||
// Executor executes a Taskfile
|
// Executor executes a Taskfile
|
||||||
type Executor struct {
|
type Executor struct {
|
||||||
Tasks Tasks
|
Tasks Tasks
|
||||||
|
Dir string
|
||||||
Force bool
|
Force bool
|
||||||
Watch bool
|
Watch bool
|
||||||
|
|
||||||
@ -86,7 +88,7 @@ func (e *Executor) RunTask(ctx context.Context, name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !e.Force {
|
if !e.Force {
|
||||||
upToDate, err := t.isUpToDate(ctx)
|
upToDate, err := e.isTaskUpToDate(ctx, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -112,7 +114,7 @@ func (e *Executor) runDeps(ctx context.Context, task string) error {
|
|||||||
dep := d
|
dep := d
|
||||||
|
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
dep, err := t.ReplaceVariables(dep)
|
dep, err := e.ReplaceVariables(task, dep)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -130,15 +132,23 @@ func (e *Executor) runDeps(ctx context.Context, task string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) isUpToDate(ctx context.Context) (bool, error) {
|
func (e *Executor) isTaskUpToDate(ctx context.Context, task string) (bool, error) {
|
||||||
|
t := e.Tasks[task]
|
||||||
|
|
||||||
if len(t.Status) > 0 {
|
if len(t.Status) > 0 {
|
||||||
return t.isUpToDateStatus(ctx)
|
return e.isUpToDateStatus(ctx, task)
|
||||||
}
|
}
|
||||||
return t.isUpToDateTimestamp(ctx)
|
return e.isUpToDateTimestamp(ctx, task)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) isUpToDateStatus(ctx context.Context) (bool, error) {
|
func (e *Executor) isUpToDateStatus(ctx context.Context, task string) (bool, error) {
|
||||||
environ, err := t.getEnviron()
|
t := e.Tasks[task]
|
||||||
|
|
||||||
|
environ, err := e.getEnviron(task)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
dir, err := e.getTaskDir(task)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -147,7 +157,7 @@ func (t *Task) isUpToDateStatus(ctx context.Context) (bool, error) {
|
|||||||
err = execext.RunCommand(&execext.RunCommandOptions{
|
err = execext.RunCommand(&execext.RunCommandOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
Command: s,
|
Command: s,
|
||||||
Dir: t.Dir,
|
Dir: dir,
|
||||||
Env: environ,
|
Env: environ,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -157,26 +167,33 @@ func (t *Task) isUpToDateStatus(ctx context.Context) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) isUpToDateTimestamp(ctx context.Context) (bool, error) {
|
func (e *Executor) isUpToDateTimestamp(ctx context.Context, task string) (bool, error) {
|
||||||
|
t := e.Tasks[task]
|
||||||
|
|
||||||
if len(t.Sources) == 0 || len(t.Generates) == 0 {
|
if len(t.Sources) == 0 || len(t.Generates) == 0 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sources, err := t.ReplaceSliceVariables(t.Sources)
|
dir, err := e.getTaskDir(task)
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
generates, err := t.ReplaceSliceVariables(t.Generates)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sourcesMaxTime, err := getPatternsMaxTime(sources)
|
sources, err := e.ReplaceSliceVariables(task, t.Sources)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
generates, err := e.ReplaceSliceVariables(task, t.Generates)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sourcesMaxTime, err := getPatternsMaxTime(dir, sources)
|
||||||
if err != nil || sourcesMaxTime.IsZero() {
|
if err != nil || sourcesMaxTime.IsZero() {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
generatesMinTime, err := getPatternsMinTime(generates)
|
generatesMinTime, err := getPatternsMinTime(dir, generates)
|
||||||
if err != nil || generatesMinTime.IsZero() {
|
if err != nil || generatesMinTime.IsZero() {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@ -187,7 +204,7 @@ func (t *Task) isUpToDateTimestamp(ctx context.Context) (bool, error) {
|
|||||||
func (e *Executor) runCommand(ctx context.Context, task string, i int) error {
|
func (e *Executor) runCommand(ctx context.Context, task string, i int) error {
|
||||||
t := e.Tasks[task]
|
t := e.Tasks[task]
|
||||||
|
|
||||||
c, err := t.ReplaceVariables(t.Cmds[i])
|
c, err := e.ReplaceVariables(task, t.Cmds[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -200,12 +217,12 @@ func (e *Executor) runCommand(ctx context.Context, task string, i int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
dir, err := t.ReplaceVariables(t.Dir)
|
dir, err := e.getTaskDir(task)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
envs, err := t.getEnviron()
|
envs, err := e.getEnviron(task)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -235,7 +252,24 @@ func (e *Executor) runCommand(ctx context.Context, task string, i int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) getEnviron() ([]string, error) {
|
func (e *Executor) getTaskDir(name string) (string, error) {
|
||||||
|
t := e.Tasks[name]
|
||||||
|
|
||||||
|
exeDir, err := e.ReplaceVariables(name, e.Dir)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
taskDir, err := e.ReplaceVariables(name, t.Dir)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Join(exeDir, taskDir), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Executor) getEnviron(task string) ([]string, error) {
|
||||||
|
t := e.Tasks[task]
|
||||||
|
|
||||||
if t.Env == nil {
|
if t.Env == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -243,7 +277,7 @@ func (t *Task) getEnviron() ([]string, error) {
|
|||||||
envs := os.Environ()
|
envs := os.Environ()
|
||||||
|
|
||||||
for k, v := range t.Env {
|
for k, v := range t.Env {
|
||||||
env, err := t.ReplaceVariables(fmt.Sprintf("%s=%s", k, v))
|
env, err := e.ReplaceVariables(task, fmt.Sprintf("%s=%s", k, v))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
33
task_test.go
33
task_test.go
@ -8,6 +8,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-task/task"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDeps(t *testing.T) {
|
func TestDeps(t *testing.T) {
|
||||||
@ -32,12 +36,11 @@ func TestDeps(t *testing.T) {
|
|||||||
_ = os.Remove(filepath.Join(dir, f))
|
_ = os.Remove(filepath.Join(dir, f))
|
||||||
}
|
}
|
||||||
|
|
||||||
c := exec.Command("task")
|
e := &task.Executor{
|
||||||
c.Dir = dir
|
Dir: dir,
|
||||||
if err := c.Run(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
assert.NoError(t, e.ReadTaskfile())
|
||||||
|
assert.NoError(t, e.Run("default"))
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
f = filepath.Join(dir, f)
|
f = filepath.Join(dir, f)
|
||||||
@ -65,13 +68,11 @@ func TestVars(t *testing.T) {
|
|||||||
_ = os.Remove(filepath.Join(dir, f.file))
|
_ = os.Remove(filepath.Join(dir, f.file))
|
||||||
}
|
}
|
||||||
|
|
||||||
c := exec.Command("task")
|
e := &task.Executor{
|
||||||
c.Dir = dir
|
Dir: dir,
|
||||||
|
|
||||||
if err := c.Run(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
assert.NoError(t, e.ReadTaskfile())
|
||||||
|
assert.NoError(t, e.Run("default"))
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
d, err := ioutil.ReadFile(filepath.Join(dir, f.file))
|
d, err := ioutil.ReadFile(filepath.Join(dir, f.file))
|
||||||
@ -99,13 +100,11 @@ func TestTaskCall(t *testing.T) {
|
|||||||
_ = os.Remove(filepath.Join(dir, f))
|
_ = os.Remove(filepath.Join(dir, f))
|
||||||
}
|
}
|
||||||
|
|
||||||
c := exec.Command("task")
|
e := &task.Executor{
|
||||||
c.Dir = dir
|
Dir: dir,
|
||||||
|
|
||||||
if err := c.Run(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
assert.NoError(t, e.ReadTaskfile())
|
||||||
|
assert.NoError(t, e.Run("default"))
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if _, err := os.Stat(filepath.Join(dir, f)); err != nil {
|
if _, err := os.Stat(filepath.Join(dir, f)); err != nil {
|
||||||
|
@ -25,7 +25,7 @@ var (
|
|||||||
ErrMultilineResultCmd = errors.New("Got multiline result from command")
|
ErrMultilineResultCmd = errors.New("Got multiline result from command")
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleDynamicVariableContent(value string) (string, error) {
|
func (e *Executor) handleDynamicVariableContent(value string) (string, error) {
|
||||||
if !strings.HasPrefix(value, "$") {
|
if !strings.HasPrefix(value, "$") {
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
@ -34,6 +34,7 @@ func handleDynamicVariableContent(value string) (string, error) {
|
|||||||
|
|
||||||
opts := &execext.RunCommandOptions{
|
opts := &execext.RunCommandOptions{
|
||||||
Command: strings.TrimPrefix(value, "$"),
|
Command: strings.TrimPrefix(value, "$"),
|
||||||
|
Dir: e.Dir,
|
||||||
Stdout: buff,
|
Stdout: buff,
|
||||||
Stderr: os.Stderr,
|
Stderr: os.Stderr,
|
||||||
}
|
}
|
||||||
@ -51,18 +52,20 @@ func handleDynamicVariableContent(value string) (string, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) getVariables() (map[string]string, error) {
|
func (e *Executor) getVariables(task string) (map[string]string, error) {
|
||||||
|
t := e.Tasks[task]
|
||||||
|
|
||||||
localVariables := make(map[string]string)
|
localVariables := make(map[string]string)
|
||||||
for key, value := range t.Vars {
|
for key, value := range t.Vars {
|
||||||
val, err := handleDynamicVariableContent(value)
|
val, err := e.handleDynamicVariableContent(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
localVariables[key] = val
|
localVariables[key] = val
|
||||||
}
|
}
|
||||||
if fileVariables, err := readTaskvarsFile(); err == nil {
|
if fileVariables, err := e.readTaskvarsFile(); err == nil {
|
||||||
for key, value := range fileVariables {
|
for key, value := range fileVariables {
|
||||||
val, err := handleDynamicVariableContent(value)
|
val, err := e.handleDynamicVariableContent(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -106,11 +109,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReplaceSliceVariables writes vars into initial string slice
|
// ReplaceSliceVariables writes vars into initial string slice
|
||||||
func (t *Task) ReplaceSliceVariables(initials []string) ([]string, error) {
|
func (e *Executor) ReplaceSliceVariables(task string, initials []string) ([]string, error) {
|
||||||
result := make([]string, len(initials))
|
result := make([]string, len(initials))
|
||||||
for i, s := range initials {
|
for i, s := range initials {
|
||||||
var err error
|
var err error
|
||||||
result[i], err = t.ReplaceVariables(s)
|
result[i], err = e.ReplaceVariables(task, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -119,8 +122,8 @@ func (t *Task) ReplaceSliceVariables(initials []string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReplaceVariables writes vars into initial string
|
// ReplaceVariables writes vars into initial string
|
||||||
func (t *Task) ReplaceVariables(initial string) (string, error) {
|
func (e *Executor) ReplaceVariables(task, initial string) (string, error) {
|
||||||
vars, err := t.getVariables()
|
vars, err := e.getVariables(task)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -152,21 +155,23 @@ func getEnvironmentVariables() map[string]string {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func readTaskvarsFile() (map[string]string, error) {
|
func (e *Executor) readTaskvarsFile() (map[string]string, error) {
|
||||||
|
file := filepath.Join(e.Dir, TaskvarsFilePath)
|
||||||
|
|
||||||
var variables map[string]string
|
var variables map[string]string
|
||||||
if b, err := ioutil.ReadFile(TaskvarsFilePath + ".yml"); err == nil {
|
if b, err := ioutil.ReadFile(file + ".yml"); err == nil {
|
||||||
if err := yaml.Unmarshal(b, &variables); err != nil {
|
if err := yaml.Unmarshal(b, &variables); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return variables, nil
|
return variables, nil
|
||||||
}
|
}
|
||||||
if b, err := ioutil.ReadFile(TaskvarsFilePath + ".json"); err == nil {
|
if b, err := ioutil.ReadFile(file + ".json"); err == nil {
|
||||||
if err := json.Unmarshal(b, &variables); err != nil {
|
if err := json.Unmarshal(b, &variables); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return variables, nil
|
return variables, nil
|
||||||
}
|
}
|
||||||
if b, err := ioutil.ReadFile(TaskvarsFilePath + ".toml"); err == nil {
|
if b, err := ioutil.ReadFile(file + ".toml"); err == nil {
|
||||||
if err := toml.Unmarshal(b, &variables); err != nil {
|
if err := toml.Unmarshal(b, &variables); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user