1
0
mirror of https://github.com/golang/go synced 2024-11-05 15:26:15 -07:00

cmd/vet/all: vet using only source

This simplifies the code and speeds it up.
It also allows us to eliminate some other TODOs;
those will come in a follow-up CL.

Running for the host platform, before:

real	0m9.907s
user	0m14.566s
sys	0m1.058s

After:

real	0m7.841s
user	0m12.339s
sys	0m0.572s

Running for a single non-host platform, before:

real	0m8.784s
user	0m15.451s
sys	0m3.445s

After:

real	0m7.681s
user	0m12.122s
sys	0m0.577s

Running for all platforms, before:

real	7m4.480s
user	8m43.398s
sys	1m15.683s

After:

real	4m37.596s
user	7m30.729s
sys	0m18.533s

It also makes my laptop considerably more
responsive while running for all platforms.

Change-Id: I748689fea0d2d4ef61aca2ce5524d03d8fafa5ca
Reviewed-on: https://go-review.googlesource.com/37691
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2017-03-02 09:07:14 -08:00
parent ddbee9abd4
commit 8a93546d68

View File

@ -22,9 +22,7 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv"
"strings" "strings"
"sync"
"sync/atomic" "sync/atomic"
) )
@ -62,7 +60,7 @@ func main() {
case *flagAll: case *flagAll:
vetPlatforms(allPlatforms()) vetPlatforms(allPlatforms())
default: default:
hostPlatform.vet(runtime.GOMAXPROCS(-1)) hostPlatform.vet()
} }
if atomic.LoadUint32(&failed) != 0 { if atomic.LoadUint32(&failed) != 0 {
os.Exit(1) os.Exit(1)
@ -198,23 +196,12 @@ var ignorePathPrefixes = [...]string{
} }
func vetPlatforms(pp []platform) { func vetPlatforms(pp []platform) {
ncpus := runtime.GOMAXPROCS(-1) / len(pp)
if ncpus < 1 {
ncpus = 1
}
var wg sync.WaitGroup
wg.Add(len(pp))
for _, p := range pp { for _, p := range pp {
p := p p.vet()
go func() {
p.vet(ncpus)
wg.Done()
}()
} }
wg.Wait()
} }
func (p platform) vet(ncpus int) { func (p platform) vet() {
var buf bytes.Buffer var buf bytes.Buffer
fmt.Fprintf(&buf, "go run main.go -p %s\n", p) fmt.Fprintf(&buf, "go run main.go -p %s\n", p)
@ -224,29 +211,13 @@ func (p platform) vet(ncpus int) {
env := append(os.Environ(), "GOOS="+p.os, "GOARCH="+p.arch, "CGO_ENABLED=0") env := append(os.Environ(), "GOOS="+p.os, "GOARCH="+p.arch, "CGO_ENABLED=0")
// Do 'go install std' before running vet.
// It is cheap when already installed.
// Not installing leads to non-obvious failures due to inability to typecheck.
// TODO: If go/loader ever makes it to the standard library, have vet use it,
// at which point vet can work off source rather than compiled packages.
gcflags := ""
if p != hostPlatform {
gcflags = "-dolinkobj=false"
}
cmd := exec.Command(cmdGoPath, "install", "-p", strconv.Itoa(ncpus), "-gcflags="+gcflags, "std")
cmd.Env = env
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("failed to run GOOS=%s GOARCH=%s 'go install std': %v\n%s", p.os, p.arch, err, out)
}
// 'go tool vet .' is considerably faster than 'go vet ./...' // 'go tool vet .' is considerably faster than 'go vet ./...'
// TODO: The unsafeptr checks are disabled for now, // TODO: The unsafeptr checks are disabled for now,
// because there are so many false positives, // because there are so many false positives,
// and no clear way to improve vet to eliminate large chunks of them. // and no clear way to improve vet to eliminate large chunks of them.
// And having them in the whitelists will just cause annoyance // And having them in the whitelists will just cause annoyance
// and churn when working on the runtime. // and churn when working on the runtime.
args := []string{"tool", "vet", "-unsafeptr=false"} args := []string{"tool", "vet", "-unsafeptr=false", "-source"}
if p != hostPlatform { if p != hostPlatform {
// When not checking the host platform, vet gets confused by // When not checking the host platform, vet gets confused by
// the fmt.Formatters in cmd/compile, // the fmt.Formatters in cmd/compile,
@ -257,7 +228,7 @@ func (p platform) vet(ncpus int) {
args = append(args, "-printf=false") args = append(args, "-printf=false")
} }
args = append(args, ".") args = append(args, ".")
cmd = exec.Command(cmdGoPath, args...) cmd := exec.Command(cmdGoPath, args...)
cmd.Dir = filepath.Join(runtime.GOROOT(), "src") cmd.Dir = filepath.Join(runtime.GOROOT(), "src")
cmd.Env = env cmd.Env = env
stderr, err := cmd.StderrPipe() stderr, err := cmd.StderrPipe()