github.com/kcmerrill/common.go@v0.0.0-20180608223308-4114128a6803/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"github.com/mitchellh/go-homedir"
    12  )
    13  
    14  // Home directory config file
    15  func Home(query, extension string) ([]byte, error) {
    16  	h, _ := homedir.Dir()
    17  	h += "/" + query + "/" + query + extension
    18  
    19  	if _, err := os.Stat(h); err == nil {
    20  		if contents, err := ioutil.ReadFile(h); err == nil {
    21  			return contents, nil
    22  		}
    23  	}
    24  	return nil, nil
    25  }
    26  
    27  // FindAndCombine will go up directories looking for a file + extension and combine all the files into one []byte{}
    28  func FindAndCombine(currentDir, query, extension string) (string, []byte, error) {
    29  	// Grab the current directory
    30  	combinedContents := []byte{}
    31  	// Just keep going ...
    32  	for {
    33  		// Did we find a bunch of config files?
    34  
    35  		dir := ""
    36  		file := query
    37  		if strings.Contains(query, string(os.PathSeparator)) {
    38  			path := strings.SplitN(query, string(os.PathSeparator), 2)
    39  			dir = string(os.PathSeparator) + path[0] + string(os.PathSeparator)
    40  			file = path[1]
    41  		}
    42  
    43  		patterns := map[string]string{
    44  			currentDir + "/" + file + "." + extension:               currentDir + "/",
    45  			currentDir + "/*" + file + "." + extension:              currentDir + "/",
    46  			currentDir + "/" + file + "/*" + file + "." + extension: currentDir + "/"}
    47  
    48  		if dir != "" {
    49  			patterns = map[string]string{
    50  				currentDir + dir + file + "." + extension:               currentDir + dir,
    51  				currentDir + dir + "*" + file + "." + extension:         currentDir + dir,
    52  				currentDir + dir + file + "/*" + file + "." + extension: currentDir + dir}
    53  		}
    54  
    55  		for pattern, dirToUse := range patterns {
    56  			if configFiles, filesErr := filepath.Glob(pattern); filesErr == nil && len(configFiles) > 0 {
    57  				for _, configFile := range configFiles {
    58  					if contents, readErr := ioutil.ReadFile(configFile); readErr == nil {
    59  						// Sweet. We found an config file. Lets save it off and return
    60  						combinedContents = append(combinedContents, []byte("\n\n")...)
    61  						combinedContents = append(combinedContents, contents...)
    62  					}
    63  				}
    64  				currentDir = dirToUse
    65  
    66  				// Are we inside the folder we are looking? If so, escape out of it ...
    67  				base := filepath.Base(currentDir)
    68  				if base == file && len(configFiles) >= 2 {
    69  					currentDir = filepath.Dir(filepath.Dir(currentDir))
    70  				}
    71  
    72  				return path.Clean(currentDir), combinedContents, nil
    73  			}
    74  		}
    75  
    76  		currentDir = filepath.Dir(currentDir)
    77  
    78  		if currentDir == "/" {
    79  			// We've gone too far ...
    80  			break
    81  		}
    82  	}
    83  	// We didn't find anything. /cry
    84  	return "./", []byte{}, fmt.Errorf("Unable to look up directory")
    85  }
    86  
    87  // Find will find a file going up the directory tree one at a time stopping when it finds the file
    88  func Find(filename string) (string, []byte, error) {
    89  	dir, err := os.Getwd()
    90  
    91  	if err != nil {
    92  		return "./", nil, fmt.Errorf("Unable to get working directory")
    93  	}
    94  
    95  	for {
    96  		if _, err := os.Stat(dir + "/" + filename); err == nil {
    97  			if contents, err := ioutil.ReadFile(dir + "/" + filename); err == nil {
    98  				return dir + "/", contents, nil
    99  			}
   100  			return dir + "/", nil, nil
   101  		}
   102  
   103  		if dir == "/" {
   104  			break
   105  		}
   106  		dir = filepath.Dir(dir)
   107  	}
   108  	return "./", nil, fmt.Errorf("Unable to find config")
   109  }