github.com/tooploox/oya@v0.0.21-0.20230524103240-1cda1861aad6/pkg/oyafile/imports.go (about) 1 package oyafile 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/pkg/errors" 8 "github.com/tooploox/oya/pkg/template" 9 "github.com/tooploox/oya/pkg/types" 10 ) 11 12 type PackLoader interface { 13 Load(importPath types.ImportPath) (*Oyafile, bool, error) 14 } 15 16 func (oyafile *Oyafile) Build(loader PackLoader) error { 17 // Do not resolve imports when loading Oyafile. Sometimes, we need to load Oyafile before packs are ready to be imported. 18 if !oyafile.IsBuilt { 19 err := oyafile.resolveImports(loader) 20 if err != nil { 21 return err 22 } 23 oyafile.IsBuilt = true 24 } 25 return nil 26 } 27 28 func (oyafile *Oyafile) resolveImports(loader PackLoader) error { 29 for alias, importPath := range oyafile.Imports { 30 packOyafile, err := oyafile.loadPackOyafile(loader, importPath) 31 if err != nil { 32 return err 33 } 34 err = packOyafile.Build(loader) 35 if err != nil { 36 return err 37 } 38 err = oyafile.Values.UpdateScopeAt(string(alias), 39 func(scope template.Scope) template.Scope { 40 // Values in the main Oyafile overwrite values in the pack Oyafile. 41 merged := packOyafile.Values.Merge(scope) 42 merged = merged.Merge(aliasBuiltin(alias)) 43 // Task is keeping a pointed to the scope. 44 packOyafile.Values.Replace(merged) 45 return merged 46 }, false) 47 if err != nil { 48 return errors.Wrapf(err, "error merging values for imported pack %v", alias) 49 } 50 51 oyafile.Tasks.ImportTasks(alias, packOyafile.Tasks) 52 } 53 return nil 54 } 55 56 func (oyafile *Oyafile) loadPackOyafile(loader PackLoader, importPath types.ImportPath) (*Oyafile, error) { 57 o, found, err := loader.Load(importPath) 58 if err != nil { 59 return nil, err 60 } 61 if found { 62 return o, nil 63 } 64 65 // Attempt to load the Oyafile using the local path. 66 fullImportPath := filepath.Join(oyafile.RootDir, string(importPath)) 67 if isValidImportPath(fullImportPath) { 68 o, found, err := LoadFromDir(fullImportPath, oyafile.RootDir) 69 if err != nil { 70 return nil, err 71 } 72 if found { 73 return o, nil 74 } 75 } 76 return nil, errors.Errorf("missing pack %v", importPath) 77 } 78 79 func isValidImportPath(fullImportPath string) bool { 80 f, err := os.Stat(fullImportPath) 81 return err == nil && f.IsDir() 82 }