diff --git a/go/tools/builders/compilepkg.go b/go/tools/builders/compilepkg.go index 77bc28b116..4af57a774b 100644 --- a/go/tools/builders/compilepkg.go +++ b/go/tools/builders/compilepkg.go @@ -460,7 +460,7 @@ func runNogo(ctx context.Context, workDir string, nogoPath string, srcs []string cmdLine := strings.Join(args, " ") return fmt.Errorf("nogo command '%s' exited unexpectedly: %s", cmdLine, exitErr.String()) } - return errors.New(out.String()) + return errors.New(string(relativizePaths(out.Bytes()))) } else { if out.Len() != 0 { fmt.Fprintln(os.Stderr, out.String()) diff --git a/go/tools/builders/env.go b/go/tools/builders/env.go index 8a839dd618..5faacee0ce 100644 --- a/go/tools/builders/env.go +++ b/go/tools/builders/env.go @@ -133,9 +133,12 @@ func (e *env) runCommand(args []string) error { cmd := exec.Command(args[0], args[1:]...) // Redirecting stdout to stderr. This mirrors behavior in the go command: // https://go.googlesource.com/go/+/refs/tags/go1.15.2/src/cmd/go/internal/work/exec.go#1958 - cmd.Stdout = os.Stderr - cmd.Stderr = os.Stderr - return runAndLogCommand(cmd, e.verbose) + buf := &bytes.Buffer{} + cmd.Stdout = buf + cmd.Stderr = buf + err := runAndLogCommand(cmd, e.verbose) + fmt.Fprint(os.Stderr, relativizePaths(buf.Bytes())) + return err } // runCommandToFile executes a subprocess and writes the output to the given @@ -332,6 +335,27 @@ func absArgs(args []string, flags []string) { } } +// relativizePaths converts absolute paths found in the given output string to +// relative, if they are within the working directory. +func relativizePaths(output []byte) []byte { + dir, err := os.Getwd() + if dir == "" || err != nil { + return output + } + dirBytes := make([]byte, len(dir), len(dir)+1) + copy(dirBytes, dir) + if bytes.HasSuffix(dirBytes, []byte{filepath.Separator}) { + return bytes.ReplaceAll(output, dirBytes, nil) + } + + // This is the common case. + // Replace "$CWD/" with "" and "$CWD" with "." + dirBytes = append(dirBytes, filepath.Separator) + output = bytes.ReplaceAll(output, dirBytes, nil) + dirBytes = dirBytes[:len(dirBytes)-1] + return bytes.ReplaceAll(output, dirBytes, []byte{'.'}) +} + // formatCommand formats cmd as a string that can be pasted into a shell. // Spaces in environment variables and arguments are escaped as needed. func formatCommand(cmd *exec.Cmd) string {