From eab6028b70c36b80a4edc52e37262d93f9371e94 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Thu, 21 Jan 2021 16:49:25 -0800 Subject: [PATCH] Replace Fillable interface with a concrete wrapper Signed-off-by: Solomon Hykes --- dagger/component.go | 4 ++-- dagger/env.go | 8 ++++---- dagger/mount.go | 2 +- dagger/op.go | 24 ++++++++++++------------ dagger/script.go | 2 +- dagger/types.go | 24 +++++++++++++++--------- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/dagger/component.go b/dagger/component.go index 78c1f4bf..68030251 100644 --- a/dagger/component.go +++ b/dagger/component.go @@ -52,7 +52,7 @@ func (c *Component) ComputeScript() (*Script, error) { // 1. Always start with an empty fs state (Execute may receive any state as input) // 2. Always solve at the end (Execute is lazy) // -func (c *Component) Compute(ctx context.Context, s Solver, out Fillable) (FS, error) { +func (c *Component) Compute(ctx context.Context, s Solver, out *Fillable) (FS, error) { fs, err := c.Execute(ctx, s.Scratch(), out) if err != nil { return fs, err @@ -67,7 +67,7 @@ func (c *Component) Compute(ctx context.Context, s Solver, out Fillable) (FS, er // A component implements the Executable interface by returning its // compute script. // See Value.Executable(). -func (c *Component) Execute(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (c *Component) Execute(ctx context.Context, fs FS, out *Fillable) (FS, error) { script, err := c.ComputeScript() if err != nil { // If the component has no script, then do not fail. diff --git a/dagger/env.go b/dagger/env.go index 2f912cf7..a5bab626 100644 --- a/dagger/env.go +++ b/dagger/env.go @@ -43,7 +43,7 @@ func NewEnv(ctx context.Context, s Solver, bootsrc, inputsrc string) (*Env, erro if err != nil { return nil, errors.Wrap(err, "compile boot script") } - bootfs, err := boot.Execute(ctx, s.Scratch(), Discard()) + bootfs, err := boot.Execute(ctx, s.Scratch(), nil) if err != nil { return nil, errors.Wrap(err, "execute boot script") } @@ -81,7 +81,7 @@ func NewEnv(ctx context.Context, s Solver, bootsrc, inputsrc string) (*Env, erro // Compute missing values in env configuration, and write them to state. func (env *Env) Compute(ctx context.Context) error { - output, err := env.Walk(ctx, func(ctx context.Context, c *Component, out Fillable) error { + output, err := env.Walk(ctx, func(ctx context.Context, c *Component, out *Fillable) error { lg := log.Ctx(ctx) lg. @@ -119,7 +119,7 @@ func (env *Env) Export(fs FS) (FS, error) { return fs, nil } -type EnvWalkFunc func(context.Context, *Component, Fillable) error +type EnvWalkFunc func(context.Context, *Component, *Fillable) error // Walk components and return any computed values func (env *Env) Walk(ctx context.Context, fn EnvWalkFunc) (*Value, error) { @@ -195,7 +195,7 @@ func (env *Env) Walk(ctx context.Context, fn EnvWalkFunc) (*Value, error) { return nil, err } return cueflow.RunnerFunc(func(t *cueflow.Task) error { - return fn(ctx, c, t) + return fn(ctx, c, NewFillable(t)) }), nil } // Orchestrate execution with cueflow diff --git a/dagger/mount.go b/dagger/mount.go index b66144f4..ecfa20e2 100644 --- a/dagger/mount.go +++ b/dagger/mount.go @@ -30,7 +30,7 @@ func (mnt *Mount) LLB(ctx context.Context, s Solver) (llb.RunOption, error) { if err != nil { return nil, errors.Wrap(err, "from") } - fromFS, err := from.Execute(ctx, s.Scratch(), Discard()) + fromFS, err := from.Execute(ctx, s.Scratch(), nil) if err != nil { return nil, err } diff --git a/dagger/op.go b/dagger/op.go index 7a376bc2..c56499da 100644 --- a/dagger/op.go +++ b/dagger/op.go @@ -14,7 +14,7 @@ type Op struct { v *Value } -func (op *Op) Execute(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) Execute(ctx context.Context, fs FS, out *Fillable) (FS, error) { action, err := op.Action() if err != nil { return fs, err @@ -50,7 +50,7 @@ func (op *Op) Walk(ctx context.Context, fn func(*Op) error) error { return fn(op) } -type Action func(context.Context, FS, Fillable) (FS, error) +type Action func(context.Context, FS, *Fillable) (FS, error) func (op *Op) Action() (Action, error) { // An empty struct is allowed as a no-op, to be @@ -88,7 +88,7 @@ func (op *Op) Validate(defs ...string) error { return op.v.Validate(defs...) } -func (op *Op) Copy(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) Copy(ctx context.Context, fs FS, out *Fillable) (FS, error) { // Decode copy options src, err := op.Get("src").String() if err != nil { @@ -103,7 +103,7 @@ func (op *Op) Copy(ctx context.Context, fs FS, out Fillable) (FS, error) { return fs, errors.Wrap(err, "from") } // Compute source component or script, discarding fs writes & output value - fromFS, err := from.Execute(ctx, fs.Solver().Scratch(), Discard()) + fromFS, err := from.Execute(ctx, fs.Solver().Scratch(), nil) if err != nil { return fs, err } @@ -123,10 +123,10 @@ func (op *Op) Copy(ctx context.Context, fs FS, out Fillable) (FS, error) { }), nil // lazy solve } -func (op *Op) Nothing(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) Nothing(ctx context.Context, fs FS, out *Fillable) (FS, error) { return fs, nil } -func (op *Op) Local(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) Local(ctx context.Context, fs FS, out *Fillable) (FS, error) { dir, err := op.Get("dir").String() if err != nil { return fs, err @@ -138,7 +138,7 @@ func (op *Op) Local(ctx context.Context, fs FS, out Fillable) (FS, error) { return fs.Set(llb.Local(dir, llb.FollowPaths(include))), nil // lazy solve } -func (op *Op) Exec(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) Exec(ctx context.Context, fs FS, out *Fillable) (FS, error) { opts := []llb.RunOption{} var cmd struct { Args []string @@ -187,7 +187,7 @@ func (op *Op) Exec(ctx context.Context, fs FS, out Fillable) (FS, error) { }), nil // lazy solve } -func (op *Op) Export(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) Export(ctx context.Context, fs FS, out *Fillable) (FS, error) { source, err := op.Get("source").String() if err != nil { return fs, err @@ -232,26 +232,26 @@ func (op *Op) Export(ctx context.Context, fs FS, out Fillable) (FS, error) { return fs, nil } -func (op *Op) Load(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) Load(ctx context.Context, fs FS, out *Fillable) (FS, error) { from, err := op.Get("from").Executable() if err != nil { return fs, errors.Wrap(err, "load") } - fromFS, err := from.Execute(ctx, fs.Solver().Scratch(), Discard()) + fromFS, err := from.Execute(ctx, fs.Solver().Scratch(), nil) if err != nil { return fs, errors.Wrap(err, "load: compute source") } return fs.Set(fromFS.LLB()), nil } -func (op *Op) FetchContainer(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) FetchContainer(ctx context.Context, fs FS, out *Fillable) (FS, error) { ref, err := op.Get("ref").String() if err != nil { return fs, err } return fs.Set(llb.Image(ref)), nil } -func (op *Op) FetchGit(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (op *Op) FetchGit(ctx context.Context, fs FS, out *Fillable) (FS, error) { remote, err := op.Get("remote").String() if err != nil { return fs, err diff --git a/dagger/script.go b/dagger/script.go index 83e64542..fd566f6b 100644 --- a/dagger/script.go +++ b/dagger/script.go @@ -25,7 +25,7 @@ func (s *Script) Value() *Value { } // Run a dagger script -func (s *Script) Execute(ctx context.Context, fs FS, out Fillable) (FS, error) { +func (s *Script) Execute(ctx context.Context, fs FS, out *Fillable) (FS, error) { err := s.v.RangeList(func(idx int, v *Value) error { // If op not concrete, interrupt without error. // This allows gradual resolution: diff --git a/dagger/types.go b/dagger/types.go index 10a3b5d4..44b9fdcc 100644 --- a/dagger/types.go +++ b/dagger/types.go @@ -2,25 +2,31 @@ package dagger import ( "context" + + cueflow "cuelang.org/go/tools/flow" ) // Implemented by Component, Script, Op type Executable interface { - Execute(context.Context, FS, Fillable) (FS, error) + Execute(context.Context, FS, *Fillable) (FS, error) Walk(context.Context, func(*Op) error) error } // Something which can be filled in-place with a cue value -type Fillable interface { - Fill(interface{}) error +type Fillable struct { + t *cueflow.Task } -func Discard() Fillable { - return discard{} +func NewFillable(t *cueflow.Task) *Fillable { + return &Fillable{ + t: t, + } } -type discard struct{} - -func (d discard) Fill(x interface{}) error { - return nil +func (f *Fillable) Fill(x interface{}) error { + // Use a nil pointer receiver to discard all values + if f == nil { + return nil + } + return f.t.Fill(x) }