Soong: Add build_error proto raw file to $(OUT_DIR).
Soong_ui produces a build_error raw file to $(OUT_DIR) where
the file contains a list of build action errors. Each build action
error represents an error raised by a command. The build_error file
is populated if there was a build error.
Bug: b/132969697
Test: Ran m for successful build. Introduced a broken build change,
ran m and verified using printproto that build_error was
generated successfully.
Change-Id: I690ca1778b4e56f144a3173ba1d16d8494c32c15
diff --git a/ui/status/log.go b/ui/status/log.go
index 7badac7..9090f49 100644
--- a/ui/status/log.go
+++ b/ui/status/log.go
@@ -15,11 +15,17 @@
package status
import (
- "android/soong/ui/logger"
"compress/gzip"
+ "errors"
"fmt"
"io"
+ "io/ioutil"
"strings"
+
+ "github.com/golang/protobuf/proto"
+
+ "android/soong/ui/logger"
+ "android/soong/ui/status/build_error_proto"
)
type verboseLog struct {
@@ -77,8 +83,7 @@
}
type errorLog struct {
- w io.WriteCloser
-
+ w io.WriteCloser
empty bool
}
@@ -102,20 +107,17 @@
return
}
- cmd := result.Command
- if cmd == "" {
- cmd = result.Description
- }
-
if !e.empty {
fmt.Fprintf(e.w, "\n\n")
}
e.empty = false
fmt.Fprintf(e.w, "FAILED: %s\n", result.Description)
+
if len(result.Outputs) > 0 {
fmt.Fprintf(e.w, "Outputs: %s\n", strings.Join(result.Outputs, " "))
}
+
fmt.Fprintf(e.w, "Error: %s\n", result.Error)
if result.Command != "" {
fmt.Fprintf(e.w, "Command: %s\n", result.Command)
@@ -144,3 +146,55 @@
fmt.Fprint(e.w, string(p))
return len(p), nil
}
+
+type errorProtoLog struct {
+ errorProto soong_build_error_proto.BuildError
+ filename string
+ log logger.Logger
+}
+
+func NewProtoErrorLog(log logger.Logger, filename string) StatusOutput {
+ return &errorProtoLog{
+ errorProto: soong_build_error_proto.BuildError{},
+ filename: filename,
+ log: log,
+ }
+}
+
+func (e *errorProtoLog) StartAction(action *Action, counts Counts) {}
+
+func (e *errorProtoLog) FinishAction(result ActionResult, counts Counts) {
+ if result.Error == nil {
+ return
+ }
+
+ e.errorProto.ActionErrors = append(e.errorProto.ActionErrors, &soong_build_error_proto.BuildActionError{
+ Description: proto.String(result.Description),
+ Command: proto.String(result.Command),
+ Output: proto.String(result.Output),
+ Artifacts: result.Outputs,
+ Error: proto.String(result.Error.Error()),
+ })
+}
+
+func (e *errorProtoLog) Flush() {
+ data, err := proto.Marshal(&e.errorProto)
+ if err != nil {
+ e.log.Println("Failed to marshal build status proto: %v", err)
+ return
+ }
+ err = ioutil.WriteFile(e.filename, []byte(data), 0644)
+ if err != nil {
+ e.log.Println("Failed to write file %s: %v", e.errorProto, err)
+ }
+}
+
+func (e *errorProtoLog) Message(level MsgLevel, message string) {
+ if level > ErrorLvl {
+ e.errorProto.ErrorMessages = append(e.errorProto.ErrorMessages, message)
+ }
+}
+
+func (e *errorProtoLog) Write(p []byte) (int, error) {
+ return 0, errors.New("not supported")
+}