github.com/mavryk-network/mvgo@v1.19.9/internal/compose/run.go (about) 1 // Copyright (c) 2023 Blockwatch Data Inc. 2 // Author: alex@blockwatch.cc, abdul@blockwatch.cc 3 4 package compose 5 6 import ( 7 "fmt" 8 "io/fs" 9 "os" 10 "path/filepath" 11 "strings" 12 ) 13 14 type RunMode byte 15 16 const ( 17 RunModeValidate RunMode = iota 18 RunModeSimulate 19 RunModeExecute 20 ) 21 22 type Spec struct { 23 Version string `yaml:"version"` 24 Filename string `yaml:"-"` 25 } 26 27 func Run(ctx Context, fpath string, mode RunMode) error { 28 ctx.Log.Debug("Initializing context...") 29 ctx.WithMode(mode) 30 if err := ctx.Init(); err != nil { 31 return err 32 } 33 visitRecursive := strings.HasSuffix(fpath, "...") 34 fpath = strings.TrimSuffix(fpath, "...") 35 finfo, err := os.Stat(fpath) 36 if err != nil { 37 return err 38 } 39 if finfo.IsDir() { 40 isFirst := true 41 return filepath.WalkDir(fpath, func(path string, d fs.DirEntry, err error) error { 42 if err != nil { 43 return err 44 } 45 if d.IsDir() { 46 if visitRecursive || isFirst { 47 isFirst = false 48 return nil 49 } else { 50 return filepath.SkipDir 51 } 52 } 53 if _, ok := yamlExts[filepath.Ext(path)]; !ok { 54 return nil 55 } 56 return handleFile(ctx, path, mode) 57 }) 58 } else { 59 return handleFile(ctx, fpath, mode) 60 } 61 } 62 63 func handleFile(ctx Context, fpath string, mode RunMode) error { 64 ctx.Log.Debugf("Reading file %s", fpath) 65 s, err := ParseFile[Spec](fpath) 66 if err != nil { 67 return err 68 } 69 s.Filename = fpath 70 71 ver := s.Version 72 if ver == "" { 73 ver = lastVersion 74 } 75 if !HasVersion(ver) { 76 return fmt.Errorf("%s: %v", fpath, ErrInvalidVersion) 77 } 78 eng := New(ver) 79 switch mode { 80 case RunModeValidate: 81 ctx.Log.Debugf("Validating file %s", s.Filename) 82 err = eng.Validate(ctx, s.Filename) 83 case RunModeSimulate: 84 ctx.Log.Debugf("Simulating file %s", s.Filename) 85 err = eng.Run(ctx, s.Filename) 86 case RunModeExecute: 87 ctx.Log.Debugf("Running file %s", s.Filename) 88 err = eng.Run(ctx, s.Filename) 89 } 90 if err != nil { 91 return fmt.Errorf("%s: %v", fpath, err) 92 } else { 93 ctx.Log.Infof("%s OK", s.Filename) 94 } 95 return nil 96 }