From 313b5ebd27de853327b5e12838cfb782b4a674fb Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Wed, 29 Jan 2020 14:08:03 -0500 Subject: [PATCH] feat: config auto-generation `cheat` now attempts to auto-generate a config file if one cannot be found on the filesystem. --- cmd/cheat/main.go | 28 ++++++++++++++++++++++++--- internal/config/init.go | 24 +++++++++++++++++++++++ internal/config/path.go | 35 +-------------------------------- internal/config/paths.go | 42 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 37 deletions(-) create mode 100644 internal/config/init.go create mode 100644 internal/config/paths.go diff --git a/cmd/cheat/main.go b/cmd/cheat/main.go index 063b916..e6ec4ad 100755 --- a/cmd/cheat/main.go +++ b/cmd/cheat/main.go @@ -31,13 +31,35 @@ func main() { os.Exit(0) } - // load the config file - confpath, err := config.Path(runtime.GOOS) + // load the os-specifc paths at which the config file may be located + confpaths, err := config.Paths(runtime.GOOS) if err != nil { - fmt.Fprintln(os.Stderr, "could not locate config file") + fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err) os.Exit(1) } + // search for the config file in the above paths + confpath, err := config.Path(confpaths) + if err != nil { + + // the config file does not exist, so we'll try to create one + if err = config.Init(confpaths[0], configs()); err != nil { + fmt.Fprintf( + os.Stderr, + "failed to create config file: %s: %v\n", + confpaths[0], + err, + ) + os.Exit(1) + } + + confpath = confpaths[0] + + fmt.Printf("Created config file: %s\n", confpath) + fmt.Println("Please edit this file now to configure cheat.") + os.Exit(0) + } + // initialize the configs conf, err := config.New(opts, confpath, true) if err != nil { diff --git a/internal/config/init.go b/internal/config/init.go new file mode 100644 index 0000000..91fa6d6 --- /dev/null +++ b/internal/config/init.go @@ -0,0 +1,24 @@ +package config + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +// Init initializes a config file +func Init(confpath string, configs string) error { + + // assert that the config directory exists + if err := os.MkdirAll(filepath.Dir(confpath), 0755); err != nil { + return fmt.Errorf("failed to create directory: %v", err) + } + + // write the config file + if err := ioutil.WriteFile(confpath, []byte(configs), 0644); err != nil { + return fmt.Errorf("failed to create file: %v", err) + } + + return nil +} diff --git a/internal/config/path.go b/internal/config/path.go index dd99974..b9ae4f4 100644 --- a/internal/config/path.go +++ b/internal/config/path.go @@ -3,43 +3,10 @@ package config import ( "fmt" "os" - "path" - - "github.com/mitchellh/go-homedir" ) // Path returns the config file path -func Path(sys string) (string, error) { - - var paths []string - - // if CHEAT_CONFIG_PATH is set, return it - if os.Getenv("CHEAT_CONFIG_PATH") != "" { - - // expand ~ - expanded, err := homedir.Expand(os.Getenv("CHEAT_CONFIG_PATH")) - if err != nil { - return "", fmt.Errorf("failed to expand ~: %v", err) - } - - return expanded, nil - } - - switch sys { - case "darwin", "linux", "freebsd": - paths = []string{ - path.Join(os.Getenv("XDG_CONFIG_HOME"), "/cheat/conf.yml"), - path.Join(os.Getenv("HOME"), ".config/cheat/conf.yml"), - path.Join(os.Getenv("HOME"), ".cheat/conf.yml"), - } - case "windows": - paths = []string{ - fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("APPDATA")), - fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("PROGRAMDATA")), - } - default: - return "", fmt.Errorf("unsupported os: %s", sys) - } +func Path(paths []string) (string, error) { // check if the config file exists on any paths for _, p := range paths { diff --git a/internal/config/paths.go b/internal/config/paths.go new file mode 100644 index 0000000..ab08916 --- /dev/null +++ b/internal/config/paths.go @@ -0,0 +1,42 @@ +package config + +import ( + "fmt" + "os" + "path" + + "github.com/mitchellh/go-homedir" +) + +// Paths returns config file paths that are appropriate for the operating +// system +func Paths(sys string) ([]string, error) { + + // if CHEAT_CONFIG_PATH is set, return it + if os.Getenv("CHEAT_CONFIG_PATH") != "" { + + // expand ~ + expanded, err := homedir.Expand(os.Getenv("CHEAT_CONFIG_PATH")) + if err != nil { + return []string{}, fmt.Errorf("failed to expand ~: %v", err) + } + + return []string{expanded}, nil + } + + switch sys { + case "darwin", "linux", "freebsd": + return []string{ + path.Join(os.Getenv("XDG_CONFIG_HOME"), "/cheat/conf.yml"), + path.Join(os.Getenv("HOME"), ".config/cheat/conf.yml"), + path.Join(os.Getenv("HOME"), ".cheat/conf.yml"), + }, nil + case "windows": + return []string{ + fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("APPDATA")), + fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("PROGRAMDATA")), + }, nil + default: + return []string{}, fmt.Errorf("unsupported os: %s", sys) + } +}