diff --git a/changelog/unreleased/pull-2607 b/changelog/unreleased/pull-2607 new file mode 100644 index 000000000..1f6a78fc2 --- /dev/null +++ b/changelog/unreleased/pull-2607 @@ -0,0 +1,7 @@ +Bugfix: Honor RESTIC_CACHE_DIR environment variable on Mac and Windows + +On Mac and Windows, the RESTIC_CACHE_DIR environment variable was ignored. +This variable can now be used on all platforms to set the directory where +restic stores caches. + +https://github.com/restic/restic/pull/2607 diff --git a/internal/cache/dir.go b/internal/cache/dir.go index e9c7278b6..1e68fa26a 100644 --- a/internal/cache/dir.go +++ b/internal/cache/dir.go @@ -1,75 +1,29 @@ package cache import ( + "fmt" "os" "path/filepath" - "runtime" "github.com/pkg/errors" "github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/fs" ) -// xdgCacheDir returns the cache directory according to XDG basedir spec, see -// http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html -// unless RESTIC_CACHE_DIR is defined -func xdgCacheDir() (string, error) { - cachedir := os.Getenv("RESTIC_CACHE_DIR") - xdgcache := os.Getenv("XDG_CACHE_HOME") - home := os.Getenv("HOME") - +// DefaultDir returns $RESTIC_CACHE_DIR, or the default cache directory +// for the current OS if that variable is not set. +func DefaultDir() (cachedir string, err error) { + cachedir = os.Getenv("RESTIC_CACHE_DIR") if cachedir != "" { return cachedir, nil - } else if xdgcache != "" { - return filepath.Join(xdgcache, "restic"), nil - } else if home != "" { - return filepath.Join(home, ".cache", "restic"), nil - } - - return "", errors.New("unable to locate cache directory (RESTIC_CACHE_DIR, XDG_CACHE_HOME and HOME unset)") -} - -// windowsCacheDir returns the cache directory for Windows. -// -// Uses LOCALAPPDATA, where application data not synchronized between machines -// is stored. (Browser caches stored here). -func windowsCacheDir() (string, error) { - appdata := os.Getenv("LOCALAPPDATA") - if appdata == "" { - return "", errors.New("unable to locate cache directory (LOCALAPPDATA unset)") - } - return filepath.Join(appdata, "restic"), nil -} - -// darwinCacheDir returns the cache directory for darwin. -// -// Uses ~/Library/Caches/, which is recommended by Apple, see -// https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html -func darwinCacheDir() (string, error) { - home := os.Getenv("HOME") - if home == "" { - return "", errors.New("unable to locate cache directory (HOME unset)") - } - return filepath.Join(home, "Library", "Caches", "restic"), nil -} - -// DefaultDir returns the default cache directory for the current OS. -func DefaultDir() (cachedir string, err error) { - switch runtime.GOOS { - case "darwin": - cachedir, err = darwinCacheDir() - case "windows": - cachedir, err = windowsCacheDir() - default: - // Default to XDG for Linux and any other OSes. - cachedir, err = xdgCacheDir() } + cachedir, err = os.UserCacheDir() if err != nil { - return "", err + return "", fmt.Errorf("unable to locate cache directory: %v", err) } - return cachedir, nil + return filepath.Join(cachedir, "restic"), nil } // mkdirCacheDir ensures that the cache directory exists. It it didn't, created diff --git a/internal/cache/dir_test.go b/internal/cache/dir_test.go new file mode 100644 index 000000000..73a08eb4d --- /dev/null +++ b/internal/cache/dir_test.go @@ -0,0 +1,26 @@ +package cache + +import ( + "os" + "testing" + + rtest "github.com/restic/restic/internal/test" +) + +// DefaultDir should honor RESTIC_CACHE_DIR on all platforms. +func TestCacheDirEnv(t *testing.T) { + cachedir := os.Getenv("RESTIC_CACHE_DIR") + + if cachedir == "" { + cachedir = "/doesnt/exist" + err := os.Setenv("RESTIC_CACHE_DIR", cachedir) + if err != nil { + t.Fatal(err) + } + defer os.Unsetenv("RESTIC_CACHE_DIR") + } + + dir, err := DefaultDir() + rtest.Equals(t, cachedir, dir) + rtest.OK(t, err) +}