github.com/octohelm/wagon@v0.0.0-20240308040401-88662650dc0b/pkg/engine/plan/internal/task.go (about) 1 package internal 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "reflect" 8 9 cueformat "cuelang.org/go/cue/format" 10 "github.com/octohelm/wagon/pkg/engine/plan" 11 "github.com/pkg/errors" 12 ) 13 14 type FlowTask interface { 15 flowTask() 16 } 17 18 type Task struct { 19 } 20 21 func (Task) flowTask() { 22 23 } 24 25 func taskFrom(r TaskRegister, t any) *task { 26 tpe := reflect.TypeOf(t) 27 if tpe.Kind() == reflect.Ptr { 28 tpe = tpe.Elem() 29 } 30 31 c := newConvert(r) 32 33 pt := &task{ 34 tpe: tpe, 35 outputFields: map[string]int{}, 36 cueType: c.toCueType(tpe, opt{naming: tpe.Name()}), 37 } 38 39 if _, ok := t.(FlowTask); ok { 40 pt.flowTask = true 41 } 42 43 walkFields(tpe, func(info *fieldInfo) { 44 for _, attr := range info.attrs { 45 if attr == "generated" { 46 pt.outputFields[info.name] = info.idx 47 } 48 } 49 }) 50 51 return pt 52 } 53 54 type task struct { 55 tpe reflect.Type 56 outputFields map[string]int 57 flowTask bool 58 cueType []byte 59 } 60 61 func (t *task) Name() string { 62 return t.tpe.Name() 63 } 64 65 func (t *task) New(planTask plan.Task) (plan.TaskRunner, error) { 66 r := &taskRunner{ 67 task: planTask, 68 inputTaskRunner: reflect.New(t.tpe), 69 outputFields: map[string]int{}, 70 } 71 72 for f, i := range t.outputFields { 73 r.outputFields[f] = i 74 } 75 76 return r, nil 77 } 78 79 func (t *task) WriteCueDeclTo(w io.Writer) error { 80 b := bytes.NewBuffer(nil) 81 name := t.Name() 82 83 if t.flowTask { 84 _, _ = fmt.Fprintf(b, `#%s: $wagon: task: name: %q 85 `, name, name) 86 } 87 88 _, _ = fmt.Fprintf(b, `#%s: %s 89 `, name, t.cueType) 90 91 data, err := cueformat.Source(b.Bytes(), cueformat.Simplify()) 92 if err != nil { 93 return errors.Wrapf(err, `format invalid: %s`, b.Bytes()) 94 } 95 _, err = w.Write(data) 96 return err 97 }