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  }