Merge "Highlight build failures in soong output" into main
This commit is contained in:
@@ -23,26 +23,28 @@ import (
|
||||
)
|
||||
|
||||
type formatter struct {
|
||||
format string
|
||||
quiet bool
|
||||
start time.Time
|
||||
colorize bool
|
||||
format string
|
||||
quiet bool
|
||||
start time.Time
|
||||
}
|
||||
|
||||
// newFormatter returns a formatter for formatting output to
|
||||
// the terminal in a format similar to Ninja.
|
||||
// format takes nearly all the same options as NINJA_STATUS.
|
||||
// %c is currently unsupported.
|
||||
func newFormatter(format string, quiet bool) formatter {
|
||||
func newFormatter(colorize bool, format string, quiet bool) formatter {
|
||||
return formatter{
|
||||
format: format,
|
||||
quiet: quiet,
|
||||
start: time.Now(),
|
||||
colorize: colorize,
|
||||
format: format,
|
||||
quiet: quiet,
|
||||
start: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s formatter) message(level status.MsgLevel, message string) string {
|
||||
if level >= status.ErrorLvl {
|
||||
return fmt.Sprintf("FAILED: %s", message)
|
||||
return fmt.Sprintf("%s %s", s.failedString(), message)
|
||||
} else if level > status.StatusLvl {
|
||||
return fmt.Sprintf("%s%s", level.Prefix(), message)
|
||||
} else if level == status.StatusLvl {
|
||||
@@ -127,9 +129,9 @@ func (s formatter) result(result status.ActionResult) string {
|
||||
if result.Error != nil {
|
||||
targets := strings.Join(result.Outputs, " ")
|
||||
if s.quiet || result.Command == "" {
|
||||
ret = fmt.Sprintf("FAILED: %s\n%s", targets, result.Output)
|
||||
ret = fmt.Sprintf("%s %s\n%s", s.failedString(), targets, result.Output)
|
||||
} else {
|
||||
ret = fmt.Sprintf("FAILED: %s\n%s\n%s", targets, result.Command, result.Output)
|
||||
ret = fmt.Sprintf("%s %s\n%s\n%s", s.failedString(), targets, result.Command, result.Output)
|
||||
}
|
||||
} else if result.Output != "" {
|
||||
ret = result.Output
|
||||
@@ -141,3 +143,11 @@ func (s formatter) result(result status.ActionResult) string {
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s formatter) failedString() string {
|
||||
failed := "FAILED:"
|
||||
if s.colorize {
|
||||
failed = ansi.red() + ansi.bold() + failed + ansi.regular()
|
||||
}
|
||||
return failed
|
||||
}
|
||||
|
@@ -27,9 +27,10 @@ import (
|
||||
// statusFormat takes nearly all the same options as NINJA_STATUS.
|
||||
// %c is currently unsupported.
|
||||
func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild, forceKeepANSI bool) status.StatusOutput {
|
||||
formatter := newFormatter(statusFormat, quietBuild)
|
||||
canUseSmartFormatting := !forceSimpleOutput && isSmartTerminal(w)
|
||||
formatter := newFormatter(canUseSmartFormatting, statusFormat, quietBuild)
|
||||
|
||||
if !forceSimpleOutput && isSmartTerminal(w) {
|
||||
if canUseSmartFormatting {
|
||||
return NewSmartStatusOutput(w, formatter)
|
||||
} else {
|
||||
return NewSimpleStatusOutput(w, formatter, forceKeepANSI)
|
||||
|
@@ -58,7 +58,7 @@ func TestStatusOutput(t *testing.T) {
|
||||
{
|
||||
name: "action with error",
|
||||
calls: actionsWithError,
|
||||
smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\nFAILED: f1 f2\ntouch f1 f2\nerror1\nerror2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
|
||||
smart: "\r\x1b[1m[ 0% 0/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action1\x1b[0m\x1b[K\r\x1b[1m[ 33% 1/3] action2\x1b[0m\x1b[K\r\x1b[1m[ 66% 2/3] action2\x1b[0m\x1b[K\n\x1b[31m\x1b[1mFAILED:\x1b[0m f1 f2\ntouch f1 f2\nerror1\nerror2\n\r\x1b[1m[ 66% 2/3] action3\x1b[0m\x1b[K\r\x1b[1m[100% 3/3] action3\x1b[0m\x1b[K\n",
|
||||
simple: "[ 33% 1/3] action1\n[ 66% 2/3] action2\nFAILED: f1 f2\ntouch f1 f2\nerror1\nerror2\n[100% 3/3] action3\n",
|
||||
},
|
||||
{
|
||||
@@ -70,7 +70,7 @@ func TestStatusOutput(t *testing.T) {
|
||||
{
|
||||
name: "messages",
|
||||
calls: actionsWithMessages,
|
||||
smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1mstatus\x1b[0m\x1b[K\r\x1b[Kprint\nFAILED: error\n\r\x1b[1m[ 50% 1/2] action2\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
|
||||
smart: "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\r\x1b[1mstatus\x1b[0m\x1b[K\r\x1b[Kprint\n\x1b[31m\x1b[1mFAILED:\x1b[0m error\n\r\x1b[1m[ 50% 1/2] action2\x1b[0m\x1b[K\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n",
|
||||
simple: "[ 50% 1/2] action1\nstatus\nprint\nFAILED: error\n[100% 2/2] action2\n",
|
||||
},
|
||||
{
|
||||
@@ -362,7 +362,7 @@ func TestSmartStatusHideAfterFailure(t *testing.T) {
|
||||
|
||||
stat.Flush()
|
||||
|
||||
w := "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\nFAILED: \nOutput1\n\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\nThere was 1 action that completed after the action that failed. See verbose.log.gz for its output.\n"
|
||||
w := "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\n\x1b[31m\x1b[1mFAILED:\x1b[0m \nOutput1\n\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\nThere was 1 action that completed after the action that failed. See verbose.log.gz for its output.\n"
|
||||
|
||||
if g := smart.String(); g != w {
|
||||
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
||||
@@ -407,7 +407,7 @@ func TestSmartStatusHideAfterFailurePlural(t *testing.T) {
|
||||
|
||||
stat.Flush()
|
||||
|
||||
w := "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action3\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\nFAILED: \nOutput1\n\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\r\x1b[1m[150% 3/2] action3\x1b[0m\x1b[K\nThere were 2 actions that completed after the action that failed. See verbose.log.gz for their output.\n"
|
||||
w := "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action3\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\n\x1b[31m\x1b[1mFAILED:\x1b[0m \nOutput1\n\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\r\x1b[1m[150% 3/2] action3\x1b[0m\x1b[K\nThere were 2 actions that completed after the action that failed. See verbose.log.gz for their output.\n"
|
||||
|
||||
if g := smart.String(); g != w {
|
||||
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
||||
@@ -445,7 +445,7 @@ func TestSmartStatusDontHideErrorAfterFailure(t *testing.T) {
|
||||
|
||||
stat.Flush()
|
||||
|
||||
w := "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\nFAILED: \nOutput1\n\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\nFAILED: \nOutput2\n"
|
||||
w := "\r\x1b[1m[ 0% 0/2] action1\x1b[0m\x1b[K\r\x1b[1m[ 0% 0/2] action2\x1b[0m\x1b[K\r\x1b[1m[ 50% 1/2] action1\x1b[0m\x1b[K\n\x1b[31m\x1b[1mFAILED:\x1b[0m \nOutput1\n\r\x1b[1m[100% 2/2] action2\x1b[0m\x1b[K\n\x1b[31m\x1b[1mFAILED:\x1b[0m \nOutput2\n"
|
||||
|
||||
if g := smart.String(); g != w {
|
||||
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
||||
|
Reference in New Issue
Block a user