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 }