feat: config auto-generation

`cheat` now attempts to auto-generate a config file if one cannot be
found on the filesystem.
This commit is contained in:
Chris Lane 2020-01-29 14:08:03 -05:00
parent ca91b25b02
commit 313b5ebd27
4 changed files with 92 additions and 37 deletions

View File

@ -31,13 +31,35 @@ func main() {
os.Exit(0) os.Exit(0)
} }
// load the config file // load the os-specifc paths at which the config file may be located
confpath, err := config.Path(runtime.GOOS) confpaths, err := config.Paths(runtime.GOOS)
if err != nil { 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) 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 // initialize the configs
conf, err := config.New(opts, confpath, true) conf, err := config.New(opts, confpath, true)
if err != nil { if err != nil {

24
internal/config/init.go Normal file
View File

@ -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
}

View File

@ -3,43 +3,10 @@ package config
import ( import (
"fmt" "fmt"
"os" "os"
"path"
"github.com/mitchellh/go-homedir"
) )
// Path returns the config file path // Path returns the config file path
func Path(sys string) (string, error) { func Path(paths []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)
}
// check if the config file exists on any paths // check if the config file exists on any paths
for _, p := range paths { for _, p := range paths {

42
internal/config/paths.go Normal file
View File

@ -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)
}
}