1
0
mirror of https://github.com/go-task/task.git synced 2025-01-06 03:53:54 +02:00

Move all structs related to Taskfile to its own package

This commit is contained in:
Andrey Nering 2018-02-17 14:22:18 -02:00
parent 3212ae4713
commit 152fc0ad38
16 changed files with 223 additions and 203 deletions

View File

@ -7,3 +7,4 @@ GO_PACKAGES:
./internal/args
./internal/execext
./internal/status
./internal/taskfile

View File

@ -4,6 +4,8 @@ import (
"fmt"
"sort"
"text/tabwriter"
"github.com/go-task/task/internal/taskfile"
)
// PrintTasksHelp prints help os tasks that have a description
@ -23,8 +25,8 @@ func (e *Executor) PrintTasksHelp() {
w.Flush()
}
func (e *Executor) tasksWithDesc() (tasks []*Task) {
tasks = make([]*Task, 0, len(e.Taskfile.Tasks))
func (e *Executor) tasksWithDesc() (tasks []*taskfile.Task) {
tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
for _, task := range e.Taskfile.Tasks {
if task.Desc != "" {
tasks = append(tasks, task)

View File

@ -4,7 +4,7 @@ import (
"errors"
"strings"
"github.com/go-task/task"
"github.com/go-task/task/internal/taskfile"
)
var (
@ -13,12 +13,12 @@ var (
)
// Parse parses command line argument: tasks and vars of each task
func Parse(args ...string) ([]task.Call, error) {
var calls []task.Call
func Parse(args ...string) ([]taskfile.Call, error) {
var calls []taskfile.Call
for _, arg := range args {
if !strings.Contains(arg, "=") {
calls = append(calls, task.Call{Task: arg})
calls = append(calls, taskfile.Call{Task: arg})
continue
}
if len(calls) < 1 {
@ -26,11 +26,11 @@ func Parse(args ...string) ([]task.Call, error) {
}
if calls[len(calls)-1].Vars == nil {
calls[len(calls)-1].Vars = make(task.Vars)
calls[len(calls)-1].Vars = make(taskfile.Vars)
}
pair := strings.SplitN(arg, "=", 2)
calls[len(calls)-1].Vars[pair[0]] = task.Var{Static: pair[1]}
calls[len(calls)-1].Vars[pair[0]] = taskfile.Var{Static: pair[1]}
}
return calls, nil
}

View File

@ -4,8 +4,8 @@ import (
"fmt"
"testing"
"github.com/go-task/task"
"github.com/go-task/task/internal/args"
"github.com/go-task/task/internal/taskfile"
"github.com/stretchr/testify/assert"
)
@ -13,12 +13,12 @@ import (
func TestArgs(t *testing.T) {
tests := []struct {
Args []string
Expected []task.Call
Expected []taskfile.Call
Err error
}{
{
Args: []string{"task-a", "task-b", "task-c"},
Expected: []task.Call{
Expected: []taskfile.Call{
{Task: "task-a"},
{Task: "task-b"},
{Task: "task-c"},
@ -26,30 +26,30 @@ func TestArgs(t *testing.T) {
},
{
Args: []string{"task-a", "FOO=bar", "task-b", "task-c", "BAR=baz", "BAZ=foo"},
Expected: []task.Call{
Expected: []taskfile.Call{
{
Task: "task-a",
Vars: task.Vars{
"FOO": task.Var{Static: "bar"},
Vars: taskfile.Vars{
"FOO": taskfile.Var{Static: "bar"},
},
},
{Task: "task-b"},
{
Task: "task-c",
Vars: task.Vars{
"BAR": task.Var{Static: "baz"},
"BAZ": task.Var{Static: "foo"},
Vars: taskfile.Vars{
"BAR": taskfile.Var{Static: "baz"},
"BAZ": taskfile.Var{Static: "foo"},
},
},
},
},
{
Args: []string{"task-a", "CONTENT=with some spaces"},
Expected: []task.Call{
Expected: []taskfile.Call{
{
Task: "task-a",
Vars: task.Vars{
"CONTENT": task.Var{Static: "with some spaces"},
Vars: taskfile.Vars{
"CONTENT": taskfile.Var{Static: "with some spaces"},
},
},
},

View File

@ -0,0 +1,7 @@
package taskfile
// Call is the parameters to a task call
type Call struct {
Task string
Vars Vars
}

View File

@ -1,4 +1,4 @@
package task
package taskfile
import (
"errors"
@ -76,9 +76,3 @@ func (d *Dep) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
return ErrCantUnmarshalDep
}
// Call is the parameters to a task call
type Call struct {
Task string
Vars Vars
}

20
internal/taskfile/task.go Normal file
View File

@ -0,0 +1,20 @@
package taskfile
// Tasks representas a group of tasks
type Tasks map[string]*Task
// Task represents a task
type Task struct {
Task string
Cmds []*Cmd
Deps []*Dep
Desc string
Sources []string
Generates []string
Status []string
Dir string
Vars Vars
Env Vars
Silent bool
Method string
}

View File

@ -0,0 +1,26 @@
package taskfile
// Taskfile represents a Taskfile.yml
type Taskfile struct {
// TODO: version is still not used
Version int
Tasks Tasks
}
// UnmarshalYAML implements yaml.Unmarshaler interface
func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := unmarshal(&tf.Tasks); err == nil {
return nil
}
var taskfile struct {
Version int
Tasks Tasks
}
if err := unmarshal(&taskfile); err != nil {
return err
}
tf.Version = taskfile.Version
tf.Tasks = taskfile.Tasks
return nil
}

View File

@ -1,9 +1,9 @@
package task_test
package taskfile_test
import (
"testing"
"github.com/go-task/task"
"github.com/go-task/task/internal/taskfile"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v2"
@ -27,28 +27,28 @@ vars:
}{
{
yamlCmd,
&task.Cmd{},
&task.Cmd{Cmd: `echo "a string command"`},
&taskfile.Cmd{},
&taskfile.Cmd{Cmd: `echo "a string command"`},
},
{
yamlTaskCall,
&task.Cmd{},
&task.Cmd{Task: "another-task", Vars: task.Vars{
"PARAM1": task.Var{Static: "VALUE1"},
"PARAM2": task.Var{Static: "VALUE2"},
&taskfile.Cmd{},
&taskfile.Cmd{Task: "another-task", Vars: taskfile.Vars{
"PARAM1": taskfile.Var{Static: "VALUE1"},
"PARAM2": taskfile.Var{Static: "VALUE2"},
}},
},
{
yamlDep,
&task.Dep{},
&task.Dep{Task: "task-name"},
&taskfile.Dep{},
&taskfile.Dep{Task: "task-name"},
},
{
yamlTaskCall,
&task.Dep{},
&task.Dep{Task: "another-task", Vars: task.Vars{
"PARAM1": task.Var{Static: "VALUE1"},
"PARAM2": task.Var{Static: "VALUE2"},
&taskfile.Dep{},
&taskfile.Dep{Task: "another-task", Vars: taskfile.Vars{
"PARAM1": taskfile.Var{Static: "VALUE1"},
"PARAM2": taskfile.Var{Static: "VALUE2"},
}},
},
}

58
internal/taskfile/var.go Normal file
View File

@ -0,0 +1,58 @@
package taskfile
import (
"errors"
"strings"
)
var (
// ErrCantUnmarshalVar is returned for invalid var YAML.
ErrCantUnmarshalVar = errors.New("task: can't unmarshal var value")
)
// Vars is a string[string] variables map.
type Vars map[string]Var
// ToStringMap converts Vars to a string map containing only the static
// variables
func (vs Vars) ToStringMap() (m map[string]string) {
m = make(map[string]string, len(vs))
for k, v := range vs {
if v.Sh != "" {
// Dynamic variable is not yet resolved; trigger
// <no value> to be used in templates.
continue
}
m[k] = v.Static
}
return
}
// Var represents either a static or dynamic variable.
type Var struct {
Static string
Sh string
}
// UnmarshalYAML implements yaml.Unmarshaler interface.
func (v *Var) UnmarshalYAML(unmarshal func(interface{}) error) error {
var str string
if err := unmarshal(&str); err == nil {
if strings.HasPrefix(str, "$") {
v.Sh = strings.TrimPrefix(str, "$")
} else {
v.Static = str
}
return nil
}
var sh struct {
Sh string
}
if err := unmarshal(&sh); err == nil {
v.Sh = sh.Sh
return nil
}
return ErrCantUnmarshalVar
}

View File

@ -6,16 +6,17 @@ import (
"github.com/go-task/task/internal/execext"
"github.com/go-task/task/internal/status"
"github.com/go-task/task/internal/taskfile"
)
// Status returns an error if any the of given tasks is not up-to-date
func (e *Executor) Status(calls ...Call) error {
func (e *Executor) Status(calls ...taskfile.Call) error {
for _, call := range calls {
t, ok := e.Taskfile.Tasks[call.Task]
if !ok {
return &taskNotFoundError{taskName: call.Task}
}
isUpToDate, err := t.isUpToDate(e.Context)
isUpToDate, err := isTaskUpToDate(e.Context, t)
if err != nil {
return err
}
@ -26,12 +27,12 @@ func (e *Executor) Status(calls ...Call) error {
return nil
}
func (t *Task) isUpToDate(ctx context.Context) (bool, error) {
func isTaskUpToDate(ctx context.Context, t *taskfile.Task) (bool, error) {
if len(t.Status) > 0 {
return t.isUpToDateStatus(ctx)
return isTaskUpToDateStatus(ctx, t)
}
checker, err := t.getStatusChecker()
checker, err := getStatusChecker(t)
if err != nil {
return false, err
}
@ -39,15 +40,15 @@ func (t *Task) isUpToDate(ctx context.Context) (bool, error) {
return checker.IsUpToDate()
}
func (t *Task) statusOnError() error {
checker, err := t.getStatusChecker()
func statusOnError(t *taskfile.Task) error {
checker, err := getStatusChecker(t)
if err != nil {
return err
}
return checker.OnError()
}
func (t *Task) getStatusChecker() (status.Checker, error) {
func getStatusChecker(t *taskfile.Task) (status.Checker, error) {
switch t.Method {
case "", "timestamp":
return &status.Timestamp{
@ -68,13 +69,13 @@ func (t *Task) getStatusChecker() (status.Checker, error) {
}
}
func (t *Task) isUpToDateStatus(ctx context.Context) (bool, error) {
func isTaskUpToDateStatus(ctx context.Context, t *taskfile.Task) (bool, error) {
for _, s := range t.Status {
err := execext.RunCommand(&execext.RunCommandOptions{
Context: ctx,
Command: s,
Dir: t.Dir,
Env: t.getEnviron(),
Env: getEnviron(t),
})
if err != nil {
return false, nil

46
task.go
View File

@ -9,6 +9,7 @@ import (
"sync/atomic"
"github.com/go-task/task/internal/execext"
"github.com/go-task/task/internal/taskfile"
"golang.org/x/sync/errgroup"
)
@ -23,7 +24,7 @@ const (
// Executor executes a Taskfile
type Executor struct {
Taskfile *Taskfile
Taskfile *taskfile.Taskfile
Dir string
Force bool
Watch bool
@ -36,7 +37,7 @@ type Executor struct {
Stdout io.Writer
Stderr io.Writer
taskvars Vars
taskvars taskfile.Vars
taskCallCount map[string]*int32
@ -44,27 +45,8 @@ type Executor struct {
muDynamicCache sync.Mutex
}
// Tasks representas a group of tasks
type Tasks map[string]*Task
// Task represents a task
type Task struct {
Task string
Cmds []*Cmd
Deps []*Dep
Desc string
Sources []string
Generates []string
Status []string
Dir string
Vars Vars
Env Vars
Silent bool
Method string
}
// Run runs Task
func (e *Executor) Run(calls ...Call) error {
func (e *Executor) Run(calls ...taskfile.Call) error {
if e.Context == nil {
e.Context = context.Background()
}
@ -109,7 +91,7 @@ func (e *Executor) Run(calls ...Call) error {
}
// RunTask runs a task by its name
func (e *Executor) RunTask(ctx context.Context, call Call) error {
func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error {
t, err := e.CompiledTask(call)
if err != nil {
return err
@ -123,7 +105,7 @@ func (e *Executor) RunTask(ctx context.Context, call Call) error {
}
if !e.Force {
upToDate, err := t.isUpToDate(ctx)
upToDate, err := isTaskUpToDate(ctx, t)
if err != nil {
return err
}
@ -137,7 +119,7 @@ func (e *Executor) RunTask(ctx context.Context, call Call) error {
for i := range t.Cmds {
if err := e.runCommand(ctx, t, call, i); err != nil {
if err2 := t.statusOnError(); err2 != nil {
if err2 := statusOnError(t); err2 != nil {
e.verboseErrf("task: error cleaning status on error: %v", err2)
}
return &taskRunError{t.Task, err}
@ -146,25 +128,25 @@ func (e *Executor) RunTask(ctx context.Context, call Call) error {
return nil
}
func (e *Executor) runDeps(ctx context.Context, t *Task) error {
func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error {
g, ctx := errgroup.WithContext(ctx)
for _, d := range t.Deps {
d := d
g.Go(func() error {
return e.RunTask(ctx, Call{Task: d.Task, Vars: d.Vars})
return e.RunTask(ctx, taskfile.Call{Task: d.Task, Vars: d.Vars})
})
}
return g.Wait()
}
func (e *Executor) runCommand(ctx context.Context, t *Task, call Call, i int) error {
func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfile.Call, i int) error {
cmd := t.Cmds[i]
if cmd.Cmd == "" {
return e.RunTask(ctx, Call{Task: cmd.Task, Vars: cmd.Vars})
return e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars})
}
if e.Verbose || (!cmd.Silent && !t.Silent && !e.Silent) {
@ -175,20 +157,20 @@ func (e *Executor) runCommand(ctx context.Context, t *Task, call Call, i int) er
Context: ctx,
Command: cmd.Cmd,
Dir: t.Dir,
Env: t.getEnviron(),
Env: getEnviron(t),
Stdin: e.Stdin,
Stdout: e.Stdout,
Stderr: e.Stderr,
})
}
func (t *Task) getEnviron() []string {
func getEnviron(t *taskfile.Task) []string {
if t.Env == nil {
return nil
}
envs := os.Environ()
for k, v := range t.Env.toStringMap() {
for k, v := range t.Env.ToStringMap() {
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
}
return envs

View File

@ -10,6 +10,7 @@ import (
"testing"
"github.com/go-task/task"
"github.com/go-task/task/internal/taskfile"
"github.com/stretchr/testify/assert"
)
@ -38,7 +39,7 @@ func (fct fileContentTest) Run(t *testing.T) {
Stderr: ioutil.Discard,
}
assert.NoError(t, e.ReadTaskfile(), "e.ReadTaskfile()")
assert.NoError(t, e.Run(task.Call{Task: fct.Target}), "e.Run(target)")
assert.NoError(t, e.Run(taskfile.Call{Task: fct.Target}), "e.Run(target)")
for name, expectContent := range fct.Files {
t.Run(fct.name(name), func(t *testing.T) {
@ -136,7 +137,7 @@ func TestVarsInvalidTmpl(t *testing.T) {
Stderr: ioutil.Discard,
}
assert.NoError(t, e.ReadTaskfile(), "e.ReadTaskfile()")
assert.EqualError(t, e.Run(task.Call{Task: target}), expectError, "e.Run(target)")
assert.EqualError(t, e.Run(taskfile.Call{Task: target}), expectError, "e.Run(target)")
}
func TestParams(t *testing.T) {
@ -188,7 +189,7 @@ func TestDeps(t *testing.T) {
Stderr: ioutil.Discard,
}
assert.NoError(t, e.ReadTaskfile())
assert.NoError(t, e.Run(task.Call{Task: "default"}))
assert.NoError(t, e.Run(taskfile.Call{Task: "default"}))
for _, f := range files {
f = filepath.Join(dir, f)
@ -214,7 +215,7 @@ func TestStatus(t *testing.T) {
Stderr: ioutil.Discard,
}
assert.NoError(t, e.ReadTaskfile())
assert.NoError(t, e.Run(task.Call{Task: "gen-foo"}))
assert.NoError(t, e.Run(taskfile.Call{Task: "gen-foo"}))
if _, err := os.Stat(file); err != nil {
t.Errorf("File should exists: %v", err)
@ -222,7 +223,7 @@ func TestStatus(t *testing.T) {
buff := bytes.NewBuffer(nil)
e.Stdout, e.Stderr = buff, buff
assert.NoError(t, e.Run(task.Call{Task: "gen-foo"}))
assert.NoError(t, e.Run(taskfile.Call{Task: "gen-foo"}))
if buff.String() != `task: Task "gen-foo" is up to date`+"\n" {
t.Errorf("Wrong output message: %s", buff.String())
@ -261,7 +262,7 @@ func TestGenerates(t *testing.T) {
fmt.Sprintf("task: Task \"%s\" is up to date\n", theTask)
// Run task for the first time.
assert.NoError(t, e.Run(task.Call{Task: theTask}))
assert.NoError(t, e.Run(taskfile.Call{Task: theTask}))
if _, err := os.Stat(srcFile); err != nil {
t.Errorf("File should exists: %v", err)
@ -276,7 +277,7 @@ func TestGenerates(t *testing.T) {
buff.Reset()
// Re-run task to ensure it's now found to be up-to-date.
assert.NoError(t, e.Run(task.Call{Task: theTask}))
assert.NoError(t, e.Run(taskfile.Call{Task: theTask}))
if buff.String() != upToDate {
t.Errorf("Wrong output message: %s", buff.String())
}
@ -307,14 +308,14 @@ func TestStatusChecksum(t *testing.T) {
}
assert.NoError(t, e.ReadTaskfile())
assert.NoError(t, e.Run(task.Call{Task: "build"}))
assert.NoError(t, e.Run(taskfile.Call{Task: "build"}))
for _, f := range files {
_, err := os.Stat(filepath.Join(dir, f))
assert.NoError(t, err)
}
buff.Reset()
assert.NoError(t, e.Run(task.Call{Task: "build"}))
assert.NoError(t, e.Run(taskfile.Call{Task: "build"}))
assert.Equal(t, `task: Task "build" is up to date`+"\n", buff.String())
}
@ -345,7 +346,7 @@ func TestCyclicDep(t *testing.T) {
Stderr: ioutil.Discard,
}
assert.NoError(t, e.ReadTaskfile())
assert.IsType(t, &task.MaximumTaskCallExceededError{}, e.Run(task.Call{Task: "task-1"}))
assert.IsType(t, &task.MaximumTaskCallExceededError{}, e.Run(taskfile.Call{Task: "task-1"}))
}
func TestTaskVersion(t *testing.T) {

View File

@ -6,35 +6,12 @@ import (
"path/filepath"
"runtime"
"github.com/go-task/task/internal/taskfile"
"github.com/imdario/mergo"
"gopkg.in/yaml.v2"
)
// Taskfile represents a Taskfile.yml
type Taskfile struct {
// TODO: version is still not used
Version int
Tasks Tasks
}
// UnmarshalYAML implements yaml.Unmarshaler interface
func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := unmarshal(&tf.Tasks); err == nil {
return nil
}
var taskfile struct {
Version int
Tasks Tasks
}
if err := unmarshal(&taskfile); err != nil {
return err
}
tf.Version = taskfile.Version
tf.Tasks = taskfile.Tasks
return nil
}
// ReadTaskfile parses Taskfile from the disk
func (e *Executor) ReadTaskfile() error {
path := filepath.Join(e.Dir, TaskFilePath)
@ -64,9 +41,9 @@ func (e *Executor) ReadTaskfile() error {
return e.readTaskvars()
}
func (e *Executor) readTaskfileData(path string) (*Taskfile, error) {
func (e *Executor) readTaskfileData(path string) (*taskfile.Taskfile, error) {
if b, err := ioutil.ReadFile(path + ".yml"); err == nil {
var taskfile Taskfile
var taskfile taskfile.Taskfile
return &taskfile, yaml.UnmarshalStrict(b, &taskfile)
}
return nil, taskFileNotFound{path}
@ -85,7 +62,7 @@ func (e *Executor) readTaskvars() error {
}
if b, err := ioutil.ReadFile(osSpecificFile + ".yml"); err == nil {
osTaskvars := make(Vars, 10)
osTaskvars := make(taskfile.Vars, 10)
if err := yaml.UnmarshalStrict(b, &osTaskvars); err != nil {
return err
}

View File

@ -2,7 +2,6 @@ package task
import (
"bytes"
"errors"
"os"
"path/filepath"
"runtime"
@ -10,6 +9,7 @@ import (
"text/template"
"github.com/go-task/task/internal/execext"
"github.com/go-task/task/internal/taskfile"
"github.com/Masterminds/sprig"
"github.com/mitchellh/go-homedir"
@ -20,70 +20,20 @@ var (
TaskvarsFilePath = "Taskvars"
)
var (
// ErrCantUnmarshalVar is returned for invalid var YAML.
ErrCantUnmarshalVar = errors.New("task: can't unmarshal var value")
)
// Vars is a string[string] variables map.
type Vars map[string]Var
func getEnvironmentVariables() Vars {
func getEnvironmentVariables() taskfile.Vars {
var (
env = os.Environ()
m = make(Vars, len(env))
m = make(taskfile.Vars, len(env))
)
for _, e := range env {
keyVal := strings.SplitN(e, "=", 2)
key, val := keyVal[0], keyVal[1]
m[key] = Var{Static: val}
m[key] = taskfile.Var{Static: val}
}
return m
}
func (vs Vars) toStringMap() (m map[string]string) {
m = make(map[string]string, len(vs))
for k, v := range vs {
if v.Sh != "" {
// Dynamic variable is not yet resolved; trigger
// <no value> to be used in templates.
continue
}
m[k] = v.Static
}
return
}
// Var represents either a static or dynamic variable.
type Var struct {
Static string
Sh string
}
// UnmarshalYAML implements yaml.Unmarshaler interface.
func (v *Var) UnmarshalYAML(unmarshal func(interface{}) error) error {
var str string
if err := unmarshal(&str); err == nil {
if strings.HasPrefix(str, "$") {
v.Sh = strings.TrimPrefix(str, "$")
} else {
v.Static = str
}
return nil
}
var sh struct {
Sh string
}
if err := unmarshal(&sh); err == nil {
v.Sh = sh.Sh
return nil
}
return ErrCantUnmarshalVar
}
// getVariables returns fully resolved variables following the priority order:
// 1. Call variables (should already have been resolved)
// 2. Environment (should not need to be resolved)
@ -91,20 +41,20 @@ func (v *Var) UnmarshalYAML(unmarshal func(interface{}) error) error {
// - call, taskvars and environment variables
// 4. Taskvars variables, resolved with access to:
// - environment variables
func (e *Executor) getVariables(call Call) (Vars, error) {
func (e *Executor) getVariables(call taskfile.Call) (taskfile.Vars, error) {
t, ok := e.Taskfile.Tasks[call.Task]
if !ok {
return nil, &taskNotFoundError{call.Task}
}
merge := func(dest Vars, srcs ...Vars) {
merge := func(dest taskfile.Vars, srcs ...taskfile.Vars) {
for _, src := range srcs {
for k, v := range src {
dest[k] = v
}
}
}
varsKeys := func(srcs ...Vars) []string {
varsKeys := func(srcs ...taskfile.Vars) []string {
m := make(map[string]struct{})
for _, src := range srcs {
for k := range src {
@ -117,29 +67,29 @@ func (e *Executor) getVariables(call Call) (Vars, error) {
}
return lst
}
replaceVars := func(dest Vars, keys []string) error {
replaceVars := func(dest taskfile.Vars, keys []string) error {
r := varReplacer{vars: dest}
for _, k := range keys {
v := dest[k]
dest[k] = Var{
dest[k] = taskfile.Var{
Static: r.replace(v.Static),
Sh: r.replace(v.Sh),
}
}
return r.err
}
resolveShell := func(dest Vars, keys []string) error {
resolveShell := func(dest taskfile.Vars, keys []string) error {
for _, k := range keys {
v := dest[k]
static, err := e.handleShVar(v)
if err != nil {
return err
}
dest[k] = Var{Static: static}
dest[k] = taskfile.Var{Static: static}
}
return nil
}
update := func(dest Vars, srcs ...Vars) error {
update := func(dest taskfile.Vars, srcs ...taskfile.Vars) error {
merge(dest, srcs...)
// updatedKeys ensures template evaluation is run only once.
updatedKeys := varsKeys(srcs...)
@ -151,7 +101,7 @@ func (e *Executor) getVariables(call Call) (Vars, error) {
// Resolve taskvars variables to "result" with environment override variables.
override := getEnvironmentVariables()
result := make(Vars, len(e.taskvars)+len(t.Vars)+len(override))
result := make(taskfile.Vars, len(e.taskvars)+len(t.Vars)+len(override))
if err := update(result, e.taskvars, override); err != nil {
return nil, err
}
@ -163,7 +113,7 @@ func (e *Executor) getVariables(call Call) (Vars, error) {
return result, nil
}
func (e *Executor) handleShVar(v Var) (string, error) {
func (e *Executor) handleShVar(v taskfile.Var) (string, error) {
if v.Static != "" || v.Sh == "" {
return v.Static, nil
}
@ -197,7 +147,7 @@ func (e *Executor) handleShVar(v Var) (string, error) {
// CompiledTask returns a copy of a task, but replacing variables in almost all
// properties using the Go template package.
func (e *Executor) CompiledTask(call Call) (*Task, error) {
func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) {
origTask, ok := e.Taskfile.Tasks[call.Task]
if !ok {
return nil, &taskNotFoundError{call.Task}
@ -209,7 +159,7 @@ func (e *Executor) CompiledTask(call Call) (*Task, error) {
}
r := varReplacer{vars: vars}
new := Task{
new := taskfile.Task{
Task: origTask.Task,
Desc: r.replace(origTask.Desc),
Sources: r.replaceSlice(origTask.Sources),
@ -233,13 +183,13 @@ func (e *Executor) CompiledTask(call Call) (*Task, error) {
if err != nil {
return nil, err
}
new.Env[k] = Var{Static: static}
new.Env[k] = taskfile.Var{Static: static}
}
if len(origTask.Cmds) > 0 {
new.Cmds = make([]*Cmd, len(origTask.Cmds))
new.Cmds = make([]*taskfile.Cmd, len(origTask.Cmds))
for i, cmd := range origTask.Cmds {
new.Cmds[i] = &Cmd{
new.Cmds[i] = &taskfile.Cmd{
Task: r.replace(cmd.Task),
Silent: cmd.Silent,
Cmd: r.replace(cmd.Cmd),
@ -249,9 +199,9 @@ func (e *Executor) CompiledTask(call Call) (*Task, error) {
}
}
if len(origTask.Deps) > 0 {
new.Deps = make([]*Dep, len(origTask.Deps))
new.Deps = make([]*taskfile.Dep, len(origTask.Deps))
for i, dep := range origTask.Deps {
new.Deps[i] = &Dep{
new.Deps[i] = &taskfile.Dep{
Task: r.replace(dep.Task),
Vars: r.replaceVars(dep.Vars),
}
@ -266,7 +216,7 @@ func (e *Executor) CompiledTask(call Call) (*Task, error) {
// happen will be assigned to r.err, and consecutive calls to funcs will just
// return the zero value.
type varReplacer struct {
vars Vars
vars taskfile.Vars
strMap map[string]string
err error
}
@ -283,7 +233,7 @@ func (r *varReplacer) replace(str string) string {
}
if r.strMap == nil {
r.strMap = r.vars.toStringMap()
r.strMap = r.vars.ToStringMap()
}
var b bytes.Buffer
@ -306,14 +256,14 @@ func (r *varReplacer) replaceSlice(strs []string) []string {
return new
}
func (r *varReplacer) replaceVars(vars Vars) Vars {
func (r *varReplacer) replaceVars(vars taskfile.Vars) taskfile.Vars {
if r.err != nil || len(vars) == 0 {
return nil
}
new := make(Vars, len(vars))
new := make(taskfile.Vars, len(vars))
for k, v := range vars {
new[k] = Var{
new[k] = taskfile.Var{
Static: r.replace(v.Static),
Sh: r.replace(v.Sh),
}

View File

@ -5,6 +5,7 @@ import (
"strings"
"time"
"github.com/go-task/task/internal/taskfile"
"github.com/mattn/go-zglob"
"github.com/radovskyb/watcher"
)
@ -15,7 +16,7 @@ var watchIgnoredDirs = []string{
}
// watchTasks start watching the given tasks
func (e *Executor) watchTasks(calls ...Call) error {
func (e *Executor) watchTasks(calls ...taskfile.Call) error {
tasks := make([]string, len(calls))
for i, c := range calls {
tasks[i] = c.Task
@ -83,7 +84,7 @@ func (e *Executor) watchTasks(calls ...Call) error {
return w.Start(time.Second)
}
func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...Call) error {
func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Call) error {
oldWatchedFiles := make(map[string]struct{})
for f := range w.WatchedFiles() {
oldWatchedFiles[f] = struct{}{}
@ -95,21 +96,21 @@ func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...Call) error
}
}
var registerTaskFiles func(Call) error
registerTaskFiles = func(c Call) error {
var registerTaskFiles func(taskfile.Call) error
registerTaskFiles = func(c taskfile.Call) error {
task, err := e.CompiledTask(c)
if err != nil {
return err
}
for _, d := range task.Deps {
if err := registerTaskFiles(Call{Task: d.Task, Vars: d.Vars}); err != nil {
if err := registerTaskFiles(taskfile.Call{Task: d.Task, Vars: d.Vars}); err != nil {
return err
}
}
for _, c := range task.Cmds {
if c.Task != "" {
if err := registerTaskFiles(Call{Task: c.Task, Vars: c.Vars}); err != nil {
if err := registerTaskFiles(taskfile.Call{Task: c.Task, Vars: c.Vars}); err != nil {
return err
}
}