mirror of
https://github.com/go-task/task.git
synced 2025-09-16 09:26:16 +02:00
Move all structs related to Taskfile to its own package
This commit is contained in:
@@ -7,3 +7,4 @@ GO_PACKAGES:
|
|||||||
./internal/args
|
./internal/args
|
||||||
./internal/execext
|
./internal/execext
|
||||||
./internal/status
|
./internal/status
|
||||||
|
./internal/taskfile
|
||||||
|
6
help.go
6
help.go
@@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrintTasksHelp prints help os tasks that have a description
|
// PrintTasksHelp prints help os tasks that have a description
|
||||||
@@ -23,8 +25,8 @@ func (e *Executor) PrintTasksHelp() {
|
|||||||
w.Flush()
|
w.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) tasksWithDesc() (tasks []*Task) {
|
func (e *Executor) tasksWithDesc() (tasks []*taskfile.Task) {
|
||||||
tasks = make([]*Task, 0, len(e.Taskfile.Tasks))
|
tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
|
||||||
for _, task := range e.Taskfile.Tasks {
|
for _, task := range e.Taskfile.Tasks {
|
||||||
if task.Desc != "" {
|
if task.Desc != "" {
|
||||||
tasks = append(tasks, task)
|
tasks = append(tasks, task)
|
||||||
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-task/task"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -13,12 +13,12 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Parse parses command line argument: tasks and vars of each task
|
// Parse parses command line argument: tasks and vars of each task
|
||||||
func Parse(args ...string) ([]task.Call, error) {
|
func Parse(args ...string) ([]taskfile.Call, error) {
|
||||||
var calls []task.Call
|
var calls []taskfile.Call
|
||||||
|
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
if !strings.Contains(arg, "=") {
|
if !strings.Contains(arg, "=") {
|
||||||
calls = append(calls, task.Call{Task: arg})
|
calls = append(calls, taskfile.Call{Task: arg})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(calls) < 1 {
|
if len(calls) < 1 {
|
||||||
@@ -26,11 +26,11 @@ func Parse(args ...string) ([]task.Call, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if calls[len(calls)-1].Vars == nil {
|
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)
|
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
|
return calls, nil
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-task/task"
|
|
||||||
"github.com/go-task/task/internal/args"
|
"github.com/go-task/task/internal/args"
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -13,12 +13,12 @@ import (
|
|||||||
func TestArgs(t *testing.T) {
|
func TestArgs(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Args []string
|
Args []string
|
||||||
Expected []task.Call
|
Expected []taskfile.Call
|
||||||
Err error
|
Err error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Args: []string{"task-a", "task-b", "task-c"},
|
Args: []string{"task-a", "task-b", "task-c"},
|
||||||
Expected: []task.Call{
|
Expected: []taskfile.Call{
|
||||||
{Task: "task-a"},
|
{Task: "task-a"},
|
||||||
{Task: "task-b"},
|
{Task: "task-b"},
|
||||||
{Task: "task-c"},
|
{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"},
|
Args: []string{"task-a", "FOO=bar", "task-b", "task-c", "BAR=baz", "BAZ=foo"},
|
||||||
Expected: []task.Call{
|
Expected: []taskfile.Call{
|
||||||
{
|
{
|
||||||
Task: "task-a",
|
Task: "task-a",
|
||||||
Vars: task.Vars{
|
Vars: taskfile.Vars{
|
||||||
"FOO": task.Var{Static: "bar"},
|
"FOO": taskfile.Var{Static: "bar"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{Task: "task-b"},
|
{Task: "task-b"},
|
||||||
{
|
{
|
||||||
Task: "task-c",
|
Task: "task-c",
|
||||||
Vars: task.Vars{
|
Vars: taskfile.Vars{
|
||||||
"BAR": task.Var{Static: "baz"},
|
"BAR": taskfile.Var{Static: "baz"},
|
||||||
"BAZ": task.Var{Static: "foo"},
|
"BAZ": taskfile.Var{Static: "foo"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Args: []string{"task-a", "CONTENT=with some spaces"},
|
Args: []string{"task-a", "CONTENT=with some spaces"},
|
||||||
Expected: []task.Call{
|
Expected: []taskfile.Call{
|
||||||
{
|
{
|
||||||
Task: "task-a",
|
Task: "task-a",
|
||||||
Vars: task.Vars{
|
Vars: taskfile.Vars{
|
||||||
"CONTENT": task.Var{Static: "with some spaces"},
|
"CONTENT": taskfile.Var{Static: "with some spaces"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
7
internal/taskfile/call.go
Normal file
7
internal/taskfile/call.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package taskfile
|
||||||
|
|
||||||
|
// Call is the parameters to a task call
|
||||||
|
type Call struct {
|
||||||
|
Task string
|
||||||
|
Vars Vars
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package task
|
package taskfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@@ -76,9 +76,3 @@ func (d *Dep) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
}
|
}
|
||||||
return ErrCantUnmarshalDep
|
return ErrCantUnmarshalDep
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call is the parameters to a task call
|
|
||||||
type Call struct {
|
|
||||||
Task string
|
|
||||||
Vars Vars
|
|
||||||
}
|
|
20
internal/taskfile/task.go
Normal file
20
internal/taskfile/task.go
Normal 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
|
||||||
|
}
|
26
internal/taskfile/taskfile.go
Normal file
26
internal/taskfile/taskfile.go
Normal 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
|
||||||
|
}
|
@@ -1,9 +1,9 @@
|
|||||||
package task_test
|
package taskfile_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-task/task"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
@@ -27,28 +27,28 @@ vars:
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
yamlCmd,
|
yamlCmd,
|
||||||
&task.Cmd{},
|
&taskfile.Cmd{},
|
||||||
&task.Cmd{Cmd: `echo "a string command"`},
|
&taskfile.Cmd{Cmd: `echo "a string command"`},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
yamlTaskCall,
|
yamlTaskCall,
|
||||||
&task.Cmd{},
|
&taskfile.Cmd{},
|
||||||
&task.Cmd{Task: "another-task", Vars: task.Vars{
|
&taskfile.Cmd{Task: "another-task", Vars: taskfile.Vars{
|
||||||
"PARAM1": task.Var{Static: "VALUE1"},
|
"PARAM1": taskfile.Var{Static: "VALUE1"},
|
||||||
"PARAM2": task.Var{Static: "VALUE2"},
|
"PARAM2": taskfile.Var{Static: "VALUE2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
yamlDep,
|
yamlDep,
|
||||||
&task.Dep{},
|
&taskfile.Dep{},
|
||||||
&task.Dep{Task: "task-name"},
|
&taskfile.Dep{Task: "task-name"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
yamlTaskCall,
|
yamlTaskCall,
|
||||||
&task.Dep{},
|
&taskfile.Dep{},
|
||||||
&task.Dep{Task: "another-task", Vars: task.Vars{
|
&taskfile.Dep{Task: "another-task", Vars: taskfile.Vars{
|
||||||
"PARAM1": task.Var{Static: "VALUE1"},
|
"PARAM1": taskfile.Var{Static: "VALUE1"},
|
||||||
"PARAM2": task.Var{Static: "VALUE2"},
|
"PARAM2": taskfile.Var{Static: "VALUE2"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
58
internal/taskfile/var.go
Normal file
58
internal/taskfile/var.go
Normal 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
|
||||||
|
}
|
21
status.go
21
status.go
@@ -6,16 +6,17 @@ import (
|
|||||||
|
|
||||||
"github.com/go-task/task/internal/execext"
|
"github.com/go-task/task/internal/execext"
|
||||||
"github.com/go-task/task/internal/status"
|
"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
|
// 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 {
|
for _, call := range calls {
|
||||||
t, ok := e.Taskfile.Tasks[call.Task]
|
t, ok := e.Taskfile.Tasks[call.Task]
|
||||||
if !ok {
|
if !ok {
|
||||||
return &taskNotFoundError{taskName: call.Task}
|
return &taskNotFoundError{taskName: call.Task}
|
||||||
}
|
}
|
||||||
isUpToDate, err := t.isUpToDate(e.Context)
|
isUpToDate, err := isTaskUpToDate(e.Context, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -26,12 +27,12 @@ func (e *Executor) Status(calls ...Call) error {
|
|||||||
return nil
|
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 {
|
if len(t.Status) > 0 {
|
||||||
return t.isUpToDateStatus(ctx)
|
return isTaskUpToDateStatus(ctx, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
checker, err := t.getStatusChecker()
|
checker, err := getStatusChecker(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -39,15 +40,15 @@ func (t *Task) isUpToDate(ctx context.Context) (bool, error) {
|
|||||||
return checker.IsUpToDate()
|
return checker.IsUpToDate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) statusOnError() error {
|
func statusOnError(t *taskfile.Task) error {
|
||||||
checker, err := t.getStatusChecker()
|
checker, err := getStatusChecker(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return checker.OnError()
|
return checker.OnError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) getStatusChecker() (status.Checker, error) {
|
func getStatusChecker(t *taskfile.Task) (status.Checker, error) {
|
||||||
switch t.Method {
|
switch t.Method {
|
||||||
case "", "timestamp":
|
case "", "timestamp":
|
||||||
return &status.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 {
|
for _, s := range t.Status {
|
||||||
err := execext.RunCommand(&execext.RunCommandOptions{
|
err := execext.RunCommand(&execext.RunCommandOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
Command: s,
|
Command: s,
|
||||||
Dir: t.Dir,
|
Dir: t.Dir,
|
||||||
Env: t.getEnviron(),
|
Env: getEnviron(t),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
46
task.go
46
task.go
@@ -9,6 +9,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/go-task/task/internal/execext"
|
"github.com/go-task/task/internal/execext"
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
@@ -23,7 +24,7 @@ const (
|
|||||||
|
|
||||||
// Executor executes a Taskfile
|
// Executor executes a Taskfile
|
||||||
type Executor struct {
|
type Executor struct {
|
||||||
Taskfile *Taskfile
|
Taskfile *taskfile.Taskfile
|
||||||
Dir string
|
Dir string
|
||||||
Force bool
|
Force bool
|
||||||
Watch bool
|
Watch bool
|
||||||
@@ -36,7 +37,7 @@ type Executor struct {
|
|||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
|
|
||||||
taskvars Vars
|
taskvars taskfile.Vars
|
||||||
|
|
||||||
taskCallCount map[string]*int32
|
taskCallCount map[string]*int32
|
||||||
|
|
||||||
@@ -44,27 +45,8 @@ type Executor struct {
|
|||||||
muDynamicCache sync.Mutex
|
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
|
// Run runs Task
|
||||||
func (e *Executor) Run(calls ...Call) error {
|
func (e *Executor) Run(calls ...taskfile.Call) error {
|
||||||
if e.Context == nil {
|
if e.Context == nil {
|
||||||
e.Context = context.Background()
|
e.Context = context.Background()
|
||||||
}
|
}
|
||||||
@@ -109,7 +91,7 @@ func (e *Executor) Run(calls ...Call) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RunTask runs a task by its name
|
// 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)
|
t, err := e.CompiledTask(call)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -123,7 +105,7 @@ func (e *Executor) RunTask(ctx context.Context, call Call) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !e.Force {
|
if !e.Force {
|
||||||
upToDate, err := t.isUpToDate(ctx)
|
upToDate, err := isTaskUpToDate(ctx, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -137,7 +119,7 @@ func (e *Executor) RunTask(ctx context.Context, call Call) error {
|
|||||||
|
|
||||||
for i := range t.Cmds {
|
for i := range t.Cmds {
|
||||||
if err := e.runCommand(ctx, t, call, i); err != nil {
|
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)
|
e.verboseErrf("task: error cleaning status on error: %v", err2)
|
||||||
}
|
}
|
||||||
return &taskRunError{t.Task, err}
|
return &taskRunError{t.Task, err}
|
||||||
@@ -146,25 +128,25 @@ func (e *Executor) RunTask(ctx context.Context, call Call) error {
|
|||||||
return nil
|
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)
|
g, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
for _, d := range t.Deps {
|
for _, d := range t.Deps {
|
||||||
d := d
|
d := d
|
||||||
|
|
||||||
g.Go(func() error {
|
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()
|
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]
|
cmd := t.Cmds[i]
|
||||||
|
|
||||||
if cmd.Cmd == "" {
|
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) {
|
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,
|
Context: ctx,
|
||||||
Command: cmd.Cmd,
|
Command: cmd.Cmd,
|
||||||
Dir: t.Dir,
|
Dir: t.Dir,
|
||||||
Env: t.getEnviron(),
|
Env: getEnviron(t),
|
||||||
Stdin: e.Stdin,
|
Stdin: e.Stdin,
|
||||||
Stdout: e.Stdout,
|
Stdout: e.Stdout,
|
||||||
Stderr: e.Stderr,
|
Stderr: e.Stderr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) getEnviron() []string {
|
func getEnviron(t *taskfile.Task) []string {
|
||||||
if t.Env == nil {
|
if t.Env == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
envs := os.Environ()
|
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))
|
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
|
||||||
}
|
}
|
||||||
return envs
|
return envs
|
||||||
|
21
task_test.go
21
task_test.go
@@ -10,6 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-task/task"
|
"github.com/go-task/task"
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -38,7 +39,7 @@ func (fct fileContentTest) Run(t *testing.T) {
|
|||||||
Stderr: ioutil.Discard,
|
Stderr: ioutil.Discard,
|
||||||
}
|
}
|
||||||
assert.NoError(t, e.ReadTaskfile(), "e.ReadTaskfile()")
|
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 {
|
for name, expectContent := range fct.Files {
|
||||||
t.Run(fct.name(name), func(t *testing.T) {
|
t.Run(fct.name(name), func(t *testing.T) {
|
||||||
@@ -136,7 +137,7 @@ func TestVarsInvalidTmpl(t *testing.T) {
|
|||||||
Stderr: ioutil.Discard,
|
Stderr: ioutil.Discard,
|
||||||
}
|
}
|
||||||
assert.NoError(t, e.ReadTaskfile(), "e.ReadTaskfile()")
|
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) {
|
func TestParams(t *testing.T) {
|
||||||
@@ -188,7 +189,7 @@ func TestDeps(t *testing.T) {
|
|||||||
Stderr: ioutil.Discard,
|
Stderr: ioutil.Discard,
|
||||||
}
|
}
|
||||||
assert.NoError(t, e.ReadTaskfile())
|
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 {
|
for _, f := range files {
|
||||||
f = filepath.Join(dir, f)
|
f = filepath.Join(dir, f)
|
||||||
@@ -214,7 +215,7 @@ func TestStatus(t *testing.T) {
|
|||||||
Stderr: ioutil.Discard,
|
Stderr: ioutil.Discard,
|
||||||
}
|
}
|
||||||
assert.NoError(t, e.ReadTaskfile())
|
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 {
|
if _, err := os.Stat(file); err != nil {
|
||||||
t.Errorf("File should exists: %v", err)
|
t.Errorf("File should exists: %v", err)
|
||||||
@@ -222,7 +223,7 @@ func TestStatus(t *testing.T) {
|
|||||||
|
|
||||||
buff := bytes.NewBuffer(nil)
|
buff := bytes.NewBuffer(nil)
|
||||||
e.Stdout, e.Stderr = buff, buff
|
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" {
|
if buff.String() != `task: Task "gen-foo" is up to date`+"\n" {
|
||||||
t.Errorf("Wrong output message: %s", buff.String())
|
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)
|
fmt.Sprintf("task: Task \"%s\" is up to date\n", theTask)
|
||||||
|
|
||||||
// Run task for the first time.
|
// 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 {
|
if _, err := os.Stat(srcFile); err != nil {
|
||||||
t.Errorf("File should exists: %v", err)
|
t.Errorf("File should exists: %v", err)
|
||||||
@@ -276,7 +277,7 @@ func TestGenerates(t *testing.T) {
|
|||||||
buff.Reset()
|
buff.Reset()
|
||||||
|
|
||||||
// Re-run task to ensure it's now found to be up-to-date.
|
// 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 {
|
if buff.String() != upToDate {
|
||||||
t.Errorf("Wrong output message: %s", buff.String())
|
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.ReadTaskfile())
|
||||||
|
|
||||||
assert.NoError(t, e.Run(task.Call{Task: "build"}))
|
assert.NoError(t, e.Run(taskfile.Call{Task: "build"}))
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
_, err := os.Stat(filepath.Join(dir, f))
|
_, err := os.Stat(filepath.Join(dir, f))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buff.Reset()
|
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())
|
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,
|
Stderr: ioutil.Discard,
|
||||||
}
|
}
|
||||||
assert.NoError(t, e.ReadTaskfile())
|
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) {
|
func TestTaskVersion(t *testing.T) {
|
||||||
|
33
taskfile.go
33
taskfile.go
@@ -6,35 +6,12 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
"gopkg.in/yaml.v2"
|
"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
|
// ReadTaskfile parses Taskfile from the disk
|
||||||
func (e *Executor) ReadTaskfile() error {
|
func (e *Executor) ReadTaskfile() error {
|
||||||
path := filepath.Join(e.Dir, TaskFilePath)
|
path := filepath.Join(e.Dir, TaskFilePath)
|
||||||
@@ -64,9 +41,9 @@ func (e *Executor) ReadTaskfile() error {
|
|||||||
return e.readTaskvars()
|
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 {
|
if b, err := ioutil.ReadFile(path + ".yml"); err == nil {
|
||||||
var taskfile Taskfile
|
var taskfile taskfile.Taskfile
|
||||||
return &taskfile, yaml.UnmarshalStrict(b, &taskfile)
|
return &taskfile, yaml.UnmarshalStrict(b, &taskfile)
|
||||||
}
|
}
|
||||||
return nil, taskFileNotFound{path}
|
return nil, taskFileNotFound{path}
|
||||||
@@ -85,7 +62,7 @@ func (e *Executor) readTaskvars() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if b, err := ioutil.ReadFile(osSpecificFile + ".yml"); err == nil {
|
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 {
|
if err := yaml.UnmarshalStrict(b, &osTaskvars); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
102
variables.go
102
variables.go
@@ -2,7 +2,6 @@ package task
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -10,6 +9,7 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/go-task/task/internal/execext"
|
"github.com/go-task/task/internal/execext"
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/Masterminds/sprig"
|
"github.com/Masterminds/sprig"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
@@ -20,70 +20,20 @@ var (
|
|||||||
TaskvarsFilePath = "Taskvars"
|
TaskvarsFilePath = "Taskvars"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func getEnvironmentVariables() taskfile.Vars {
|
||||||
// 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 {
|
|
||||||
var (
|
var (
|
||||||
env = os.Environ()
|
env = os.Environ()
|
||||||
m = make(Vars, len(env))
|
m = make(taskfile.Vars, len(env))
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, e := range env {
|
for _, e := range env {
|
||||||
keyVal := strings.SplitN(e, "=", 2)
|
keyVal := strings.SplitN(e, "=", 2)
|
||||||
key, val := keyVal[0], keyVal[1]
|
key, val := keyVal[0], keyVal[1]
|
||||||
m[key] = Var{Static: val}
|
m[key] = taskfile.Var{Static: val}
|
||||||
}
|
}
|
||||||
return m
|
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:
|
// getVariables returns fully resolved variables following the priority order:
|
||||||
// 1. Call variables (should already have been resolved)
|
// 1. Call variables (should already have been resolved)
|
||||||
// 2. Environment (should not need to be 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
|
// - call, taskvars and environment variables
|
||||||
// 4. Taskvars variables, resolved with access to:
|
// 4. Taskvars variables, resolved with access to:
|
||||||
// - environment variables
|
// - 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]
|
t, ok := e.Taskfile.Tasks[call.Task]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, &taskNotFoundError{call.Task}
|
return nil, &taskNotFoundError{call.Task}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge := func(dest Vars, srcs ...Vars) {
|
merge := func(dest taskfile.Vars, srcs ...taskfile.Vars) {
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
for k, v := range src {
|
for k, v := range src {
|
||||||
dest[k] = v
|
dest[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
varsKeys := func(srcs ...Vars) []string {
|
varsKeys := func(srcs ...taskfile.Vars) []string {
|
||||||
m := make(map[string]struct{})
|
m := make(map[string]struct{})
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
for k := range src {
|
for k := range src {
|
||||||
@@ -117,29 +67,29 @@ func (e *Executor) getVariables(call Call) (Vars, error) {
|
|||||||
}
|
}
|
||||||
return lst
|
return lst
|
||||||
}
|
}
|
||||||
replaceVars := func(dest Vars, keys []string) error {
|
replaceVars := func(dest taskfile.Vars, keys []string) error {
|
||||||
r := varReplacer{vars: dest}
|
r := varReplacer{vars: dest}
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
v := dest[k]
|
v := dest[k]
|
||||||
dest[k] = Var{
|
dest[k] = taskfile.Var{
|
||||||
Static: r.replace(v.Static),
|
Static: r.replace(v.Static),
|
||||||
Sh: r.replace(v.Sh),
|
Sh: r.replace(v.Sh),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r.err
|
return r.err
|
||||||
}
|
}
|
||||||
resolveShell := func(dest Vars, keys []string) error {
|
resolveShell := func(dest taskfile.Vars, keys []string) error {
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
v := dest[k]
|
v := dest[k]
|
||||||
static, err := e.handleShVar(v)
|
static, err := e.handleShVar(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dest[k] = Var{Static: static}
|
dest[k] = taskfile.Var{Static: static}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
update := func(dest Vars, srcs ...Vars) error {
|
update := func(dest taskfile.Vars, srcs ...taskfile.Vars) error {
|
||||||
merge(dest, srcs...)
|
merge(dest, srcs...)
|
||||||
// updatedKeys ensures template evaluation is run only once.
|
// updatedKeys ensures template evaluation is run only once.
|
||||||
updatedKeys := varsKeys(srcs...)
|
updatedKeys := varsKeys(srcs...)
|
||||||
@@ -151,7 +101,7 @@ func (e *Executor) getVariables(call Call) (Vars, error) {
|
|||||||
|
|
||||||
// Resolve taskvars variables to "result" with environment override variables.
|
// Resolve taskvars variables to "result" with environment override variables.
|
||||||
override := getEnvironmentVariables()
|
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 {
|
if err := update(result, e.taskvars, override); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -163,7 +113,7 @@ func (e *Executor) getVariables(call Call) (Vars, error) {
|
|||||||
return result, nil
|
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 == "" {
|
if v.Static != "" || v.Sh == "" {
|
||||||
return v.Static, nil
|
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
|
// CompiledTask returns a copy of a task, but replacing variables in almost all
|
||||||
// properties using the Go template package.
|
// 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]
|
origTask, ok := e.Taskfile.Tasks[call.Task]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, &taskNotFoundError{call.Task}
|
return nil, &taskNotFoundError{call.Task}
|
||||||
@@ -209,7 +159,7 @@ func (e *Executor) CompiledTask(call Call) (*Task, error) {
|
|||||||
}
|
}
|
||||||
r := varReplacer{vars: vars}
|
r := varReplacer{vars: vars}
|
||||||
|
|
||||||
new := Task{
|
new := taskfile.Task{
|
||||||
Task: origTask.Task,
|
Task: origTask.Task,
|
||||||
Desc: r.replace(origTask.Desc),
|
Desc: r.replace(origTask.Desc),
|
||||||
Sources: r.replaceSlice(origTask.Sources),
|
Sources: r.replaceSlice(origTask.Sources),
|
||||||
@@ -233,13 +183,13 @@ func (e *Executor) CompiledTask(call Call) (*Task, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
new.Env[k] = Var{Static: static}
|
new.Env[k] = taskfile.Var{Static: static}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(origTask.Cmds) > 0 {
|
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 {
|
for i, cmd := range origTask.Cmds {
|
||||||
new.Cmds[i] = &Cmd{
|
new.Cmds[i] = &taskfile.Cmd{
|
||||||
Task: r.replace(cmd.Task),
|
Task: r.replace(cmd.Task),
|
||||||
Silent: cmd.Silent,
|
Silent: cmd.Silent,
|
||||||
Cmd: r.replace(cmd.Cmd),
|
Cmd: r.replace(cmd.Cmd),
|
||||||
@@ -249,9 +199,9 @@ func (e *Executor) CompiledTask(call Call) (*Task, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(origTask.Deps) > 0 {
|
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 {
|
for i, dep := range origTask.Deps {
|
||||||
new.Deps[i] = &Dep{
|
new.Deps[i] = &taskfile.Dep{
|
||||||
Task: r.replace(dep.Task),
|
Task: r.replace(dep.Task),
|
||||||
Vars: r.replaceVars(dep.Vars),
|
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
|
// happen will be assigned to r.err, and consecutive calls to funcs will just
|
||||||
// return the zero value.
|
// return the zero value.
|
||||||
type varReplacer struct {
|
type varReplacer struct {
|
||||||
vars Vars
|
vars taskfile.Vars
|
||||||
strMap map[string]string
|
strMap map[string]string
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
@@ -283,7 +233,7 @@ func (r *varReplacer) replace(str string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r.strMap == nil {
|
if r.strMap == nil {
|
||||||
r.strMap = r.vars.toStringMap()
|
r.strMap = r.vars.ToStringMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
@@ -306,14 +256,14 @@ func (r *varReplacer) replaceSlice(strs []string) []string {
|
|||||||
return new
|
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 {
|
if r.err != nil || len(vars) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
new := make(Vars, len(vars))
|
new := make(taskfile.Vars, len(vars))
|
||||||
for k, v := range vars {
|
for k, v := range vars {
|
||||||
new[k] = Var{
|
new[k] = taskfile.Var{
|
||||||
Static: r.replace(v.Static),
|
Static: r.replace(v.Static),
|
||||||
Sh: r.replace(v.Sh),
|
Sh: r.replace(v.Sh),
|
||||||
}
|
}
|
||||||
|
13
watch.go
13
watch.go
@@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
"github.com/mattn/go-zglob"
|
"github.com/mattn/go-zglob"
|
||||||
"github.com/radovskyb/watcher"
|
"github.com/radovskyb/watcher"
|
||||||
)
|
)
|
||||||
@@ -15,7 +16,7 @@ var watchIgnoredDirs = []string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// watchTasks start watching the given tasks
|
// 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))
|
tasks := make([]string, len(calls))
|
||||||
for i, c := range calls {
|
for i, c := range calls {
|
||||||
tasks[i] = c.Task
|
tasks[i] = c.Task
|
||||||
@@ -83,7 +84,7 @@ func (e *Executor) watchTasks(calls ...Call) error {
|
|||||||
return w.Start(time.Second)
|
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{})
|
oldWatchedFiles := make(map[string]struct{})
|
||||||
for f := range w.WatchedFiles() {
|
for f := range w.WatchedFiles() {
|
||||||
oldWatchedFiles[f] = struct{}{}
|
oldWatchedFiles[f] = struct{}{}
|
||||||
@@ -95,21 +96,21 @@ func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...Call) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var registerTaskFiles func(Call) error
|
var registerTaskFiles func(taskfile.Call) error
|
||||||
registerTaskFiles = func(c Call) error {
|
registerTaskFiles = func(c taskfile.Call) error {
|
||||||
task, err := e.CompiledTask(c)
|
task, err := e.CompiledTask(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range task.Deps {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, c := range task.Cmds {
|
for _, c := range task.Cmds {
|
||||||
if c.Task != "" {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user