src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

default.go (2325B)


      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 
     49 	if prog := os.Getenv("GOCACHEPROG"); prog != "" {
     50 		defaultCache = startCacheProg(prog)
     51 	} else {
     52 		defaultCache = c
     53 	}
     54 }
     55 
     56 var (
     57 	defaultDirOnce sync.Once
     58 	defaultDir     string
     59 	defaultDirErr  error
     60 )
     61 
     62 // DefaultDir returns the effective STATICCHECK_CACHE setting.
     63 func DefaultDir() string {
     64 	// Save the result of the first call to DefaultDir for later use in
     65 	// initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that
     66 	// subprocesses will inherit it, but that means initDefaultCache can't
     67 	// otherwise distinguish between an explicit "off" and a UserCacheDir error.
     68 
     69 	defaultDirOnce.Do(func() {
     70 		defaultDir = os.Getenv("STATICCHECK_CACHE")
     71 		if filepath.IsAbs(defaultDir) {
     72 			return
     73 		}
     74 		if defaultDir != "" {
     75 			defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not an absolute path")
     76 			return
     77 		}
     78 
     79 		// Compute default location.
     80 		dir, err := os.UserCacheDir()
     81 		if err != nil {
     82 			defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not defined and %v", err)
     83 			return
     84 		}
     85 		defaultDir = filepath.Join(dir, "staticcheck")
     86 	})
     87 
     88 	return defaultDir
     89 }