Simplify Env API: Compute/Components instead of Compute/Walk
Signed-off-by: Solomon Hykes <sh.github.6811@hykes.org>
This commit is contained in:
parent
5b7bc78cf1
commit
0fe2ef4fe4
@ -165,22 +165,18 @@ func (env *Env) LocalDirs(ctx context.Context) (map[string]string, error) {
|
|||||||
lg.Debug().Str("func", "Env.LocalDirs").Interface("result", dirs).Msg("done")
|
lg.Debug().Str("func", "Env.LocalDirs").Interface("result", dirs).Msg("done")
|
||||||
}()
|
}()
|
||||||
// 1. Walk env state, scan compute script for each component.
|
// 1. Walk env state, scan compute script for each component.
|
||||||
_, err := env.Walk(ctx, func(ctx context.Context, c *Component, out *Fillable) error {
|
for _, c := range env.Components() {
|
||||||
lg.Debug().
|
lg.Debug().
|
||||||
Str("func", "Env.LocalDirs").
|
Str("func", "Env.LocalDirs").
|
||||||
Str("component", c.Value().Path().String()).
|
Str("component", c.Value().Path().String()).
|
||||||
Msg("scanning next component for local dirs")
|
Msg("scanning next component for local dirs")
|
||||||
cdirs, err := c.LocalDirs(ctx)
|
cdirs, err := c.LocalDirs(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return dirs, err
|
||||||
}
|
}
|
||||||
for k, v := range cdirs {
|
for k, v := range cdirs {
|
||||||
dirs[k] = v
|
dirs[k] = v
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return dirs, err
|
|
||||||
}
|
}
|
||||||
// 2. Scan updater script
|
// 2. Scan updater script
|
||||||
updirs, err := env.updater.LocalDirs(ctx)
|
updirs, err := env.updater.LocalDirs(ctx)
|
||||||
@ -193,31 +189,24 @@ func (env *Env) LocalDirs(ctx context.Context) (map[string]string, error) {
|
|||||||
return dirs, nil
|
return dirs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute missing values in env configuration, and write them to state.
|
// Return a list of components in the env config.
|
||||||
func (env *Env) Compute(ctx context.Context, s Solver) error {
|
func (env *Env) Components() []*Component {
|
||||||
output, err := env.Walk(ctx, func(ctx context.Context, c *Component, out *Fillable) error {
|
components := []*Component{}
|
||||||
lg := log.Ctx(ctx)
|
env.State().Walk(
|
||||||
|
func(v *Value) bool {
|
||||||
lg.
|
c, err := NewComponent(v)
|
||||||
Debug().
|
if os.IsNotExist(err) {
|
||||||
Msg("[Env.Compute] processing")
|
return true
|
||||||
if _, err := c.Compute(ctx, s, out); err != nil {
|
|
||||||
lg.
|
|
||||||
Error().
|
|
||||||
Err(err).
|
|
||||||
Msg("component failed")
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false
|
||||||
}
|
}
|
||||||
return env.set(
|
components = append(components, c)
|
||||||
env.base,
|
return false // skip nested components, as cueflow does not allow them
|
||||||
env.input,
|
},
|
||||||
output,
|
nil,
|
||||||
)
|
)
|
||||||
|
return components
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this is just a 3-way merge. Add var args to Value.Merge.
|
// FIXME: this is just a 3-way merge. Add var args to Value.Merge.
|
||||||
@ -285,11 +274,8 @@ func (env *Env) Export(fs FS) (FS, error) {
|
|||||||
return fs, nil
|
return fs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: don't need ctx here
|
// Compute missing values in env configuration, and write them to state.
|
||||||
type EnvWalkFunc func(context.Context, *Component, *Fillable) error
|
func (env *Env) Compute(ctx context.Context, s Solver) error {
|
||||||
|
|
||||||
// Walk components and return any computed values
|
|
||||||
func (env *Env) Walk(ctx context.Context, fn EnvWalkFunc) (*Value, error) {
|
|
||||||
lg := log.Ctx(ctx)
|
lg := log.Ctx(ctx)
|
||||||
|
|
||||||
// Cueflow cue instance
|
// Cueflow cue instance
|
||||||
@ -300,9 +286,9 @@ func (env *Env) Walk(ctx context.Context, fn EnvWalkFunc) (*Value, error) {
|
|||||||
Msg("walking")
|
Msg("walking")
|
||||||
|
|
||||||
// Initialize empty output
|
// Initialize empty output
|
||||||
out, err := env.cc.EmptyStruct()
|
output, err := env.cc.EmptyStruct()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cueflow config
|
// Cueflow config
|
||||||
@ -325,7 +311,7 @@ func (env *Env) Walk(ctx context.Context, fn EnvWalkFunc) (*Value, error) {
|
|||||||
lg.Debug().Msg("cueflow task: filling result")
|
lg.Debug().Msg("cueflow task: filling result")
|
||||||
// Merge task value into output
|
// Merge task value into output
|
||||||
var err error
|
var err error
|
||||||
out, err = out.MergePath(t.Value(), t.Path())
|
output, err = output.MergePath(t.Value(), t.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lg.
|
lg.
|
||||||
Error().
|
Error().
|
||||||
@ -362,15 +348,26 @@ func (env *Env) Walk(ctx context.Context, fn EnvWalkFunc) (*Value, error) {
|
|||||||
Str("dependency", dep.Path().String()).
|
Str("dependency", dep.Path().String()).
|
||||||
Msg("dependency detected")
|
Msg("dependency detected")
|
||||||
}
|
}
|
||||||
return fn(ctx, c, NewFillable(t))
|
if _, err := c.Compute(ctx, s, NewFillable(t)); err != nil {
|
||||||
|
lg.
|
||||||
|
Error().
|
||||||
|
Err(err).
|
||||||
|
Msg("component failed")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
// Orchestrate execution with cueflow
|
// Orchestrate execution with cueflow
|
||||||
flow := cueflow.New(flowCfg, flowInst, flowMatchFn)
|
flow := cueflow.New(flowCfg, flowInst, flowMatchFn)
|
||||||
if err := flow.Run(ctx); err != nil {
|
if err := flow.Run(ctx); err != nil {
|
||||||
return out, err
|
return err
|
||||||
}
|
}
|
||||||
return out, nil
|
return env.set(
|
||||||
|
env.base,
|
||||||
|
env.input,
|
||||||
|
output,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the component at the specified path in the config, eg. `www`
|
// Return the component at the specified path in the config, eg. `www`
|
||||||
|
@ -192,6 +192,25 @@ func (v *Value) IsConcreteR() error {
|
|||||||
return v.val.Validate(cue.Concrete(true))
|
return v.val.Validate(cue.Concrete(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Value) Walk(before func(*Value) bool, after func(*Value)) {
|
||||||
|
// FIXME: lock?
|
||||||
|
var (
|
||||||
|
llBefore func(cue.Value) bool
|
||||||
|
llAfter func(cue.Value)
|
||||||
|
)
|
||||||
|
if before != nil {
|
||||||
|
llBefore = func(child cue.Value) bool {
|
||||||
|
return before(v.Wrap(child))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if after != nil {
|
||||||
|
llAfter = func(child cue.Value) {
|
||||||
|
after(v.Wrap(child))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v.val.Walk(llBefore, llAfter)
|
||||||
|
}
|
||||||
|
|
||||||
// Export concrete values to JSON. ignoring non-concrete values.
|
// Export concrete values to JSON. ignoring non-concrete values.
|
||||||
// Contrast with cue.Value.MarshalJSON which requires all values
|
// Contrast with cue.Value.MarshalJSON which requires all values
|
||||||
// to be concrete.
|
// to be concrete.
|
||||||
|
Reference in New Issue
Block a user