Walk parent directories to find config file (#141)

Code is mostly borrowed from [gqlgen](https://github.com/99designs/gqlgen).

The idea here is that I want to be able to store `genqlient.yaml` at the top-level, but my client code lives down in `graph/client/`. I put the `//go:generate` line in `graph/client/client.go`.
This commit is contained in:
John Maguire
2021-10-21 21:43:34 -04:00
committed by GitHub
parent 9ecc62e285
commit 10dc388016
14 changed files with 193 additions and 6 deletions
+45
View File
@@ -10,6 +10,8 @@ import (
"gopkg.in/yaml.v2"
)
var cfgFilenames = []string{".genqlient.yml", ".genqlient.yaml", "genqlient.yml", "genqlient.yaml"}
// Config represents genqlient's configuration, generally read from
// genqlient.yaml.
//
@@ -109,6 +111,17 @@ func ReadAndValidateConfig(filename string) (*Config, error) {
return &config, nil
}
// ReadAndValidateConfigFromDefaultLocations looks for a config file in the
// current directory, and all parent directories walking up the tree. The
// closest config file will be returned.
func ReadAndValidateConfigFromDefaultLocations() (*Config, error) {
cfgFile, err := findCfg()
if err != nil {
return nil, err
}
return ReadAndValidateConfig(cfgFile)
}
func initConfig(filename string) error {
// TODO(benkraft): Embed this config file into the binary, see
// https://github.com/Khan/genqlient/issues/9.
@@ -126,3 +139,35 @@ func initConfig(filename string) error {
}
return nil
}
// findCfg searches for the config file in this directory and all parents up the tree
// looking for the closest match
func findCfg() (string, error) {
dir, err := os.Getwd()
if err != nil {
return "", errorf(nil, "unable to get working dir to findCfg: %v", err)
}
cfg := findCfgInDir(dir)
for cfg == "" && dir != filepath.Dir(dir) {
dir = filepath.Dir(dir)
cfg = findCfgInDir(dir)
}
if cfg == "" {
return "", os.ErrNotExist
}
return cfg, nil
}
func findCfgInDir(dir string) string {
for _, cfgName := range cfgFilenames {
path := filepath.Join(dir, cfgName)
if _, err := os.Stat(path); err == nil {
return path
}
}
return ""
}