github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/utils/fsutils/fs.go (about) 1 package fsutils 2 3 import ( 4 "fmt" 5 "io" 6 "io/fs" 7 "os" 8 "path/filepath" 9 10 "go.uber.org/zap" 11 "golang.org/x/exp/slices" 12 "golang.org/x/xerrors" 13 14 "github.com/devseccon/trivy/pkg/log" 15 ) 16 17 const ( 18 xdgDataHome = "XDG_DATA_HOME" 19 ) 20 21 var cacheDir string 22 23 // defaultCacheDir returns/creates the cache-dir to be used for trivy operations 24 func defaultCacheDir() string { 25 tmpDir, err := os.UserCacheDir() 26 if err != nil { 27 tmpDir = os.TempDir() 28 } 29 return filepath.Join(tmpDir, "trivy") 30 } 31 32 // CacheDir returns the directory used for caching 33 func CacheDir() string { 34 if cacheDir == "" { 35 return defaultCacheDir() 36 } 37 return cacheDir 38 } 39 40 // SetCacheDir sets the trivy cacheDir 41 func SetCacheDir(dir string) { 42 cacheDir = dir 43 } 44 45 func HomeDir() string { 46 dataHome := os.Getenv(xdgDataHome) 47 if dataHome != "" { 48 return dataHome 49 } 50 51 homeDir, _ := os.UserHomeDir() 52 return homeDir 53 } 54 55 // CopyFile copies the file content from scr to dst 56 func CopyFile(src, dst string) (int64, error) { 57 sourceFileStat, err := os.Stat(src) 58 if err != nil { 59 return 0, xerrors.Errorf("file (%s) stat error: %w", src, err) 60 } 61 62 if !sourceFileStat.Mode().IsRegular() { 63 return 0, fmt.Errorf("%s is not a regular file", src) 64 } 65 66 source, err := os.Open(src) 67 if err != nil { 68 return 0, err 69 } 70 defer source.Close() 71 72 destination, err := os.Create(dst) 73 if err != nil { 74 return 0, err 75 } 76 defer destination.Close() 77 n, err := io.Copy(destination, source) 78 return n, err 79 } 80 81 func DirExists(path string) bool { 82 if f, err := os.Stat(path); os.IsNotExist(err) || !f.IsDir() { 83 return false 84 } 85 return true 86 } 87 88 type WalkDirRequiredFunc func(path string, d fs.DirEntry) bool 89 90 type WalkDirFunc func(path string, d fs.DirEntry, r io.Reader) error 91 92 func WalkDir(fsys fs.FS, root string, required WalkDirRequiredFunc, fn WalkDirFunc) error { 93 return fs.WalkDir(fsys, root, func(path string, d fs.DirEntry, err error) error { 94 if err != nil { 95 return err 96 } else if !d.Type().IsRegular() || !required(path, d) { 97 return nil 98 } 99 100 f, err := fsys.Open(path) 101 if err != nil { 102 return xerrors.Errorf("file open error: %w", err) 103 } 104 defer f.Close() 105 106 if err = fn(path, d, f); err != nil { 107 log.Logger.Debugw("Walk error", zap.String("file_path", path), zap.Error(err)) 108 } 109 return nil 110 }) 111 } 112 113 func RequiredExt(exts ...string) WalkDirRequiredFunc { 114 return func(filePath string, _ fs.DirEntry) bool { 115 return slices.Contains(exts, filepath.Ext(filePath)) 116 } 117 } 118 119 func RequiredFile(fileNames ...string) WalkDirRequiredFunc { 120 return func(filePath string, _ fs.DirEntry) bool { 121 return slices.Contains(fileNames, filepath.Base(filePath)) 122 } 123 }