From ce9140fa1e1e36070a2dedf6dfa0ac0d8def2f3c Mon Sep 17 00:00:00 2001 From: Christoph Loy Date: Thu, 11 Jan 2024 19:01:59 +0100 Subject: [PATCH] Fix handling of `XDG_CONFIG_HOME` (#347) --- cmd/root.go | 38 ++++++++++++++++++++------------------ cmd/root_test.go | 36 ++++++++++++++++++++++++++++++++++++ docs/pages/config.md | 3 ++- 3 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 cmd/root_test.go diff --git a/cmd/root.go b/cmd/root.go index fd367a1..3da9e25 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -59,24 +59,7 @@ func initConfig() { os.Exit(1) } } else { - configPaths := []string{"."} - - // Home - if home, err := homedir.Dir(); err == nil { - configPaths = append(configPaths, home) - } - - // XDG_CONFIG_HOME - { - prefix, found := os.LookupEnv("XDG_CONFIG_HOME") - if !found { - if home, err := homedir.Dir(); err != nil { - prefix = filepath.Join(home, ".config") - } - } - xdgConfig := filepath.Join(prefix, "autorestic") - configPaths = append(configPaths, xdgConfig) - } + configPaths := getConfigPaths() for _, cfgPath := range configPaths { viper.AddConfigPath(cfgPath) } @@ -88,3 +71,22 @@ func initConfig() { viper.AutomaticEnv() } } + +func getConfigPaths() []string { + result := []string{"."} + if home, err := homedir.Dir(); err == nil { + result = append(result, home) + } + + { + xdgConfigHome, found := os.LookupEnv("XDG_CONFIG_HOME") + if !found { + if home, err := homedir.Dir(); err == nil { + xdgConfigHome = filepath.Join(home, ".config") + } + } + xdgConfig := filepath.Join(xdgConfigHome, "autorestic") + result = append(result, xdgConfig) + } + return result +} diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 0000000..feabb1b --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,36 @@ +package cmd + +import ( + "github.com/mitchellh/go-homedir" + "os" + "path/filepath" + "slices" + "testing" +) + +const xdgConfigHome = "XDG_CONFIG_HOME" + +func assertContains(t *testing.T, array []string, element string) { + if !slices.Contains(array, element) { + t.Errorf("Expected %s to be contained in %s", element, array) + } +} + +func TestConfigResolving(t *testing.T) { + t.Run("~/.config/autorestic is used if XDG_CONFIG_HOME is not set", func(t *testing.T) { + // Override env using testing so that env gets restored after test + t.Setenv(xdgConfigHome, "") + _ = os.Unsetenv("XDG_CONFIG_HOME") + configPaths := getConfigPaths() + homeDir, _ := homedir.Dir() + expectedConfigPath := filepath.Join(homeDir, ".config/autorestic") + assertContains(t, configPaths, expectedConfigPath) + }) + + t.Run("XDG_CONFIG_HOME is respected if set", func(t *testing.T) { + t.Setenv(xdgConfigHome, "/foo/bar") + + configPaths := getConfigPaths() + assertContains(t, configPaths, filepath.Join("/", "foo", "bar", "autorestic")) + }) +} diff --git a/docs/pages/config.md b/docs/pages/config.md index 749fd6c..ce5aec5 100644 --- a/docs/pages/config.md +++ b/docs/pages/config.md @@ -2,10 +2,11 @@ ## Path -By default autorestic searches for a `.autorestic.yml` file in the current directory and your home folder. +By default autorestic searches for a `.autorestic.yml` file in the current directory, your home folder and your XDG config folder (`~/.config/` by default): - `./.autorestic.yml` - `~/.autorestic.yml` +- `~/.config/autorestic/.autorestic.yml` You can also specify a custom file with the `-c path/to/some/config.yml`