125 lines
2.2 KiB
Go
125 lines
2.2 KiB
Go
package detect
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/evcc-io/evcc/detect/tasks"
|
|
"github.com/evcc-io/evcc/util"
|
|
)
|
|
|
|
type TaskList struct {
|
|
tasks []tasks.Task
|
|
once sync.Once
|
|
}
|
|
|
|
func (l *TaskList) Add(task tasks.Task) {
|
|
task.TaskHandler = l.handler(task)
|
|
l.tasks = append(l.tasks, task)
|
|
}
|
|
|
|
func (l *TaskList) Count() int {
|
|
return len(l.tasks)
|
|
}
|
|
|
|
func (l *TaskList) delete(i int) {
|
|
if len(l.tasks) == 1 {
|
|
l.tasks = nil
|
|
}
|
|
|
|
res := l.tasks[:i]
|
|
if i < len(l.tasks)-1 {
|
|
res = append(res, l.tasks[i+1:]...)
|
|
}
|
|
|
|
l.tasks = res
|
|
}
|
|
|
|
func (l *TaskList) sort() {
|
|
var res []tasks.Task
|
|
|
|
for len(l.tasks) > 0 {
|
|
last := len(l.tasks)
|
|
|
|
NEXT:
|
|
for i, task := range l.tasks {
|
|
if task.Depends == "" {
|
|
res = append(res, task)
|
|
l.delete(i)
|
|
break NEXT
|
|
}
|
|
|
|
for _, sortedTask := range res {
|
|
if task.Depends == sortedTask.ID {
|
|
res = append(res, task)
|
|
l.delete(i)
|
|
break NEXT
|
|
}
|
|
}
|
|
}
|
|
|
|
if last == len(l.tasks) {
|
|
panic("tasks with unmatched dependencies: " + fmt.Sprintf("%v", l))
|
|
}
|
|
}
|
|
|
|
l.tasks = res
|
|
}
|
|
|
|
func (l *TaskList) handler(task tasks.Task) tasks.TaskHandler {
|
|
factory, err := tasks.Get(task.Type)
|
|
if err != nil {
|
|
panic("invalid task type " + task.Type)
|
|
}
|
|
|
|
// fmt.Println(task)
|
|
handler, err := factory(task.Config)
|
|
if err != nil {
|
|
panic("invalid config: " + err.Error())
|
|
}
|
|
|
|
return handler
|
|
}
|
|
|
|
func (l *TaskList) Test(log *util.Logger, id string, input tasks.ResultDetails) []tasks.Result {
|
|
l.once.Do(l.sort)
|
|
|
|
var all []tasks.Result
|
|
var inputs []tasks.ResultDetails
|
|
|
|
if id == "" {
|
|
inputs = append(inputs, input)
|
|
} else {
|
|
var task tasks.Task
|
|
for _, t := range l.tasks {
|
|
if t.ID == id {
|
|
task = t
|
|
break
|
|
}
|
|
}
|
|
|
|
inputs = task.Test(log, input)
|
|
success := len(inputs) > 0
|
|
log.DEBUG.Printf("task: %s %v -> %v", id, input, success)
|
|
|
|
for _, detail := range inputs {
|
|
all = append(all, tasks.Result{
|
|
Task: task,
|
|
ResultDetails: detail,
|
|
})
|
|
}
|
|
}
|
|
|
|
// run dependent tasks
|
|
for _, task := range l.tasks {
|
|
if task.Depends == id {
|
|
// fmt.Println("task:", task)
|
|
for _, input := range inputs {
|
|
// fmt.Println("input:", input)
|
|
all = append(all, l.Test(log, task.ID, input)...)
|
|
}
|
|
}
|
|
}
|
|
|
|
return all
|
|
}
|