Skip to content

Commit ac803b5

Browse files
adonovangopherbot
authored andcommitted
cmd/go/internal/work: copy vet tool's stdout to our stdout
The go command connects both the stdout and stderr files of its child commands (cmd/compile, cmd/vet, etc) to the go command's own stderr. If the child command is supposed to produce structure output on stderr, as is the case for go vet -json or go fix -diff, it will be merged with the error stream, making it useless. This change to the go vet <-> unitchecker protocol specifies the name of a file into which the vet tool should write its stdout. On success, the go command will then copy the entire content of that file to its own stdout, under a lock. This ensures that partial writes to stdout in case of failure, concurrent writes to stdout by parallel vet tasks, or other junk on stderr, cannot interfere with the integrity of the go command's structure output on stdout. CL 702835 is the corresponding change on the x/tools side. For golang#75432 Change-Id: Ib4db25b6b0095d359152d7543bd9bf692551bbfa Reviewed-on: https://go-review.googlesource.com/c/go/+/702815 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Matloob <[email protected]> Auto-Submit: Alan Donovan <[email protected]>
1 parent 889e71c commit ac803b5

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

src/cmd/go/internal/work/exec.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,7 @@ type vetConfig struct {
11841184
PackageVetx map[string]string // map package path to vetx data from earlier vet run
11851185
VetxOnly bool // only compute vetx data; don't report detected problems
11861186
VetxOutput string // write vetx data to this output file
1187+
Stdout string // write stdout (JSON, unified diff) to this output file
11871188
GoVersion string // Go version for package
11881189

11891190
SucceedOnTypecheckFailure bool // awful hack; see #18395 and below
@@ -1297,6 +1298,7 @@ func (b *Builder) vet(ctx context.Context, a *Action) error {
12971298

12981299
vcfg.VetxOnly = a.VetxOnly
12991300
vcfg.VetxOutput = a.Objdir + "vet.out"
1301+
vcfg.Stdout = a.Objdir + "vet.stdout"
13001302
vcfg.PackageVetx = make(map[string]string)
13011303

13021304
h := cache.NewHash("vet " + a.Package.ImportPath)
@@ -1392,13 +1394,25 @@ func (b *Builder) vet(ctx context.Context, a *Action) error {
13921394
// If vet wrote export data, save it for input to future vets.
13931395
if f, err := os.Open(vcfg.VetxOutput); err == nil {
13941396
a.built = vcfg.VetxOutput
1395-
cache.Default().Put(key, f)
1396-
f.Close()
1397+
cache.Default().Put(key, f) // ignore error
1398+
f.Close() // ignore error
1399+
}
1400+
1401+
// If vet wrote to stdout, copy it to go's stdout, atomically.
1402+
if f, err := os.Open(vcfg.Stdout); err == nil {
1403+
stdoutMu.Lock()
1404+
if _, err := io.Copy(os.Stdout, f); err != nil && runErr == nil {
1405+
runErr = fmt.Errorf("copying vet tool stdout: %w", err)
1406+
}
1407+
f.Close() // ignore error
1408+
stdoutMu.Unlock()
13971409
}
13981410

13991411
return runErr
14001412
}
14011413

1414+
var stdoutMu sync.Mutex // serializes concurrent writes (e.g. JSON values) to stdout
1415+
14021416
// linkActionID computes the action ID for a link action.
14031417
func (b *Builder) linkActionID(a *Action) cache.ActionID {
14041418
p := a.Package

src/cmd/go/testdata/script/vet_asm.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ stderr '2 MOVW'
1414
stderr '3 RET'
1515
stderr '4'
1616

17-
# -json causes success, even with diagnostics and errors.
17+
# -json causes success, even with diagnostics and errors,
18+
# and writes to stdout.
1819
go vet -json -asmdecl a
19-
stderr '"a": {'
20-
stderr '"asmdecl":'
21-
stderr '"posn": ".*asm.s:2:1",'
22-
stderr '"message": ".*invalid MOVW.*"'
20+
stdout '"a": {'
21+
stdout '"asmdecl":'
22+
stdout '"posn": ".*asm.s:2:1",'
23+
stdout '"message": ".*invalid MOVW.*"'
2324

2425
-- a/a.go --
2526
package a

0 commit comments

Comments
 (0)