summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/multiproduct_kati/main.go8
-rw-r--r--cmd/soong_ui/main.go3
-rw-r--r--cuj/cuj.go2
-rw-r--r--ui/terminal/simple_status.go8
-rw-r--r--ui/terminal/smart_status.go57
-rw-r--r--ui/terminal/status.go4
-rw-r--r--ui/terminal/status_test.go8
7 files changed, 55 insertions, 35 deletions
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index fa63b465d..3c9cac190 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -218,10 +218,16 @@ func distDir(outDir string) string {
}
}
+func forceAnsiOutput() bool {
+ value := os.Getenv("SOONG_UI_ANSI_OUTPUT")
+ return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true"
+}
+
func main() {
stdio := terminal.StdioImpl{}
- output := terminal.NewStatusOutput(stdio.Stdout(), "", false, false)
+ output := terminal.NewStatusOutput(stdio.Stdout(), "", false, false,
+ forceAnsiOutput())
log := logger.New(output)
defer log.Cleanup()
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index d70978727..9ee373e79 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -164,7 +164,8 @@ func main() {
// Create a terminal output that mimics Ninja's.
output := terminal.NewStatusOutput(c.stdio().Stdout(), os.Getenv("NINJA_STATUS"), c.simpleOutput,
- build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"))
+ build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"),
+ build.OsEnvironment().IsEnvTrue("SOONG_UI_ANSI_OUTPUT"))
// Attach a new logger instance to the terminal output.
log := logger.New(output)
diff --git a/cuj/cuj.go b/cuj/cuj.go
index c671f6f09..869e0f7b1 100644
--- a/cuj/cuj.go
+++ b/cuj/cuj.go
@@ -48,7 +48,7 @@ type TestResults struct {
// Run runs a single build command. It emulates the "m" command line by calling into Soong UI directly.
func (t *Test) Run(logsDir string) {
- output := terminal.NewStatusOutput(os.Stdout, "", false, false)
+ output := terminal.NewStatusOutput(os.Stdout, "", false, false, false)
log := logger.New(output)
defer log.Cleanup()
diff --git a/ui/terminal/simple_status.go b/ui/terminal/simple_status.go
index 4e8c56804..936b275a1 100644
--- a/ui/terminal/simple_status.go
+++ b/ui/terminal/simple_status.go
@@ -24,15 +24,17 @@ import (
type simpleStatusOutput struct {
writer io.Writer
formatter formatter
+ keepANSI bool
}
// NewSimpleStatusOutput returns a StatusOutput that represents the
// current build status similarly to Ninja's built-in terminal
// output.
-func NewSimpleStatusOutput(w io.Writer, formatter formatter) status.StatusOutput {
+func NewSimpleStatusOutput(w io.Writer, formatter formatter, keepANSI bool) status.StatusOutput {
return &simpleStatusOutput{
writer: w,
formatter: formatter,
+ keepANSI: keepANSI,
}
}
@@ -54,7 +56,9 @@ func (s *simpleStatusOutput) FinishAction(result status.ActionResult, counts sta
progress := s.formatter.progress(counts) + str
output := s.formatter.result(result)
- output = string(stripAnsiEscapes([]byte(output)))
+ if !s.keepANSI {
+ output = string(stripAnsiEscapes([]byte(output)))
+ }
if output != "" {
fmt.Fprint(s.writer, progress, "\n", output)
diff --git a/ui/terminal/smart_status.go b/ui/terminal/smart_status.go
index 6bdf14074..06a4064ff 100644
--- a/ui/terminal/smart_status.go
+++ b/ui/terminal/smart_status.go
@@ -77,7 +77,12 @@ func NewSmartStatusOutput(w io.Writer, formatter formatter) status.StatusOutput
s.requestedTableHeight = h
}
- s.updateTermSize()
+ if w, h, ok := termSize(s.writer); ok {
+ s.termWidth, s.termHeight = w, h
+ s.computeTableHeight()
+ } else {
+ s.tableMode = false
+ }
if s.tableMode {
// Add empty lines at the bottom of the screen to scroll back the existing history
@@ -296,40 +301,44 @@ func (s *smartStatusOutput) stopSigwinch() {
close(s.sigwinch)
}
+// computeTableHeight recomputes s.tableHeight based on s.termHeight and s.requestedTableHeight.
+func (s *smartStatusOutput) computeTableHeight() {
+ tableHeight := s.requestedTableHeight
+ if tableHeight == 0 {
+ tableHeight = s.termHeight / 4
+ if tableHeight < 1 {
+ tableHeight = 1
+ } else if tableHeight > 10 {
+ tableHeight = 10
+ }
+ }
+ if tableHeight > s.termHeight-1 {
+ tableHeight = s.termHeight - 1
+ }
+ s.tableHeight = tableHeight
+}
+
+// updateTermSize recomputes the table height after a SIGWINCH and pans any existing text if
+// necessary.
func (s *smartStatusOutput) updateTermSize() {
if w, h, ok := termSize(s.writer); ok {
- firstUpdate := s.termHeight == 0 && s.termWidth == 0
oldScrollingHeight := s.termHeight - s.tableHeight
s.termWidth, s.termHeight = w, h
if s.tableMode {
- tableHeight := s.requestedTableHeight
- if tableHeight == 0 {
- tableHeight = s.termHeight / 4
- if tableHeight < 1 {
- tableHeight = 1
- } else if tableHeight > 10 {
- tableHeight = 10
- }
- }
- if tableHeight > s.termHeight-1 {
- tableHeight = s.termHeight - 1
- }
- s.tableHeight = tableHeight
+ s.computeTableHeight()
scrollingHeight := s.termHeight - s.tableHeight
- if !firstUpdate {
- // If the scrolling region has changed, attempt to pan the existing text so that it is
- // not overwritten by the table.
- if scrollingHeight < oldScrollingHeight {
- pan := oldScrollingHeight - scrollingHeight
- if pan > s.tableHeight {
- pan = s.tableHeight
- }
- fmt.Fprint(s.writer, ansi.panDown(pan))
+ // If the scrolling region has changed, attempt to pan the existing text so that it is
+ // not overwritten by the table.
+ if scrollingHeight < oldScrollingHeight {
+ pan := oldScrollingHeight - scrollingHeight
+ if pan > s.tableHeight {
+ pan = s.tableHeight
}
+ fmt.Fprint(s.writer, ansi.panDown(pan))
}
}
}
diff --git a/ui/terminal/status.go b/ui/terminal/status.go
index d8e739211..2ad174fee 100644
--- a/ui/terminal/status.go
+++ b/ui/terminal/status.go
@@ -26,12 +26,12 @@ import (
//
// statusFormat takes nearly all the same options as NINJA_STATUS.
// %c is currently unsupported.
-func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild bool) status.StatusOutput {
+func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild, forceKeepANSI bool) status.StatusOutput {
formatter := newFormatter(statusFormat, quietBuild)
if !forceSimpleOutput && isSmartTerminal(w) {
return NewSmartStatusOutput(w, formatter)
} else {
- return NewSimpleStatusOutput(w, formatter)
+ return NewSimpleStatusOutput(w, formatter, forceKeepANSI)
}
}
diff --git a/ui/terminal/status_test.go b/ui/terminal/status_test.go
index aa69dff53..810e31d1b 100644
--- a/ui/terminal/status_test.go
+++ b/ui/terminal/status_test.go
@@ -94,7 +94,7 @@ func TestStatusOutput(t *testing.T) {
t.Run("smart", func(t *testing.T) {
smart := &fakeSmartTerminal{termWidth: 40}
- stat := NewStatusOutput(smart, "", false, false)
+ stat := NewStatusOutput(smart, "", false, false, false)
tt.calls(stat)
stat.Flush()
@@ -105,7 +105,7 @@ func TestStatusOutput(t *testing.T) {
t.Run("simple", func(t *testing.T) {
simple := &bytes.Buffer{}
- stat := NewStatusOutput(simple, "", false, false)
+ stat := NewStatusOutput(simple, "", false, false, false)
tt.calls(stat)
stat.Flush()
@@ -116,7 +116,7 @@ func TestStatusOutput(t *testing.T) {
t.Run("force simple", func(t *testing.T) {
smart := &fakeSmartTerminal{termWidth: 40}
- stat := NewStatusOutput(smart, "", true, false)
+ stat := NewStatusOutput(smart, "", true, false, false)
tt.calls(stat)
stat.Flush()
@@ -269,7 +269,7 @@ func TestSmartStatusOutputWidthChange(t *testing.T) {
os.Setenv(tableHeightEnVar, "")
smart := &fakeSmartTerminal{termWidth: 40}
- stat := NewStatusOutput(smart, "", false, false)
+ stat := NewStatusOutput(smart, "", false, false, false)
smartStat := stat.(*smartStatusOutput)
smartStat.sigwinchHandled = make(chan bool)