github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/internal/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 "io/ioutil" 10 "log" 11 "os" 12 "path/filepath" 13 "sync" 14 ) 15 16 // Default returns the default cache to use. 17 func Default() (*Cache, error) { 18 defaultOnce.Do(initDefaultCache) 19 return defaultCache, defaultDirErr 20 } 21 22 var ( 23 defaultOnce sync.Once 24 defaultCache *Cache 25 ) 26 27 // cacheREADME is a message stored in a README in the cache directory. 28 // Because the cache lives outside the normal Go trees, we leave the 29 // README as a courtesy to explain where it came from. 30 const cacheREADME = `This directory holds cached build artifacts from golangci-lint. 31 ` 32 33 // initDefaultCache does the work of finding the default cache 34 // the first time Default is called. 35 func initDefaultCache() { 36 dir := DefaultDir() 37 if err := os.MkdirAll(dir, 0744); err != nil { 38 log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) 39 } 40 if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { 41 // Best effort. 42 if wErr := ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666); wErr != nil { 43 log.Fatalf("Failed to write README file to cache dir %s: %s", dir, err) 44 } 45 } 46 47 c, err := Open(dir) 48 if err != nil { 49 log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) 50 } 51 defaultCache = c 52 } 53 54 var ( 55 defaultDirOnce sync.Once 56 defaultDir string 57 defaultDirErr error 58 ) 59 60 // DefaultDir returns the effective GOLANGCI_LINT_CACHE setting. 61 func DefaultDir() string { 62 // Save the result of the first call to DefaultDir for later use in 63 // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that 64 // subprocesses will inherit it, but that means initDefaultCache can't 65 // otherwise distinguish between an explicit "off" and a UserCacheDir error. 66 67 defaultDirOnce.Do(func() { 68 defaultDir = os.Getenv("GOLANGCI_LINT_CACHE") 69 if filepath.IsAbs(defaultDir) { 70 return 71 } 72 if defaultDir != "" { 73 defaultDirErr = fmt.Errorf("GOLANGCI_LINT_CACHE is not an absolute path") 74 return 75 } 76 77 // Compute default location. 78 dir, err := os.UserCacheDir() 79 if err != nil { 80 defaultDirErr = fmt.Errorf("GOLANGCI_LINT_CACHE is not defined and %v", err) 81 return 82 } 83 defaultDir = filepath.Join(dir, "golangci-lint") 84 }) 85 86 return defaultDir 87 }