2022-02-22 22:04:54 +01:00
|
|
|
package plan
|
|
|
|
|
|
|
|
import (
|
|
|
|
"cuelang.org/go/cue"
|
2022-03-28 21:47:42 +02:00
|
|
|
"go.dagger.io/dagger/compiler"
|
2022-02-22 22:04:54 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Action struct {
|
2022-03-11 20:32:29 +01:00
|
|
|
Name string
|
|
|
|
Hidden bool
|
|
|
|
Path cue.Path
|
|
|
|
Documentation string
|
|
|
|
Children []*Action
|
2022-03-28 21:47:42 +02:00
|
|
|
Value *compiler.Value
|
|
|
|
inputs []Input
|
|
|
|
}
|
|
|
|
|
|
|
|
type Input struct {
|
|
|
|
Name string
|
|
|
|
Type string
|
|
|
|
Documentation string
|
2022-02-22 22:04:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2022-03-28 21:47:42 +02:00
|
|
|
|
|
|
|
func (a *Action) FindClosest(path cue.Path) *Action {
|
|
|
|
if a.Path.String() == path.String() {
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
commonSubPath := commonSubPath(a.Path, path)
|
|
|
|
if commonSubPath.String() == a.Path.String() {
|
|
|
|
if len(a.Children) > 0 {
|
|
|
|
for _, c := range a.Children {
|
|
|
|
if c.Path.String() == path.String() {
|
|
|
|
return c.FindClosest(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func commonSubPath(a, b cue.Path) cue.Path {
|
|
|
|
if a.String() == b.String() {
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
aSelectors := a.Selectors()
|
|
|
|
bSelectors := b.Selectors()
|
|
|
|
commonSelectors := []cue.Selector{}
|
|
|
|
for i := 0; i < len(aSelectors) && i < len(bSelectors); i++ {
|
|
|
|
if aSelectors[i].String() != bSelectors[i].String() {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
commonSelectors = append(commonSelectors, aSelectors[i])
|
|
|
|
}
|
|
|
|
return cue.MakePath(commonSelectors...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Action) Inputs() []Input {
|
|
|
|
if a.inputs == nil {
|
|
|
|
cueVal := a.Value.Cue()
|
|
|
|
inputs := []Input{}
|
|
|
|
for iter, _ := cueVal.Fields(cue.All()); iter.Next(); {
|
|
|
|
val := iter.Value()
|
|
|
|
cVal := compiler.Wrap(val)
|
|
|
|
|
|
|
|
_, refPath := val.ReferencePath()
|
|
|
|
|
|
|
|
ik := val.IncompleteKind()
|
|
|
|
validKind := ik == cue.StringKind || ik == cue.NumberKind || ik == cue.BoolKind || ik == cue.IntKind || ik == cue.FloatKind
|
|
|
|
if validKind && !val.IsConcrete() && len(refPath.Selectors()) == 0 {
|
|
|
|
inputs = append(inputs, Input{
|
|
|
|
Name: iter.Label(),
|
|
|
|
Type: ik.String(),
|
|
|
|
Documentation: cVal.DocSummary(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a.inputs = inputs
|
|
|
|
}
|
|
|
|
return a.inputs
|
|
|
|
}
|