diff options
author | Bryan C. Mills <bcmills@google.com> | 2019-03-06 11:06:14 -0500 |
---|---|---|
committer | Bryan C. Mills <bcmills@google.com> | 2019-03-06 20:05:33 +0000 |
commit | a30421a39480efd766eb07518fb2edc4c9e0a8b8 (patch) | |
tree | d39012429cfff93cdf9f5dc3d981e18d2fa2e3ef /src/cmd/vet | |
parent | 4a9064ef41ccc65454564536f40cf7d5a00db8ad (diff) | |
download | go-a30421a39480efd766eb07518fb2edc4c9e0a8b8.tar.gz go-a30421a39480efd766eb07518fb2edc4c9e0a8b8.zip |
cmd/vet/all: build the vet tool within the golang.org/x/tools repository
When running cmd/vet/all on multiple builders, the coordinator places
a copy of golang.org/x/tools at a consistent revision in the builders'
GOPATHs. Keep using the consistent revision in module mode by
executing the build from a working directory within that repository.
When not running on a builder, use 'go vet' directly instead of
building an arbitrarily stale vet tool from the user's GOPATH.
Updates #30228
Change-Id: I19bc809247378da98f3e6ac8572f61bda4518143
Reviewed-on: https://go-review.googlesource.com/c/go/+/165740
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd/vet')
-rw-r--r-- | src/cmd/vet/all/main.go | 90 |
1 files changed, 65 insertions, 25 deletions
diff --git a/src/cmd/vet/all/main.go b/src/cmd/vet/all/main.go index 8cc4140e6e..018eba4d6e 100644 --- a/src/cmd/vet/all/main.go +++ b/src/cmd/vet/all/main.go @@ -42,7 +42,7 @@ var failed uint32 // updated atomically func main() { log.SetPrefix("vet/all: ") - log.SetFlags(0) + log.SetFlags(log.Lshortfile) testenv.SetModVendor() var err error @@ -78,9 +78,10 @@ var hostPlatform = platform{os: build.Default.GOOS, arch: build.Default.GOARCH} func allPlatforms() []platform { var pp []platform cmd := exec.Command(cmdGoPath, "tool", "dist", "list") + cmd.Stderr = new(strings.Builder) out, err := cmd.Output() if err != nil { - log.Fatal(err) + log.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) } lines := bytes.Split(out, []byte{'\n'}) for _, line := range lines { @@ -222,22 +223,61 @@ func (p platform) vet() { w := make(whitelist) w.load(p.os, p.arch) - tmpdir, err := ioutil.TempDir("", "cmd-vet-all") - if err != nil { - log.Fatal(err) - } - defer os.RemoveAll(tmpdir) + var vetCmd []string - // Build the go/packages-based vet command from the x/tools - // repo. It is considerably faster than "go vet", which rebuilds - // the standard library. - vetTool := filepath.Join(tmpdir, "vet") - cmd := exec.Command(cmdGoPath, "build", "-o", vetTool, "golang.org/x/tools/go/analysis/cmd/vet") - cmd.Dir = filepath.Join(runtime.GOROOT(), "src") - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stderr - if err := cmd.Run(); err != nil { - log.Fatal(err) + if os.Getenv("GO_BUILDER_NAME") == "" { + vetCmd = []string{cmdGoPath, "vet"} + } else { + // Build the go/packages-based vet command from the x/tools + // repo. It is considerably faster than "go vet", which rebuilds + // the standard library. + tmpdir, err := ioutil.TempDir("", "cmd-vet-all") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + vetTool := filepath.Join(tmpdir, "vet") + vetCmd = []string{ + vetTool, + "-nilness=0", // expensive, uses SSA + } + + cmd := exec.Command(cmdGoPath, "build", "-o", vetTool, "golang.org/x/tools/go/analysis/cmd/vet") + cmd.Env = os.Environ() + + // golang.org/x/tools does not have a vendor directory, so don't try to use + // one in module mode. + for i, v := range cmd.Env { + if strings.HasPrefix(v, "GOFLAGS=") { + var goflags []string + for _, f := range strings.Fields(strings.TrimPrefix(v, "GOFLAGS=")) { + if f != "-mod=vendor" && f != "--mod=vendor" { + goflags = append(goflags, f) + } + } + cmd.Env[i] = strings.Join(goflags, " ") + } + } + + // The coordinator places a copy of golang.org/x/tools in GOPATH. + // If we can find it there, use that specific version. + for _, gp := range filepath.SplitList(os.Getenv("GOPATH")) { + gopathDir := filepath.Join(gp, "src", "golang.org", "x", "tools", "go", "analysis", "cmd", "vet") + if _, err := os.Stat(gopathDir); err == nil { + cmd.Dir = gopathDir + } + } + if cmd.Dir == "" { + // Otherwise, move to tmpdir and let the module loader resolve the latest version. + cmd.Dir = tmpdir + } + + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stderr + if err := cmd.Run(); err != nil { + log.Fatalf("%s: %v", strings.Join(cmd.Args, " "), err) + } } // TODO: The unsafeptr checks are disabled for now, @@ -245,13 +285,13 @@ func (p platform) vet() { // and no clear way to improve vet to eliminate large chunks of them. // And having them in the whitelists will just cause annoyance // and churn when working on the runtime. - cmd = exec.Command(vetTool, - "-unsafeptr=0", - "-nilness=0", // expensive, uses SSA - "std", - "cmd/...", - "cmd/compile/internal/gc/testdata", - ) + cmd := exec.Command(vetCmd[0], + append(vetCmd[1:], + "-unsafeptr=0", + "std", + "cmd/...", + "cmd/compile/internal/gc/testdata", + )...) cmd.Dir = filepath.Join(runtime.GOROOT(), "src") cmd.Env = append(os.Environ(), "GOOS="+p.os, "GOARCH="+p.arch, "CGO_ENABLED=0") stderr, err := cmd.StderrPipe() @@ -321,7 +361,7 @@ NextLine: if file == "" { if !parseFailed { parseFailed = true - fmt.Fprintf(os.Stderr, "failed to parse %s vet output:\n", p) + fmt.Fprintf(os.Stderr, "failed to parse %s output:\n# %s\n", p, strings.Join(cmd.Args, " ")) } fmt.Fprintln(os.Stderr, line) continue |