github.com/henvic/wedeploycli@v1.7.6-0.20200319005353-3630f582f284/findresource/findresource.go (about)

     1  package findresource
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/hashicorp/errwrap"
     9  )
    10  
    11  var sysRoot string
    12  
    13  func init() {
    14  	setupOSRoot()
    15  }
    16  
    17  // SetSysRoot sets the delimiter to stop searching for a resource
    18  func SetSysRoot(sr string) error {
    19  	var err error
    20  	sysRoot, err = filepath.Abs(sr)
    21  	return err
    22  }
    23  
    24  // GetSysRoot returns the delimiter to stop searching for a resource
    25  func GetSysRoot() string {
    26  	return sysRoot
    27  }
    28  
    29  // GetRootDirectory for a given file source
    30  func GetRootDirectory(dir, delimiter, file string) (string, error) {
    31  	switch stat, err := os.Stat(delimiter); {
    32  	case os.IsNotExist(err) || !stat.IsDir():
    33  		return "", os.ErrNotExist
    34  	case err != nil:
    35  		return "", errwrap.Wrapf("can't read delimiter "+delimiter+"directory: {{err}}", err)
    36  	}
    37  
    38  	return walkToRootDirectory(dir, delimiter, file)
    39  }
    40  
    41  var errReachedDirectoryTreeRoot = errors.New("reached directory tree root")
    42  
    43  func walkToRootDirectory(dir, delimiter, file string) (string, error) {
    44  	var err error
    45  
    46  	if dir, err = filepath.Abs(dir); err != nil {
    47  		return "", err
    48  	}
    49  
    50  	// sysRoot = / = upper-bound / The Power of Ten rule 2
    51  	for {
    52  		stat, err := os.Stat(dir)
    53  
    54  		switch {
    55  		case os.IsNotExist(err) || !stat.IsDir():
    56  			return "", os.ErrNotExist
    57  		case err != nil:
    58  			return "", errwrap.Wrapf("can't read directory "+dir+": {{err}}", err)
    59  		}
    60  
    61  		switch _, err = os.Stat(filepath.Join(dir, file)); {
    62  		case os.IsNotExist(err):
    63  			if dir == delimiter {
    64  				return "", os.ErrNotExist
    65  			}
    66  
    67  			newDir := filepath.Join(dir, "..")
    68  
    69  			if dir == newDir {
    70  				return "", errReachedDirectoryTreeRoot
    71  			}
    72  
    73  			dir = newDir
    74  
    75  			if !isRootDelimiter(dir) && dir != delimiter {
    76  				continue
    77  			}
    78  
    79  			return "", os.ErrNotExist
    80  		case err != nil:
    81  			return "", errwrap.Wrapf("can't walk filesystem to find "+file+": {{err}}", err)
    82  		}
    83  
    84  		return dir, nil
    85  	}
    86  }