return e.importPath
}
-// showOutput prints "# desc" followed by the given output.
-// The output is expected to contain references to 'dir', usually
-// the source directory for the package that has failed to build.
-// showOutput rewrites mentions of dir with a relative path to dir
-// when the relative path is shorter. This is usually more pleasant.
-// For example, if fmt doesn't compile and we are in src/html,
-// the output is
-//
-// $ go build
-// # fmt
-// ../fmt/print.go:1090: undefined: asdf
-// $
-//
-// instead of
-//
-// $ go build
-// # fmt
-// /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
-// $
-//
-// showOutput also replaces references to the work directory with $WORK.
-//
-// If a is not nil and a.output is not nil, showOutput appends to that slice instead of
-// printing to b.Print.
-func (b *Builder) showOutput(a *Action, dir, desc, out string) {
- importPath := ""
- if a != nil && a.Package != nil {
- importPath = a.Package.ImportPath
- }
- psErr := formatOutput(b.WorkDir, dir, importPath, desc, out)
- if a != nil && a.output != nil {
- a.output = append(a.output, psErr.prefix...)
- a.output = append(a.output, psErr.suffix...)
- return
- }
-
- b.output.Lock()
- defer b.output.Unlock()
- b.Print(psErr.prefix, psErr.suffix)
-}
-
-// A prefixSuffixError is an error formatted by formatOutput.
-type prefixSuffixError struct {
- importPath string
- prefix, suffix string
-}
-
-func (e *prefixSuffixError) Error() string {
- if e.importPath != "" && !strings.HasPrefix(strings.TrimPrefix(e.prefix, "# "), e.importPath) {
- return fmt.Sprintf("go build %s:\n%s%s", e.importPath, e.prefix, e.suffix)
- }
- return e.prefix + e.suffix
-}
-
-func (e *prefixSuffixError) ImportPath() string {
- return e.importPath
-}
-
-// formatOutput prints "# desc" followed by the given output.
-// The output is expected to contain references to 'dir', usually
-// the source directory for the package that has failed to build.
-// formatOutput rewrites mentions of dir with a relative path to dir
-// when the relative path is shorter. This is usually more pleasant.
-// For example, if fmt doesn't compile and we are in src/html,
-// the output is
-//
-// $ go build
-// # fmt
-// ../fmt/print.go:1090: undefined: asdf
-// $
-//
-// instead of
-//
-// $ go build
-// # fmt
-// /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
-// $
-//
-// formatOutput also replaces references to the work directory with $WORK.
-// formatOutput returns the output in a prefix with the description and a
-// suffix with the actual output.
-func formatOutput(workDir, dir, importPath, desc, out string) *prefixSuffixError {
- prefix := "# " + desc
- suffix := "\n" + out
-
- suffix = strings.ReplaceAll(suffix, " "+workDir, " $WORK")
-
- for {
- // Note that dir starts out long, something like
- // /foo/bar/baz/root/a
- // The target string to be reduced is something like
- // (blah-blah-blah) /foo/bar/baz/root/sibling/whatever.go:blah:blah
- // /foo/bar/baz/root/a doesn't match /foo/bar/baz/root/sibling, but the prefix
- // /foo/bar/baz/root does. And there may be other niblings sharing shorter
- // prefixes, the only way to find them is to look.
- // This doesn't always produce a relative path --
- // /foo is shorter than ../../.., for example.
- //
- if reldir := base.ShortPath(dir); reldir != dir {
- suffix = strings.ReplaceAll(suffix, " "+dir, " "+reldir)
- suffix = strings.ReplaceAll(suffix, "\n"+dir, "\n"+reldir)
- suffix = strings.ReplaceAll(suffix, "\n\t"+dir, "\n\t"+reldir)
- if filepath.Separator == '\\' {
- // Don't know why, sometimes this comes out with slashes, not backslashes.
- wdir := strings.ReplaceAll(dir, "\\", "/")
- suffix = strings.ReplaceAll(suffix, " "+wdir, " "+reldir)
- suffix = strings.ReplaceAll(suffix, "\n"+wdir, "\n"+reldir)
- suffix = strings.ReplaceAll(suffix, "\n\t"+wdir, "\n\t"+reldir)
- }
- }
- dirP := filepath.Dir(dir)
- if dir == dirP {
- break
- }
- dir = dirP
- }
-
- return &prefixSuffixError{importPath: importPath, prefix: prefix, suffix: suffix}
-}
-
var cgoLine = lazyregexp.New(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`)
var cgoTypeSigRe = lazyregexp.New(`\b_C2?(type|func|var|macro)_\B`)
return b.reportCmd(a, nil, desc, dir, out, err)
}
-// processOutput prepares the output of runOut to be output to the console.
-func (b *Builder) processOutput(out []byte) string {
- if out[len(out)-1] != '\n' {
- out = append(out, '\n')
- }
- messages := string(out)
- // Fix up output referring to cgo-generated code to be more readable.
- // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
- // Replace *[100]_Ctype_foo with *[100]C.foo.
- // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
- if !cfg.BuildX && cgoLine.MatchString(messages) {
- messages = cgoLine.ReplaceAllString(messages, "")
- messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
- }
- return messages
-}
-
// runOut runs the command given by cmdline in the directory dir.
// It returns the command output and any errors that occurred.
// It accumulates execution time in a.