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  }