implements dagger do

Signed-off-by: Richard Jones <richard@dagger.io>
This commit is contained in:
Richard Jones
2022-02-22 14:04:54 -07:00
parent 621edd6b2f
commit 6cdf13223c
23 changed files with 486 additions and 335 deletions

34
plan/action.go Normal file
View File

@@ -0,0 +1,34 @@
package plan
import (
"cuelang.org/go/cue"
)
type Action struct {
Name string
Hidden bool
Path cue.Path
Comment string
Children []*Action
// pkg string
}
func (a *Action) AddChild(c *Action) {
a.Children = append(a.Children, c)
}
func (a *Action) FindByPath(path cue.Path) *Action {
queue := []*Action{a}
for len(queue) > 0 {
nextUp := queue[0]
queue = queue[1:]
if nextUp.Path.String() == path.String() {
return nextUp
}
if len(nextUp.Children) > 0 {
queue = append(queue, nextUp.Children...)
}
}
return nil
}

View File

@@ -17,11 +17,16 @@ import (
"go.opentelemetry.io/otel"
)
const (
ActionsPath = "actions"
)
type Plan struct {
config Config
context *plancontext.Context
source *compiler.Value
action *Action
}
type Config struct {
@@ -66,6 +71,8 @@ func Load(ctx context.Context, cfg Config) (*Plan, error) {
source: v,
}
p.fillAction()
if err := p.configPlatform(); err != nil {
return nil, err
}
@@ -85,6 +92,10 @@ func (p *Plan) Source() *compiler.Value {
return p.source
}
func (p *Plan) Action() *Action {
return p.action
}
// configPlatform load the platform specified in the context
// Buildkit will then run every operation using that platform
// If platform is not define, context keep default platform
@@ -186,6 +197,78 @@ func (p *Plan) Up(ctx context.Context, s solver.Solver) (*compiler.Value, error)
}
}
func (p *Plan) fillAction() {
cfg := &cueflow.Config{
FindHiddenTasks: true,
Root: cue.ParsePath(ActionsPath),
}
flow := cueflow.New(
cfg,
p.source.Cue(),
noOpRunner,
)
actions := p.source.Lookup(ActionsPath)
actionsComment := ""
for _, cg := range actions.Doc() {
actionsComment += cg.Text()
}
p.action = &Action{
ActionsPath,
false,
actions.Path(),
actionsComment,
[]*Action{},
}
tasks := flow.Tasks()
for _, t := range tasks {
var q []cue.Selector
prevAction := p.action
for _, s := range t.Path().Selectors() {
q = append(q, s)
path := cue.MakePath(q...)
a := prevAction.FindByPath(path)
if a == nil {
v := p.Source().LookupPath(path)
childComment := ""
for _, cg := range v.Doc() {
childComment += cg.Text()
}
a = &Action{
s.String(),
s.PkgPath() != "",
path,
childComment,
[]*Action{},
}
prevAction.AddChild(a)
}
prevAction = a
}
}
}
func noOpRunner(flowVal cue.Value) (cueflow.Runner, error) {
v := compiler.Wrap(flowVal)
_, err := task.Lookup(v)
if err != nil {
// Not a task
if err == task.ErrNotTask {
return nil, nil
}
return nil, err
}
// Wrapper around `task.Run` that handles logging, tracing, etc.
return cueflow.RunnerFunc(func(t *cueflow.Task) error {
return nil
}), nil
}
func newRunner(pctx *plancontext.Context, s solver.Solver, computed *compiler.Value) cueflow.TaskFunc {
return func(flowVal cue.Value) (cueflow.Runner, error) {
v := compiler.Wrap(flowVal)