github.com/tooploox/oya@v0.0.21-0.20230524103240-1cda1861aad6/pkg/project/project.go (about) 1 package project 2 3 import ( 4 "path/filepath" 5 6 "github.com/tooploox/oya/pkg/oyafile" 7 "github.com/tooploox/oya/pkg/raw" 8 ) 9 10 // TODO: Duplicated in oyafile module. 11 type Project struct { 12 RootDir string 13 installDir string 14 dependencies Deps 15 16 oyafileCache map[string]*oyafile.Oyafile 17 rawOyafileCache map[string]*raw.Oyafile 18 } 19 20 func Detect(workDir, installDir string) (*Project, error) { 21 detectedRootDir, found, err := detectRoot(workDir) 22 if err != nil { 23 return nil, err 24 } 25 if !found { 26 return nil, ErrNoProject{Path: workDir} 27 } 28 return &Project{ 29 RootDir: detectedRootDir, 30 installDir: installDir, 31 dependencies: nil, // lazily-loaded in Deps() 32 oyafileCache: make(map[string]*oyafile.Oyafile), 33 rawOyafileCache: make(map[string]*raw.Oyafile), 34 }, nil 35 } 36 37 // detectRoot attempts to detect the root project directory marked by 38 // root Oyafile, i.e. one containing Project: directive. 39 // It walks the directory tree, starting from startDir, going upwards, 40 // looking for root. 41 func detectRoot(startDir string) (string, bool, error) { 42 path := startDir 43 maxParts := 256 44 for i := 0; i < maxParts; i++ { 45 raw, found, err := raw.LoadFromDir(path, path) // "Guess" path is the root dir. 46 if err == nil && found { 47 isRoot, err := raw.IsRoot() 48 if err != nil { 49 return "", false, err 50 } 51 if isRoot { 52 return path, true, nil 53 } 54 } 55 56 if path == "/" { 57 break 58 } 59 path = filepath.Dir(path) 60 } 61 62 return "", false, nil 63 }