github.com/fengjian1993/viper@v1.11.0/fs.go (about)

     1  //go:build go1.16 && finder
     2  // +build go1.16,finder
     3  
     4  package viper
     5  
     6  import (
     7  	"errors"
     8  	"io/fs"
     9  	"path"
    10  )
    11  
    12  type finder struct {
    13  	paths      []string
    14  	fileNames  []string
    15  	extensions []string
    16  
    17  	withoutExtension bool
    18  }
    19  
    20  func (f finder) Find(fsys fs.FS) (string, error) {
    21  	for _, searchPath := range f.paths {
    22  		for _, fileName := range f.fileNames {
    23  			for _, extension := range f.extensions {
    24  				filePath := path.Join(searchPath, fileName+"."+extension)
    25  
    26  				ok, err := fileExists(fsys, filePath)
    27  				if err != nil {
    28  					return "", err
    29  				}
    30  
    31  				if ok {
    32  					return filePath, nil
    33  				}
    34  			}
    35  
    36  			if f.withoutExtension {
    37  				filePath := path.Join(searchPath, fileName)
    38  
    39  				ok, err := fileExists(fsys, filePath)
    40  				if err != nil {
    41  					return "", err
    42  				}
    43  
    44  				if ok {
    45  					return filePath, nil
    46  				}
    47  			}
    48  		}
    49  	}
    50  
    51  	return "", nil
    52  }
    53  
    54  func fileExists(fsys fs.FS, filePath string) (bool, error) {
    55  	fileInfo, err := fs.Stat(fsys, filePath)
    56  	if err == nil {
    57  		return !fileInfo.IsDir(), nil
    58  	}
    59  
    60  	if errors.Is(err, fs.ErrNotExist) {
    61  		return false, nil
    62  	}
    63  
    64  	return false, err
    65  }