101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
package execution
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"code.icb4dc0.de/buildr/buildr/modules"
|
|
)
|
|
|
|
type taskFactoryOption interface {
|
|
applyToFactory(f *TaskFactory)
|
|
}
|
|
|
|
type taskFactoryOptionFunc func(f *TaskFactory)
|
|
|
|
func (f taskFactoryOptionFunc) applyToFactory(factory *TaskFactory) {
|
|
f(factory)
|
|
}
|
|
|
|
func WithProvider(p TaskProvider) taskFactoryOption {
|
|
return taskFactoryOptionFunc(func(f *TaskFactory) {
|
|
f.providers = append(f.providers, p)
|
|
})
|
|
}
|
|
|
|
func NewTaskFactory(opts ...taskFactoryOption) *TaskFactory {
|
|
factory := &TaskFactory{
|
|
knownTasks: make(map[string]Task),
|
|
}
|
|
|
|
for i := range opts {
|
|
opts[i].applyToFactory(factory)
|
|
}
|
|
|
|
return factory
|
|
}
|
|
|
|
type TaskFactory struct {
|
|
knownTasks map[string]Task
|
|
providers []TaskProvider
|
|
}
|
|
|
|
func (f *TaskFactory) TaskForModuleWithoutDependencies(module modules.ModuleWithMeta) (Task, error) {
|
|
var t Task
|
|
|
|
for i := range f.providers {
|
|
if p := f.providers[i]; p.CanProvide(module) {
|
|
if task, err := p.Create(module); err != nil {
|
|
return nil, err
|
|
} else {
|
|
t = task
|
|
}
|
|
}
|
|
}
|
|
|
|
if t == nil {
|
|
return nil, fmt.Errorf("no provider available to handle module %s", module.Name())
|
|
}
|
|
|
|
return t, nil
|
|
}
|
|
|
|
func (f *TaskFactory) TaskForModule(id string, repo *modules.Repository) (Task, error) {
|
|
if t, ok := f.knownTasks[id]; ok {
|
|
return t, nil
|
|
}
|
|
|
|
module := repo.ModuleByID(id)
|
|
if module == nil {
|
|
return nil, fmt.Errorf("ID %s could not be resolved to module", id)
|
|
}
|
|
|
|
var t Task
|
|
|
|
for i := range f.providers {
|
|
if p := f.providers[i]; p.CanProvide(module) {
|
|
if task, err := p.Create(module); err != nil {
|
|
return nil, err
|
|
} else {
|
|
t = task
|
|
}
|
|
}
|
|
}
|
|
|
|
if t == nil {
|
|
return nil, fmt.Errorf("no provider available to handle module %s", module.Name())
|
|
}
|
|
|
|
f.knownTasks[id] = t
|
|
deps := module.Dependencies()
|
|
|
|
for i := range deps {
|
|
if dependent, err := f.TaskForModule(deps[i], repo); err != nil {
|
|
return nil, err
|
|
} else {
|
|
t.AddDependentTask(dependent)
|
|
}
|
|
}
|
|
|
|
return t, nil
|
|
}
|