diff options
author | Colin Cross <ccross@android.com> | 2019-06-08 21:48:58 -0700 |
---|---|---|
committer | Luca Stefani <luca.stefani.ge1@gmail.com> | 2019-09-04 15:14:54 +0200 |
commit | e047b1f5db66bcebc00d14e5cba982b300adc17e (patch) | |
tree | 864f8bbae66bf333f39d83a2f23cf0472777f64e | |
parent | 90f1662aa6e57185a4175d07a826a71e067cb1cf (diff) | |
download | build_soong-e047b1f5db66bcebc00d14e5cba982b300adc17e.tar.gz build_soong-e047b1f5db66bcebc00d14e5cba982b300adc17e.tar.bz2 build_soong-e047b1f5db66bcebc00d14e5cba982b300adc17e.zip |
Remove terminal.Writer
terminal.Writer is now just a wrapper around stdio.Stdout() without
any useful functionality. Replace it with stdio.Stdout() as an
io.Writer.
Test: ui/terminal/status_test.go
Change-Id: I5bc5476afdca950b505642f0135a3af9d37fbe24
-rw-r--r-- | cmd/multiproduct_kati/main.go | 13 | ||||
-rw-r--r-- | cmd/soong_ui/main.go | 23 | ||||
-rw-r--r-- | ui/build/config_test.go | 3 | ||||
-rw-r--r-- | ui/build/context.go | 4 | ||||
-rw-r--r-- | ui/build/dumpvars.go | 2 | ||||
-rw-r--r-- | ui/terminal/Android.bp | 2 | ||||
-rw-r--r-- | ui/terminal/dumb_status.go | 5 | ||||
-rw-r--r-- | ui/terminal/smart_status.go | 7 | ||||
-rw-r--r-- | ui/terminal/status.go | 6 | ||||
-rw-r--r-- | ui/terminal/status_test.go | 31 | ||||
-rw-r--r-- | ui/terminal/stdio.go | 55 | ||||
-rw-r--r-- | ui/terminal/writer.go | 122 |
12 files changed, 90 insertions, 183 deletions
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go index 330c5dd2..c976dcb4 100644 --- a/cmd/multiproduct_kati/main.go +++ b/cmd/multiproduct_kati/main.go @@ -156,10 +156,9 @@ type mpContext struct { } func main() { - writer := terminal.NewWriter(terminal.StdioImpl{}) - defer writer.Finish() + stdio := terminal.StdioImpl{} - log := logger.New(writer) + log := logger.New(stdio.Stdout()) defer log.Cleanup() flag.Parse() @@ -172,7 +171,7 @@ func main() { stat := &status.Status{} defer stat.Finish() - stat.AddOutput(terminal.NewStatusOutput(writer, "", + stat.AddOutput(terminal.NewStatusOutput(stdio.Stdout(), "", build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"))) var failures failureCount @@ -188,7 +187,7 @@ func main() { Context: ctx, Logger: log, Tracer: trace, - Writer: writer, + Writer: stdio.Stdout(), Status: stat, }} @@ -341,7 +340,7 @@ func main() { } else if failures > 1 { log.Fatalf("%d failures", failures) } else { - writer.Print("Success") + fmt.Fprintln(stdio.Stdout(), "Success") } } @@ -386,7 +385,7 @@ func buildProduct(mpctx *mpContext, product string) { Context: mpctx.Context, Logger: log, Tracer: mpctx.Tracer, - Writer: terminal.NewWriter(terminal.NewCustomStdio(nil, f, f)), + Writer: f, Thread: mpctx.Tracer.NewThread(product), Status: &status.Status{}, }} diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go index 4500eb15..695a4260 100644 --- a/cmd/soong_ui/main.go +++ b/cmd/soong_ui/main.go @@ -109,10 +109,7 @@ func main() { os.Exit(1) } - writer := terminal.NewWriter(c.stdio()) - defer writer.Finish() - - log := logger.New(writer) + log := logger.New(c.stdio().Stdout()) defer log.Cleanup() ctx, cancel := context.WithCancel(context.Background()) @@ -125,7 +122,7 @@ func main() { stat := &status.Status{} defer stat.Finish() - stat.AddOutput(terminal.NewStatusOutput(writer, os.Getenv("NINJA_STATUS"), + stat.AddOutput(terminal.NewStatusOutput(c.stdio().Stdout(), os.Getenv("NINJA_STATUS"), build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"))) stat.AddOutput(trace.StatusTracer()) @@ -140,7 +137,7 @@ func main() { Logger: log, Metrics: met, Tracer: trace, - Writer: writer, + Writer: c.stdio().Stdout(), Status: stat, }} @@ -331,13 +328,13 @@ func dumpVarConfig(ctx build.Context, args ...string) build.Config { func make(ctx build.Context, config build.Config, _ []string, logsDir string) { if config.IsVerbose() { writer := ctx.Writer - writer.Print("! The argument `showcommands` is no longer supported.") - writer.Print("! Instead, the verbose log is always written to a compressed file in the output dir:") - writer.Print("!") - writer.Print(fmt.Sprintf("! gzip -cd %s/verbose.log.gz | less -R", logsDir)) - writer.Print("!") - writer.Print("! Older versions are saved in verbose.log.#.gz files") - writer.Print("") + fmt.Fprintln(writer, "! The argument `showcommands` is no longer supported.") + fmt.Fprintln(writer, "! Instead, the verbose log is always written to a compressed file in the output dir:") + fmt.Fprintln(writer, "!") + fmt.Fprintf(writer, "! gzip -cd %s/verbose.log.gz | less -R\n", logsDir) + fmt.Fprintln(writer, "!") + fmt.Fprintln(writer, "! Older versions are saved in verbose.log.#.gz files") + fmt.Fprintln(writer, "") time.Sleep(5 * time.Second) } diff --git a/ui/build/config_test.go b/ui/build/config_test.go index 242e3afb..1d23fec5 100644 --- a/ui/build/config_test.go +++ b/ui/build/config_test.go @@ -22,14 +22,13 @@ import ( "testing" "android/soong/ui/logger" - "android/soong/ui/terminal" ) func testContext() Context { return Context{&ContextImpl{ Context: context.Background(), Logger: logger.New(&bytes.Buffer{}), - Writer: terminal.NewWriter(terminal.NewCustomStdio(&bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{})), + Writer: &bytes.Buffer{}, }} } diff --git a/ui/build/context.go b/ui/build/context.go index 249e8982..7ff98ef7 100644 --- a/ui/build/context.go +++ b/ui/build/context.go @@ -16,12 +16,12 @@ package build import ( "context" + "io" "android/soong/ui/logger" "android/soong/ui/metrics" "android/soong/ui/metrics/metrics_proto" "android/soong/ui/status" - "android/soong/ui/terminal" "android/soong/ui/tracer" ) @@ -35,7 +35,7 @@ type ContextImpl struct { Metrics *metrics.Metrics - Writer terminal.Writer + Writer io.Writer Status *status.Status Thread tracer.Thread diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index 3e387c1e..9c6c63cb 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -221,7 +221,7 @@ func runMakeProductConfig(ctx Context, config Config) { env := config.Environment() // Print the banner like make does if !env.IsEnvTrue("ANDROID_QUIET_BUILD") { - ctx.Writer.Print(Banner(make_vars)) + fmt.Fprintln(ctx.Writer, Banner(make_vars)) } // Populate the environment diff --git a/ui/terminal/Android.bp b/ui/terminal/Android.bp index 683e3e39..b533b0d3 100644 --- a/ui/terminal/Android.bp +++ b/ui/terminal/Android.bp @@ -21,7 +21,7 @@ bootstrap_go_package { "format.go", "smart_status.go", "status.go", - "writer.go", + "stdio.go", "util.go", ], testSrcs: [ diff --git a/ui/terminal/dumb_status.go b/ui/terminal/dumb_status.go index f2fcba79..08ef3733 100644 --- a/ui/terminal/dumb_status.go +++ b/ui/terminal/dumb_status.go @@ -16,19 +16,20 @@ package terminal import ( "fmt" + "io" "android/soong/ui/status" ) type dumbStatusOutput struct { - writer Writer + writer io.Writer formatter formatter } // NewDumbStatusOutput returns a StatusOutput that represents the // current build status similarly to Ninja's built-in terminal // output. -func NewDumbStatusOutput(w Writer, formatter formatter) status.StatusOutput { +func NewDumbStatusOutput(w io.Writer, formatter formatter) status.StatusOutput { return &dumbStatusOutput{ writer: w, formatter: formatter, diff --git a/ui/terminal/smart_status.go b/ui/terminal/smart_status.go index 5edc21a1..a52fdc2b 100644 --- a/ui/terminal/smart_status.go +++ b/ui/terminal/smart_status.go @@ -16,6 +16,7 @@ package terminal import ( "fmt" + "io" "strings" "sync" @@ -23,7 +24,7 @@ import ( ) type smartStatusOutput struct { - writer Writer + writer io.Writer formatter formatter lock sync.Mutex @@ -34,7 +35,7 @@ type smartStatusOutput struct { // NewSmartStatusOutput returns a StatusOutput that represents the // current build status similarly to Ninja's built-in terminal // output. -func NewSmartStatusOutput(w Writer, formatter formatter) status.StatusOutput { +func NewSmartStatusOutput(w io.Writer, formatter formatter) status.StatusOutput { return &smartStatusOutput{ writer: w, formatter: formatter, @@ -133,7 +134,7 @@ func (s *smartStatusOutput) statusLine(str string) { // Run this on every line in case the window has been resized while // we're printing. This could be optimized to only re-run when we get // SIGWINCH if it ever becomes too time consuming. - if max, ok := s.writer.termWidth(); ok { + if max, ok := termWidth(s.writer); ok { if len(str) > max { // TODO: Just do a max. Ninja elides the middle, but that's // more complicated and these lines aren't that important. diff --git a/ui/terminal/status.go b/ui/terminal/status.go index 481c511a..69a2a092 100644 --- a/ui/terminal/status.go +++ b/ui/terminal/status.go @@ -15,6 +15,8 @@ package terminal import ( + "io" + "android/soong/ui/status" ) @@ -24,10 +26,10 @@ import ( // // statusFormat takes nearly all the same options as NINJA_STATUS. // %c is currently unsupported. -func NewStatusOutput(w Writer, statusFormat string, quietBuild bool) status.StatusOutput { +func NewStatusOutput(w io.Writer, statusFormat string, quietBuild bool) status.StatusOutput { formatter := newFormatter(statusFormat, quietBuild) - if w.isSmartTerminal() { + if isSmartTerminal(w) { return NewSmartStatusOutput(w, formatter) } else { return NewDumbStatusOutput(w, formatter) diff --git a/ui/terminal/status_test.go b/ui/terminal/status_test.go index e032c1f1..c81e837b 100644 --- a/ui/terminal/status_test.go +++ b/ui/terminal/status_test.go @@ -89,17 +89,9 @@ func TestStatusOutput(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Run("smart", func(t *testing.T) { smart := &fakeSmartTerminal{termWidth: 40} - stdio := customStdio{ - stdin: nil, - stdout: smart, - stderr: nil, - } - - writer := NewWriter(stdio) - stat := NewStatusOutput(writer, "", false) + stat := NewStatusOutput(smart, "", false) tt.calls(stat) stat.Flush() - writer.Finish() if g, w := smart.String(), tt.smart; g != w { t.Errorf("want:\n%q\ngot:\n%q", w, g) @@ -108,17 +100,9 @@ func TestStatusOutput(t *testing.T) { t.Run("dumb", func(t *testing.T) { dumb := &bytes.Buffer{} - stdio := customStdio{ - stdin: nil, - stdout: dumb, - stderr: nil, - } - - writer := NewWriter(stdio) - stat := NewStatusOutput(writer, "", false) + stat := NewStatusOutput(dumb, "", false) tt.calls(stat) stat.Flush() - writer.Finish() if g, w := dumb.String(), tt.dumb; g != w { t.Errorf("want:\n%q\ngot:\n%q", w, g) @@ -267,15 +251,7 @@ func actionWithOuptutWithAnsiCodes(stat status.StatusOutput) { func TestSmartStatusOutputWidthChange(t *testing.T) { smart := &fakeSmartTerminal{termWidth: 40} - - stdio := customStdio{ - stdin: nil, - stdout: smart, - stderr: nil, - } - - writer := NewWriter(stdio) - stat := NewStatusOutput(writer, "", false) + stat := NewStatusOutput(smart, "", false) runner := newRunner(stat, 2) @@ -287,7 +263,6 @@ func TestSmartStatusOutputWidthChange(t *testing.T) { runner.finishAction(result) stat.Flush() - writer.Finish() w := "\r[ 0% 0/2] action with very long descrip\x1b[K\r[ 50% 1/2] action with very lo\x1b[K\n" diff --git a/ui/terminal/stdio.go b/ui/terminal/stdio.go new file mode 100644 index 00000000..dec29631 --- /dev/null +++ b/ui/terminal/stdio.go @@ -0,0 +1,55 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package terminal provides a set of interfaces that can be used to interact +// with the terminal (including falling back when the terminal is detected to +// be a redirect or other dumb terminal) +package terminal + +import ( + "io" + "os" +) + +// StdioInterface represents a set of stdin/stdout/stderr Reader/Writers +type StdioInterface interface { + Stdin() io.Reader + Stdout() io.Writer + Stderr() io.Writer +} + +// StdioImpl uses the OS stdin/stdout/stderr to implement StdioInterface +type StdioImpl struct{} + +func (StdioImpl) Stdin() io.Reader { return os.Stdin } +func (StdioImpl) Stdout() io.Writer { return os.Stdout } +func (StdioImpl) Stderr() io.Writer { return os.Stderr } + +var _ StdioInterface = StdioImpl{} + +type customStdio struct { + stdin io.Reader + stdout io.Writer + stderr io.Writer +} + +func NewCustomStdio(stdin io.Reader, stdout, stderr io.Writer) StdioInterface { + return customStdio{stdin, stdout, stderr} +} + +func (c customStdio) Stdin() io.Reader { return c.stdin } +func (c customStdio) Stdout() io.Writer { return c.stdout } +func (c customStdio) Stderr() io.Writer { return c.stderr } + +var _ StdioInterface = customStdio{} diff --git a/ui/terminal/writer.go b/ui/terminal/writer.go deleted file mode 100644 index 26e0e342..00000000 --- a/ui/terminal/writer.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2018 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package terminal provides a set of interfaces that can be used to interact -// with the terminal (including falling back when the terminal is detected to -// be a redirect or other dumb terminal) -package terminal - -import ( - "fmt" - "io" - "os" -) - -// Writer provides an interface to write temporary and permanent messages to -// the terminal. -// -// The terminal is considered to be a dumb terminal if TERM==dumb, or if a -// terminal isn't detected on stdout/stderr (generally because it's a pipe or -// file). Dumb terminals will strip out all ANSI escape sequences, including -// colors. -type Writer interface { - // Print prints the string to the terminal, overwriting any current - // status being displayed. - // - // On a dumb terminal, the status messages will be kept. - Print(str string) - - // Finish ensures that the output ends with a newline (preserving any - // current status line that is current displayed). - // - // This does nothing on dumb terminals. - Finish() - - // Write implements the io.Writer interface. This is primarily so that - // the logger can use this interface to print to stderr without - // breaking the other semantics of this interface. - // - // Try to use any of the other functions if possible. - Write(p []byte) (n int, err error) - - isSmartTerminal() bool - termWidth() (int, bool) -} - -// NewWriter creates a new Writer based on the stdio and the TERM -// environment variable. -func NewWriter(stdio StdioInterface) Writer { - w := &writerImpl{ - stdio: stdio, - } - - return w -} - -type writerImpl struct { - stdio StdioInterface -} - -func (w *writerImpl) Print(str string) { - fmt.Fprint(w.stdio.Stdout(), str) - if len(str) == 0 || str[len(str)-1] != '\n' { - fmt.Fprint(w.stdio.Stdout(), "\n") - } -} - -func (w *writerImpl) Finish() {} - -func (w *writerImpl) Write(p []byte) (n int, err error) { - return w.stdio.Stdout().Write(p) -} - -func (w *writerImpl) isSmartTerminal() bool { - return isSmartTerminal(w.stdio.Stdout()) -} - -func (w *writerImpl) termWidth() (int, bool) { - return termWidth(w.stdio.Stdout()) -} - -// StdioInterface represents a set of stdin/stdout/stderr Reader/Writers -type StdioInterface interface { - Stdin() io.Reader - Stdout() io.Writer - Stderr() io.Writer -} - -// StdioImpl uses the OS stdin/stdout/stderr to implement StdioInterface -type StdioImpl struct{} - -func (StdioImpl) Stdin() io.Reader { return os.Stdin } -func (StdioImpl) Stdout() io.Writer { return os.Stdout } -func (StdioImpl) Stderr() io.Writer { return os.Stderr } - -var _ StdioInterface = StdioImpl{} - -type customStdio struct { - stdin io.Reader - stdout io.Writer - stderr io.Writer -} - -func NewCustomStdio(stdin io.Reader, stdout, stderr io.Writer) StdioInterface { - return customStdio{stdin, stdout, stderr} -} - -func (c customStdio) Stdin() io.Reader { return c.stdin } -func (c customStdio) Stdout() io.Writer { return c.stdout } -func (c customStdio) Stderr() io.Writer { return c.stderr } - -var _ StdioInterface = customStdio{} |