From 0e141e03c8cd266b8d59d8e8b2eedca0bc9204f9 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 20 Jun 2018 16:46:02 -0700 Subject: [PATCH] Closes #217. Use XDG-compatible config directory This change is largely experimental and it's entirely possible it could wipe out your existing configuration. Be warned. Old config path was: ~/.wtf/ New config path is: ~/.config/wtf/ If an existing config directory already exists, this change attempts to copy it to the new location. Note that if your config file contains paths to files in the old config directory, they won't work. You'll need to change them by hand. --- cfg/config_files.go | 46 +++++++++++++++++++++++++-- cfg/copy.go | 75 +++++++++++++++++++++++++++++++++++++++++++++ flags/flags.go | 2 +- logger/log.go | 2 +- wtf.go | 1 + 5 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 cfg/copy.go diff --git a/cfg/config_files.go b/cfg/config_files.go index 46a99780..7f6dfc0a 100644 --- a/cfg/config_files.go +++ b/cfg/config_files.go @@ -6,11 +6,53 @@ import ( "os" "github.com/olebedev/config" + "github.com/senorprogrammer/wtf/logger" "github.com/senorprogrammer/wtf/wtf" ) +const CONFIG_DIR_V1 = "~/.wtf/" +const CONFIG_DIR_V2 = "~/.config/wtf/" + +/* -------------------- Config Migration -------------------- */ + +// MigrateOldConfig copies any existing configuration from the old location +// to the new, XDG-compatible location +func MigrateOldConfig() { + srcDir, _ := wtf.ExpandHomeDir(CONFIG_DIR_V1) + destDir, _ := wtf.ExpandHomeDir(CONFIG_DIR_V2) + + // If the old config directory doesn't exist, do not move + if _, err := os.Stat(srcDir); os.IsNotExist(err) { + return + } + + // If the new config directory already exists, do not move + if _, err := os.Stat(destDir); err == nil { + return + } + + // Time to move + err := Copy(srcDir, destDir) + if err != nil { + panic(err) + } else { + logger.Log(fmt.Sprintf("Copied old config from %s to %s", srcDir, destDir)) + } + + // Delete the old directory if the new one exists + if _, err := os.Stat(destDir); err == nil { + err := os.RemoveAll(srcDir) + if err != nil { + logger.Log(err.Error()) + } + } +} + +/* -------------------- Config Migration -------------------- */ + +// ConfigDir returns the absolute path to the configuration directory func ConfigDir() (string, error) { - configDir, err := wtf.ExpandHomeDir("~/.wtf/") + configDir, err := wtf.ExpandHomeDir(CONFIG_DIR_V2) if err != nil { return "", err } @@ -18,7 +60,7 @@ func ConfigDir() (string, error) { return configDir, nil } -// CreateConfigDir creates the .wtf directory in the user's home dir +// CreateConfigDir creates the wtf/ directory in the user's home dir func CreateConfigDir() { configDir, _ := ConfigDir() diff --git a/cfg/copy.go b/cfg/copy.go new file mode 100644 index 00000000..6cea318d --- /dev/null +++ b/cfg/copy.go @@ -0,0 +1,75 @@ +// Copied verbatim from: +// +// https://github.com/otiai10/copy/blob/master/copy.go + +package cfg + +import ( + "io" + "io/ioutil" + "os" + "path/filepath" +) + +// Copy copies src to dest, doesn't matter if src is a directory or a file +func Copy(src, dest string) error { + info, err := os.Stat(src) + if err != nil { + return err + } + return copy(src, dest, info) +} + +// "info" must be given here, NOT nil. +func copy(src, dest string, info os.FileInfo) error { + if info.IsDir() { + return dcopy(src, dest, info) + } + return fcopy(src, dest, info) +} + +func fcopy(src, dest string, info os.FileInfo) error { + + f, err := os.Create(dest) + if err != nil { + return err + } + defer f.Close() + + if err = os.Chmod(f.Name(), info.Mode()); err != nil { + return err + } + + s, err := os.Open(src) + if err != nil { + return err + } + defer s.Close() + + _, err = io.Copy(f, s) + return err +} + +func dcopy(src, dest string, info os.FileInfo) error { + + if err := os.MkdirAll(dest, info.Mode()); err != nil { + return err + } + + infos, err := ioutil.ReadDir(src) + if err != nil { + return err + } + + for _, info := range infos { + if err := copy( + filepath.Join(src, info.Name()), + filepath.Join(dest, info.Name()), + info, + ); err != nil { + return err + } + } + + return nil +} diff --git a/flags/flags.go b/flags/flags.go index 48904c36..62c86aed 100644 --- a/flags/flags.go +++ b/flags/flags.go @@ -68,6 +68,6 @@ func (flags *Flags) Parse() { os.Exit(1) } - flags.Config = filepath.Join(homeDir, ".wtf", "config.yml") + flags.Config = filepath.Join(homeDir, ".config", "wtf", "config.yml") } } diff --git a/logger/log.go b/logger/log.go index 05cdbbec..fba557e8 100644 --- a/logger/log.go +++ b/logger/log.go @@ -89,7 +89,7 @@ func logFilePath() string { return "" } - return filepath.Join(dir, ".wtf", "log.txt") + return filepath.Join(dir, ".config", "wtf", "log.txt") } func (widget *Widget) tailFile() []string { diff --git a/wtf.go b/wtf.go index a9942a4e..4757265f 100644 --- a/wtf.go +++ b/wtf.go @@ -243,6 +243,7 @@ func main() { flags.Parse() flags.Display(version) + cfg.MigrateOldConfig() cfg.CreateConfigDir() cfg.CreateConfigFile() loadConfigFile(flags.ConfigFilePath())