github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/lintcmd/cache/default.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cache 6 7 import ( 8 "fmt" 9 "log" 10 "os" 11 "path/filepath" 12 "sync" 13 ) 14 15 // Default returns the default cache to use. 16 func Default() (*Cache, error) { 17 defaultOnce.Do(initDefaultCache) 18 return defaultCache, defaultDirErr 19 } 20 21 var ( 22 defaultOnce sync.Once 23 defaultCache *Cache 24 ) 25 26 // cacheREADME is a message stored in a README in the cache directory. 27 // Because the cache lives outside the normal Go trees, we leave the 28 // README as a courtesy to explain where it came from. 29 const cacheREADME = `This directory holds cached build artifacts from staticcheck. 30 ` 31 32 // initDefaultCache does the work of finding the default cache 33 // the first time Default is called. 34 func initDefaultCache() { 35 dir := DefaultDir() 36 if err := os.MkdirAll(dir, 0777); err != nil { 37 log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) 38 } 39 if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { 40 // Best effort. 41 os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) 42 } 43 44 c, err := Open(dir) 45 if err != nil { 46 log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) 47 } 48 defaultCache = c 49 } 50 51 var ( 52 defaultDirOnce sync.Once 53 defaultDir string 54 defaultDirErr error 55 ) 56 57 // DefaultDir returns the effective STATICCHECK_CACHE setting. 58 func DefaultDir() string { 59 // Save the result of the first call to DefaultDir for later use in 60 // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that 61 // subprocesses will inherit it, but that means initDefaultCache can't 62 // otherwise distinguish between an explicit "off" and a UserCacheDir error. 63 64 defaultDirOnce.Do(func() { 65 defaultDir = os.Getenv("STATICCHECK_CACHE") 66 if filepath.IsAbs(defaultDir) { 67 return 68 } 69 if defaultDir != "" { 70 defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not an absolute path") 71 return 72 } 73 74 // Compute default location. 75 dir, err := os.UserCacheDir() 76 if err != nil { 77 defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not defined and %v", err) 78 return 79 } 80 defaultDir = filepath.Join(dir, "staticcheck") 81 }) 82 83 return defaultDir 84 }