diff --git a/run_tests.go b/run_tests.go new file mode 100644 index 000000000..28b1ef389 --- /dev/null +++ b/run_tests.go @@ -0,0 +1,162 @@ +// +build ignore + +package main + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func specialDir(name string) bool { + if name == "." { + return false + } + + base := filepath.Base(name) + return base[0] == '_' || base[0] == '.' +} + +func emptyDir(name string) bool { + dir, err := os.Open(name) + defer dir.Close() + if err != nil { + fmt.Fprintf(os.Stderr, "unable to open directory %v: %v\n", name, err) + return true + } + + fis, err := dir.Readdir(-1) + if err != nil { + fmt.Fprintf(os.Stderr, "Readdirnames(%v): %v\n", name, err) + return true + } + + for _, fi := range fis { + if fi.IsDir() { + continue + } + + if filepath.Ext(fi.Name()) == ".go" { + return false + } + } + + return true +} + +func forceRelativeDirname(dirname string) string { + if dirname == "." { + return dirname + } + + if strings.HasPrefix(dirname, "./") { + return dirname + } + + return "./" + dirname +} + +func mergeCoverprofile(file *os.File, out io.Writer) error { + _, err := file.Seek(0, 0) + if err != nil { + return err + } + + rd := bufio.NewReader(file) + _, err = rd.ReadString('\n') + if err == io.EOF { + return nil + } + + if err != nil { + return err + } + + _, err = io.Copy(out, rd) + if err != nil { + return err + } + + err = file.Close() + if err != nil { + return err + } + + return err +} + +func testPackage(pkg string, out io.Writer) error { + file, err := ioutil.TempFile("", "test-coverage-") + defer os.Remove(file.Name()) + defer file.Close() + if err != nil { + return err + } + + cmd := exec.Command("go", "test", + "-cover", "-covermode", "set", "-coverprofile", file.Name(), + pkg, "-test.integration") + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + + err = cmd.Run() + if err != nil { + return err + } + + return mergeCoverprofile(file, out) +} + +func main() { + if len(os.Args) < 2 { + fmt.Fprintln(os.Stderr, "USAGE: run_tests COVERPROFILE [PATHS]") + os.Exit(1) + } + + target := os.Args[1] + dirs := os.Args[2:] + + if len(dirs) == 0 { + dirs = append(dirs, ".") + } + + file, err := os.Create(target) + if err != nil { + fmt.Fprintf(os.Stderr, "create coverprofile failed: %v\n", err) + os.Exit(1) + } + + fmt.Fprintln(file, "mode: set") + + for _, dir := range dirs { + err := filepath.Walk(dir, + func(p string, fi os.FileInfo, e error) error { + if e != nil { + return e + } + + if !fi.IsDir() { + return nil + } + + if specialDir(p) || emptyDir(p) { + return filepath.SkipDir + } + + return testPackage(forceRelativeDirname(p), file) + }) + + if err != nil { + fmt.Fprintf(os.Stderr, "walk(%q): %v\n", dir, err) + } + } + + err = file.Close() + + fmt.Printf("coverprofile: %v\n", file.Name()) +}