script: abort execution with a warning when the op is not concrete

Fixes #28

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi 2021-01-20 17:18:06 -08:00
parent 1d64422320
commit 4edc5764e5
2 changed files with 19 additions and 26 deletions

View File

@ -4,6 +4,11 @@ import (
"context" "context"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
var (
ErrAbortExecution = errors.New("execution stopped")
) )
type Script struct { type Script struct {
@ -25,8 +30,13 @@ func (s *Script) Execute(ctx context.Context, fs FS, out Fillable) (FS, error) {
// If op not concrete, interrupt without error. // If op not concrete, interrupt without error.
// This allows gradual resolution: // This allows gradual resolution:
// compute what you can compute.. leave the rest incomplete. // compute what you can compute.. leave the rest incomplete.
if !v.IsConcreteR() { if err := v.IsConcreteR(); err != nil {
return nil log.
Ctx(ctx).
Warn().
Err(err).
Msg("script is unspecified, aborting execution")
return ErrAbortExecution
} }
op, err := v.Op() op, err := v.Op()
if err != nil { if err != nil {
@ -38,6 +48,11 @@ func (s *Script) Execute(ctx context.Context, fs FS, out Fillable) (FS, error) {
} }
return nil return nil
}) })
// If the execution was gracefully stopped, do not return an error
if err == ErrAbortExecution {
return fs, nil
}
return fs, err return fs, err
} }

View File

@ -167,30 +167,8 @@ func (v *Value) MergeTarget(x interface{}, target string) (*Value, error) {
} }
// Recursive concreteness check. // Recursive concreteness check.
// Return false if v is not concrete, or contains any func (v *Value) IsConcreteR() error {
// non-concrete fields or items. return v.val.Validate(cue.Concrete(true))
func (v *Value) IsConcreteR() bool {
// FIXME: use Value.Walk
if it, err := v.Fields(); err == nil {
for it.Next() {
w := v.Wrap(it.Value())
if !w.IsConcreteR() {
return false
}
}
return true
}
if it, err := v.List(); err == nil {
for it.Next() {
w := v.Wrap(it.Value())
if !w.IsConcreteR() {
return false
}
}
return true
}
dv, _ := v.val.Default()
return v.val.IsConcrete() || dv.IsConcrete()
} }
// Export concrete values to JSON. ignoring non-concrete values. // Export concrete values to JSON. ignoring non-concrete values.