Merge "Highlight build failures in soong output" into main
This commit is contained in:
@@ -23,26 +23,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type formatter struct {
|
type formatter struct {
|
||||||
format string
|
colorize bool
|
||||||
quiet bool
|
format string
|
||||||
start time.Time
|
quiet bool
|
||||||
|
start time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFormatter returns a formatter for formatting output to
|
// newFormatter returns a formatter for formatting output to
|
||||||
// the terminal in a format similar to Ninja.
|
// the terminal in a format similar to Ninja.
|
||||||
// format takes nearly all the same options as NINJA_STATUS.
|
// format takes nearly all the same options as NINJA_STATUS.
|
||||||
// %c is currently unsupported.
|
// %c is currently unsupported.
|
||||||
func newFormatter(format string, quiet bool) formatter {
|
func newFormatter(colorize bool, format string, quiet bool) formatter {
|
||||||
return formatter{
|
return formatter{
|
||||||
format: format,
|
colorize: colorize,
|
||||||
quiet: quiet,
|
format: format,
|
||||||
start: time.Now(),
|
quiet: quiet,
|
||||||
|
start: time.Now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s formatter) message(level status.MsgLevel, message string) string {
|
func (s formatter) message(level status.MsgLevel, message string) string {
|
||||||
if level >= status.ErrorLvl {
|
if level >= status.ErrorLvl {
|
||||||
return fmt.Sprintf("FAILED: %s", message)
|
return fmt.Sprintf("%s %s", s.failedString(), message)
|
||||||
} else if level > status.StatusLvl {
|
} else if level > status.StatusLvl {
|
||||||
return fmt.Sprintf("%s%s", level.Prefix(), message)
|
return fmt.Sprintf("%s%s", level.Prefix(), message)
|
||||||
} else if level == status.StatusLvl {
|
} else if level == status.StatusLvl {
|
||||||
@@ -127,9 +129,9 @@ func (s formatter) result(result status.ActionResult) string {
|
|||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
targets := strings.Join(result.Outputs, " ")
|
targets := strings.Join(result.Outputs, " ")
|
||||||
if s.quiet || result.Command == "" {
|
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 {
|
} 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 != "" {
|
} else if result.Output != "" {
|
||||||
ret = result.Output
|
ret = result.Output
|
||||||
@@ -141,3 +143,11 @@ func (s formatter) result(result status.ActionResult) string {
|
|||||||
|
|
||||||
return ret
|
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.
|
// statusFormat takes nearly all the same options as NINJA_STATUS.
|
||||||
// %c is currently unsupported.
|
// %c is currently unsupported.
|
||||||
func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild, forceKeepANSI bool) status.StatusOutput {
|
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)
|
return NewSmartStatusOutput(w, formatter)
|
||||||
} else {
|
} else {
|
||||||
return NewSimpleStatusOutput(w, formatter, forceKeepANSI)
|
return NewSimpleStatusOutput(w, formatter, forceKeepANSI)
|
||||||
|
@@ -58,7 +58,7 @@ func TestStatusOutput(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "action with error",
|
name: "action with error",
|
||||||
calls: actionsWithError,
|
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",
|
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",
|
name: "messages",
|
||||||
calls: actionsWithMessages,
|
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",
|
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()
|
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 {
|
if g := smart.String(); g != w {
|
||||||
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
||||||
@@ -407,7 +407,7 @@ func TestSmartStatusHideAfterFailurePlural(t *testing.T) {
|
|||||||
|
|
||||||
stat.Flush()
|
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 {
|
if g := smart.String(); g != w {
|
||||||
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
||||||
@@ -445,7 +445,7 @@ func TestSmartStatusDontHideErrorAfterFailure(t *testing.T) {
|
|||||||
|
|
||||||
stat.Flush()
|
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 {
|
if g := smart.String(); g != w {
|
||||||
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
t.Errorf("want:\n%q\ngot:\n%q", w, g)
|
||||||
|
Reference in New Issue
Block a user