diff --git a/go.mod b/go.mod index c42c678..c13e346 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 github.com/jfreymuth/pulse v0.0.0-20200608153616-84b2d752b9d4 + github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f // indirect github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4 github.com/micmonay/keybd_event v1.1.1 // indirect github.com/mitchellh/go-ps v1.0.0 diff --git a/go.sum b/go.sum index ef8bbd5..468443c 100644 --- a/go.sum +++ b/go.sum @@ -119,6 +119,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU= +github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f/go.mod h1:4rEELDSfUAlBSyUjPG0JnaNGjf13JySHFeRdD/3dLP0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= diff --git a/pkg/deej/config.go b/pkg/deej/config.go index 4f93b5a..dd05ad6 100644 --- a/pkg/deej/config.go +++ b/pkg/deej/config.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/kirsle/configdir" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" "go.uber.org/zap" @@ -48,14 +49,9 @@ type CanonicalConfig struct { } const ( - userConfigFilepath = "config.yaml" - internalConfigFilepath = "preferences.yaml" - userConfigName = "config" internalConfigName = "preferences" - userConfigPath = "." - configType = "yaml" configKeySliderMapping = "slider_mapping" @@ -74,8 +70,37 @@ const ( defaultBaudRate = 9600 ) -// has to be defined as a non-constant because we're using path.Join -var internalConfigPath = path.Join(".", logDirectory) +var userConfigFilename = userConfigName+"."+configType +var userConfigPath = func() string { + configPath := configdir.LocalConfig("reeemiks") + err := util.EnsureDirExists(configPath) + if err != nil { + panic(err) + } + // Check if we need to make XDG path + // do existing config file check here + // if XDG config doesn't exist and rel path does, move rel path to XDG + // if XDG config does exist and rel config does exist, warn user + // if XDG config doesn't exist and rel config doesn't exist, create XDG path + + configFile := path.Join(configPath, userConfigFilename) + xdg_exists := util.FileExists(configFile) + rel_exists := util.FileExists(userConfigFilename) + + if !xdg_exists && rel_exists { + util.MoveFile(userConfigFilename,configFile) + } else if xdg_exists && rel_exists { + fmt.Printf("I'm ignoring your config relative to my binary, your config is located at: %s", configFile) + } else if !xdg_exists && !rel_exists { + fmt.Errorf("Config file doesn't exist: %s", configFile) + } + + + return configPath +}() +var userConfigFilepath = path.Join(userConfigPath, userConfigFilename) +var internalConfigPath = path.Join(userConfigPath, logDirectory) +var internalConfigFilepath = path.Join(userConfigPath, "preferences.yaml") var defaultSliderMapping = func() *sliderMap { emptyMap := newSliderMap() @@ -97,7 +122,7 @@ func NewConfig(logger *zap.SugaredLogger, notifier Notifier) (*CanonicalConfig, // distinguish between the user-provided config (config.yaml) and the internal config (logs/preferences.yaml) userConfig := viper.New() - userConfig.SetConfigName(userConfigName) + userConfig.SetConfigName(userConfigFilename) userConfig.SetConfigType(configType) userConfig.AddConfigPath(userConfigPath) @@ -129,9 +154,9 @@ func (cc *CanonicalConfig) Load() error { if !util.FileExists(userConfigFilepath) { cc.logger.Warnw("Config file not found", "path", userConfigFilepath) cc.notifier.Notify("Can't find configuration!", - fmt.Sprintf("%s must be in the same directory as deej. Please re-launch", userConfigFilepath)) + fmt.Sprintf("Config must be located at %s . Please re-launch", userConfigFilepath)) - return fmt.Errorf("config file doesn't exist: %s", userConfigFilepath) + return fmt.Errorf("Config file doesn't exist: %s", userConfigFilepath) } // load the user config diff --git a/pkg/deej/util/util.go b/pkg/deej/util/util.go index 44abf0c..1b421de 100644 --- a/pkg/deej/util/util.go +++ b/pkg/deej/util/util.go @@ -3,6 +3,7 @@ package util import ( "fmt" "math" + "io" "os" "os/exec" "os/signal" @@ -31,6 +32,46 @@ func FileExists(filename string) bool { return !info.IsDir() } +func MoveFile(src, dst string) error { + in, err := os.Open(src) + if err != nil { + return fmt.Errorf("Couldn't open source file: %s", err) + } + + out, err := os.Create(dst) + if err != nil { + in.Close() + return fmt.Errorf("Couldn't open dest file: %s", err) + } + defer out.Close() + + _, err = io.Copy(out, in) + in.Close() + if err != nil { + return fmt.Errorf("Writing to output file failed: %s", err) + } + + err = out.Sync() + if err != nil { + return fmt.Errorf("Sync error: %s", err) + } + + si, err := os.Stat(src) + if err != nil { + return fmt.Errorf("Stat error: %s", err) + } + err = os.Chmod(dst, si.Mode()) + if err != nil { + return fmt.Errorf("Chmod error: %s", err) + } + + err = os.Remove(src) + if err != nil { + return fmt.Errorf("Failed removing original file: %s", err) + } + return nil +} + // Linux returns true if we're running on Linux func Linux() bool { return runtime.GOOS == "linux"