github.com/please-build/go-rules/tools/please_go@v0.0.0-20240319165128-ea27d6f5caba/test/find_cover_vars.go (about) 1 // Package test contains utilities used by plz_go_test. 2 package test 3 4 import ( 5 "fmt" 6 "os" 7 "path" 8 "path/filepath" 9 "strings" 10 ) 11 12 // A CoverVar is just a combination of package path and variable name 13 // for one of the templated-in coverage variables. 14 type CoverVar struct { 15 Dir, ImportPath, ImportName, Var, File string 16 } 17 18 // FindCoverVars searches the given directory recursively to find all Go files with coverage variables. 19 func FindCoverVars(dir, testPackage string, external bool, excludedDirs []string) ([]CoverVar, error) { 20 if dir == "" { 21 return nil, nil 22 } 23 excludeMap := map[string]struct{}{} 24 for _, e := range excludedDirs { 25 excludeMap[e] = struct{}{} 26 } 27 var ret []CoverVar 28 29 err := filepath.WalkDir(dir, func(name string, info os.DirEntry, err error) error { 30 if err != nil { 31 return err 32 } 33 if _, present := excludeMap[name]; present { 34 if info.IsDir() { 35 return filepath.SkipDir 36 } 37 } else if strings.HasSuffix(name, ".cover_vars") { 38 vars, err := parseCoverVars(name, testPackage, external) 39 if err != nil { 40 return err 41 } 42 ret = append(ret, vars...) 43 } 44 return nil 45 }) 46 return ret, err 47 } 48 49 // parseCoverVars parses the coverage variables file for all cover vars 50 func parseCoverVars(filepath, testPackage string, external bool) ([]CoverVar, error) { 51 dir := strings.TrimRight(path.Dir(filepath), "/") 52 if dir == "" { 53 dir = "." 54 } 55 56 b, err := os.ReadFile(filepath) 57 if err != nil { 58 return nil, err 59 } 60 lines := strings.Split(string(b), "\n") 61 ret := make([]CoverVar, 0, len(lines)) 62 for _, line := range lines { 63 if strings.TrimSpace(line) == "" { 64 continue 65 } 66 67 parts := strings.Split(line, "=") 68 if len(parts) != 2 { 69 return nil, fmt.Errorf("malformed cover var line in %v: %v", filepath, line) 70 } 71 if external || dir != os.Getenv("PKG_DIR") { 72 ret = append(ret, coverVar(dir, parts[0], parts[1])) 73 } else { 74 // We recompile the test package, so override the import path here to get the right version 75 ret = append(ret, coverVar(dir, testPackage, parts[1])) 76 } 77 } 78 79 return ret, nil 80 } 81 82 func coverVar(dir, importPath, v string) CoverVar { 83 fmt.Fprintf(os.Stderr, "Found cover variable: %s %s %s\n", dir, importPath, v) 84 f := path.Join(dir, strings.TrimPrefix(v, "GoCover_")) 85 if strings.HasSuffix(f, "_go") { 86 f = f[:len(f)-3] + ".go" 87 } 88 return CoverVar{ 89 Dir: dir, 90 ImportPath: importPath, 91 Var: v, 92 File: f, 93 } 94 }