1
0
mirror of https://github.com/go-task/task.git synced 2025-06-27 00:51:05 +02:00

Run deps concurrently

This commit is contained in:
Andrey Nering
2017-03-15 20:19:29 -03:00
parent 419a74b018
commit ce823ad510

63
task.go
View File

@ -5,6 +5,7 @@ import (
"log" "log"
"os" "os"
"strings" "strings"
"sync"
"github.com/go-task/task/execext" "github.com/go-task/task/execext"
@ -22,6 +23,7 @@ var (
Tasks = make(map[string]*Task) Tasks = make(map[string]*Task)
runnedTasks = make(map[string]struct{}) runnedTasks = make(map[string]struct{})
mu sync.Mutex
) )
// Task represents a task // Task represents a task
@ -61,30 +63,22 @@ func Run() {
// RunTask runs a task by its name // RunTask runs a task by its name
func RunTask(name string) error { func RunTask(name string) error {
mu.Lock()
if _, found := runnedTasks[name]; found { if _, found := runnedTasks[name]; found {
mu.Unlock()
return &cyclicDepError{name} return &cyclicDepError{name}
} }
runnedTasks[name] = struct{}{} runnedTasks[name] = struct{}{}
mu.Unlock()
t, ok := Tasks[name] t, ok := Tasks[name]
if !ok { if !ok {
return &taskNotFoundError{name} return &taskNotFoundError{name}
} }
vars, err := t.handleVariables() if err := t.runDeps(); err != nil {
if err != nil {
return &taskRunError{name, err}
}
for _, d := range t.Deps {
d, err = ReplaceVariables(d, vars)
if err != nil {
return err return err
} }
if err = RunTask(d); err != nil {
return err
}
}
if !Force && t.isUpToDate() { if !Force && t.isUpToDate() {
log.Printf(`task: Task "%s" is up to date`, name) log.Printf(`task: Task "%s" is up to date`, name)
@ -92,13 +86,56 @@ func RunTask(name string) error {
} }
for i := range t.Cmds { for i := range t.Cmds {
if err = t.runCommand(i); err != nil { if err := t.runCommand(i); err != nil {
return &taskRunError{name, err} return &taskRunError{name, err}
} }
} }
return nil return nil
} }
func (t *Task) runDeps() error {
vars, err := t.handleVariables()
if err != nil {
return err
}
var (
wg sync.WaitGroup
errChan = make(chan error)
doneChan = make(chan struct{})
)
for _, d := range t.Deps {
wg.Add(1)
go func(dep string) {
defer wg.Done()
dep, err := ReplaceVariables(dep, vars)
if err != nil {
errChan <- err
return
}
if err := RunTask(dep); err != nil {
errChan <- err
}
}(d)
}
go func() {
wg.Wait()
doneChan <- struct{}{}
}()
select {
case err := <-errChan:
return err
case <-doneChan:
return nil
}
}
func (t *Task) isUpToDate() bool { func (t *Task) isUpToDate() bool {
if len(t.Sources) == 0 || len(t.Generates) == 0 { if len(t.Sources) == 0 || len(t.Generates) == 0 {
return false return false