Skip to content

Commit

Permalink
Use os.UserCacheDir as first fallback if cacheDir is not set
Browse files Browse the repository at this point in the history
We will now try

1. cacheDir (or, commonly set in environment as `HUGO_CACHEDIR`)
2. if on Netlify we use `/opt/build/cache/hugo_cache/`
3. os.UserCacheDir
4. A temp dir

Storing the cache, especially the module cache, in a temporary idea has had lots of hard to debug issues, especially on MacOS,
which this commit tries to fix.

This should also make it easier to locate the Hugo cache:

>UserCacheDir returns the default root directory to use for user-specific cached data. Users should create their own
application-specific subdirectory within this one and use that.
>
>On Unix systems, it returns $XDG_CACHE_HOME as specified by
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if non-empty, else $HOME/.cache. On Darwin, it
returns $HOME/Library/Caches. On Windows, it returns %LocalAppData%. On Plan 9, it returns $home/lib/cache.
>
>If the location cannot be determined (for example, $HOME is not defined), then it will return an error.

Fixes gohugoio#11286
Fixes gohugoio#11291
  • Loading branch information
bep committed Jul 27, 2023
1 parent 575d7f8 commit 69a600b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
5 changes: 5 additions & 0 deletions config/allconfig/allconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ func fromLoadConfigResult(fs afero.Fs, logger loggers.Logger, res config.LoadCon
cfg := res.Cfg

all := &Config{}

err := decodeConfigFromParams(fs, bcfg, cfg, all, nil)
if err != nil {
return nil, err
Expand Down Expand Up @@ -871,6 +872,10 @@ func fromLoadConfigResult(fs afero.Fs, logger loggers.Logger, res config.LoadCon

bcfg.PublishDir = all.PublishDir
res.BaseConfig = bcfg
all.CommonDirs.CacheDir = bcfg.CacheDir
for _, l := range langConfigs {
l.CommonDirs.CacheDir = bcfg.CacheDir
}

cm := &Configs{
Base: all,
Expand Down
17 changes: 14 additions & 3 deletions helpers/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ func OpenFileForWriting(fs afero.Fs, filename string) (afero.File, error) {
// The dir will be created if it does not exist.
func GetCacheDir(fs afero.Fs, cacheDir string) (string, error) {
cacheDir = cacheDirDefault(cacheDir)

if cacheDir != "" {
exists, err := DirExists(cacheDir, fs)
if err != nil {
Expand All @@ -408,12 +409,22 @@ func GetCacheDir(fs afero.Fs, cacheDir string) (string, error) {
return cacheDir, nil
}

const hugoCacheBase = "hugo_cache"

userCacheDir, err := os.UserCacheDir()
if err == nil {
cacheDir := filepath.Join(userCacheDir, hugoCacheBase)
if err := fs.Mkdir(cacheDir, 0777); err == nil || os.IsExist(err) {
return cacheDir, nil
}
}

// Fall back to a cache in /tmp.
userName := os.Getenv("USER")
if userName != "" {
return GetTempDir("hugo_cache_"+userName, fs), nil
return GetTempDir(hugoCacheBase+"_"+userName, fs), nil
} else {
return GetTempDir("hugo_cache", fs), nil
return GetTempDir(hugoCacheBase, fs), nil
}
}

Expand All @@ -433,7 +444,7 @@ func cacheDirDefault(cacheDir string) string {
return "/opt/build/cache/hugo_cache/"
}

// This will fall back to an hugo_cache folder in the tmp dir, which should work fine for most CI
// This will fall back to an hugo_cache folder in either os.UserCacheDir or the tmp dir, which should work fine for most CI
// providers. See this for a working CircleCI setup:
// https://github.com/bep/hugo-sass-test/blob/6c3960a8f4b90e8938228688bc49bdcdd6b2d99e/.circleci/config.yml
// If not, they can set the HUGO_CACHEDIR environment variable or cacheDir config key.
Expand Down
19 changes: 17 additions & 2 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,23 @@ func testSetupFunc() func(env *testscript.Env) error {
return func(env *testscript.Env) error {
var keyVals []string
keyVals = append(keyVals, "HUGO_TESTRUN", "true")
hugoCachedDir := filepath.Join(env.WorkDir, "hugocache")
keyVals = append(keyVals, "HUGO_CACHEDIR", hugoCachedDir)
keyVals = append(keyVals, "HUGO_CACHEDIR", filepath.Join(env.WorkDir, "hugocache"))
xdghome := filepath.Join(env.WorkDir, "xdgcachehome")
keyVals = append(keyVals, "XDG_CACHE_HOME", xdghome)
home := filepath.Join(env.WorkDir, "home")
keyVals = append(keyVals, "HOME", home)

if runtime.GOOS == "darwin" {
if err := os.MkdirAll(filepath.Join(home, "Library", "Caches"), 0777); err != nil {
return err
}
}

if runtime.GOOS == "linux" {
if err := os.MkdirAll(xdghome, 0777); err != nil {
return err
}
}

keyVals = append(keyVals, "SOURCE", sourceDir)

Expand Down
18 changes: 18 additions & 0 deletions testscripts/commands/config__cachedir.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

[windows] skip

env HUGO_CACHEDIR=
hugo config

[darwin] stdout 'home/Library/Caches/hugo_cache'
[linux] stdout 'xdgcachehome/hugo_cache'

# Repeat it to make sure it handles an existing hugo_cache dir.
hugo config

[darwin] stdout 'home/Library/Caches/hugo_cache'
[linux] stdout 'xdgcachehome/hugo_cache'

-- hugo.toml --
baseURL="https://example.com/"
title="My New Hugo Site"

0 comments on commit 69a600b

Please sign in to comment.