github.com/fawick/restic@v0.1.1-0.20171126184616-c02923fbfc79/internal/cache/dir.go (about) 1 package cache 2 3 import ( 4 "os" 5 "path/filepath" 6 "runtime" 7 8 "github.com/pkg/errors" 9 "github.com/restic/restic/internal/debug" 10 "github.com/restic/restic/internal/fs" 11 ) 12 13 // xdgCacheDir returns the cache directory according to XDG basedir spec, see 14 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 15 func xdgCacheDir() (string, error) { 16 xdgcache := os.Getenv("XDG_CACHE_HOME") 17 home := os.Getenv("HOME") 18 19 if xdgcache != "" { 20 return filepath.Join(xdgcache, "restic"), nil 21 } else if home != "" { 22 return filepath.Join(home, ".cache", "restic"), nil 23 } 24 25 return "", errors.New("unable to locate cache directory (XDG_CACHE_HOME and HOME unset)") 26 } 27 28 // windowsCacheDir returns the cache directory for Windows. 29 // 30 // Uses LOCALAPPDATA, where application data not synchronized between machines 31 // is stored. (Browser caches stored here). 32 func windowsCacheDir() (string, error) { 33 appdata := os.Getenv("LOCALAPPDATA") 34 if appdata == "" { 35 return "", errors.New("unable to locate cache directory (APPDATA unset)") 36 } 37 return filepath.Join(appdata, "restic"), nil 38 } 39 40 // darwinCacheDir returns the cache directory for darwin. 41 // 42 // Uses ~/Library/Caches/, which is recommended by Apple, see 43 // https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html 44 func darwinCacheDir() (string, error) { 45 home := os.Getenv("HOME") 46 if home == "" { 47 return "", errors.New("unable to locate cache directory (HOME unset)") 48 } 49 return filepath.Join(home, "Library", "Caches", "restic"), nil 50 } 51 52 // defaultCacheDir determines and creates the default cache directory for this 53 // system. 54 func defaultCacheDir() (string, error) { 55 var cachedir string 56 var err error 57 switch runtime.GOOS { 58 case "darwin": 59 cachedir, err = darwinCacheDir() 60 case "windows": 61 cachedir, err = windowsCacheDir() 62 default: 63 // Default to XDG for Linux and any other OSes. 64 cachedir, err = xdgCacheDir() 65 } 66 if err != nil { 67 return "", err 68 } 69 70 fi, err := fs.Stat(cachedir) 71 if os.IsNotExist(errors.Cause(err)) { 72 err = fs.MkdirAll(cachedir, 0700) 73 if err != nil { 74 return "", errors.Wrap(err, "MkdirAll") 75 } 76 77 fi, err = fs.Stat(cachedir) 78 debug.Log("create cache dir %v", cachedir) 79 } 80 81 if err != nil { 82 return "", errors.Wrap(err, "Stat") 83 } 84 85 if !fi.IsDir() { 86 return "", errors.Errorf("cache dir %v is not a directory", cachedir) 87 } 88 89 return cachedir, nil 90 }