Simplify op.go by removing unnecessary cue validations

Signed-off-by: Solomon Hykes <sh.github.6811@hykes.org>
This commit is contained in:
Solomon Hykes 2021-02-07 08:01:51 +00:00
parent 612a25fb9f
commit 781b89e41c
2 changed files with 31 additions and 36 deletions

View File

@ -48,17 +48,15 @@ func (op *Op) Walk(ctx context.Context, fn func(*Op) error) error {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
lg.Debug().Interface("v", op.v).Msg("Op.Walk") lg.Debug().Interface("v", op.v).Msg("Op.Walk")
isCopy := (op.Validate("#Copy") == nil) switch op.Do() {
isLoad := (op.Validate("#Load") == nil) case "copy", "load":
if isCopy || isLoad {
if from, err := newExecutable(op.Get("from")); err == nil { if from, err := newExecutable(op.Get("from")); err == nil {
if err := from.Walk(ctx, fn); err != nil { if err := from.Walk(ctx, fn); err != nil {
return err return err
} }
} }
// FIXME: we tolerate "from" which is not executable // FIXME: we tolerate "from" which is not executable
} case "exec":
if err := op.Validate("#Exec"); err == nil {
return op.Get("mount").RangeStruct(func(k string, v *cc.Value) error { return op.Get("mount").RangeStruct(func(k string, v *cc.Value) error {
if from, err := newExecutable(op.Get("from")); err == nil { if from, err := newExecutable(op.Get("from")); err == nil {
if err := from.Walk(ctx, fn); err != nil { if err := from.Walk(ctx, fn); err != nil {
@ -74,43 +72,40 @@ func (op *Op) Walk(ctx context.Context, fn func(*Op) error) error {
type Action func(context.Context, FS, *Fillable) (FS, error) type Action func(context.Context, FS, *Fillable) (FS, error)
func (op *Op) Do() string {
do, err := op.Get("do").String()
if err != nil {
return ""
}
return do
}
func (op *Op) Action() (Action, error) { func (op *Op) Action() (Action, error) {
// An empty struct is allowed as a no-op, to be // An empty struct is allowed as a no-op, to be
// more tolerant of if() in arrays. // more tolerant of if() in arrays.
if op.v.IsEmptyStruct() { if op.v.IsEmptyStruct() {
return op.Nothing, nil return op.Nothing, nil
} }
// Manually check for a 'do' field. switch op.Do() {
// This is necessary because Runtime.ValidateSpec has a bug case "copy":
// where an empty struct matches everything. return op.Copy, nil
// see https://github.com/cuelang/cue/issues/566#issuecomment-749735878 case "exec":
// Once the bug is fixed, the manual check can be removed. return op.Exec, nil
if _, err := op.Get("do").String(); err != nil { case "export":
return nil, fmt.Errorf("invalid action: no \"do\" field") return op.Export, nil
} case "fetch-container":
actions := map[string]Action{ return op.FetchContainer, nil
"#Copy": op.Copy, case "fetch-git":
"#Exec": op.Exec, return op.FetchGit, nil
"#Export": op.Export, case "local":
"#FetchContainer": op.FetchContainer, return op.Local, nil
"#FetchGit": op.FetchGit, case "load":
"#Local": op.Local, return op.Load, nil
"#Load": op.Load, case "subdir":
"#Subdir": op.Subdir, return op.Subdir, nil
} default:
for def, action := range actions {
if err := op.Validate(def); err == nil {
return action, nil
}
}
return nil, fmt.Errorf("invalid operation: %s", op.v.JSON()) return nil, fmt.Errorf("invalid operation: %s", op.v.JSON())
}
func (op *Op) Validate(def string) error {
if err := spec.Validate(op.v, "#Op"); err != nil {
return err
} }
return spec.Validate(op.v, def)
} }
func (op *Op) Subdir(ctx context.Context, fs FS, out *Fillable) (FS, error) { func (op *Op) Subdir(ctx context.Context, fs FS, out *Fillable) (FS, error) {

View File

@ -122,7 +122,7 @@ func (s *Script) LocalDirs(ctx context.Context) (map[string]string, error) {
Msg("starting") Msg("starting")
dirs := map[string]string{} dirs := map[string]string{}
err := s.Walk(ctx, func(op *Op) error { err := s.Walk(ctx, func(op *Op) error {
if err := op.Validate("#Local"); err != nil { if op.Do() != "local" {
// Ignore all operations except 'do:"local"' // Ignore all operations except 'do:"local"'
return nil return nil
} }