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
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 330c5dd..c976dcb 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -156,10 +156,9 @@
 }
 
 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 @@
 
 	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 @@
 		Context: ctx,
 		Logger:  log,
 		Tracer:  trace,
-		Writer:  writer,
+		Writer:  stdio.Stdout(),
 		Status:  stat,
 	}}
 
@@ -341,7 +340,7 @@
 	} else if failures > 1 {
 		log.Fatalf("%d failures", failures)
 	} else {
-		writer.Print("Success")
+		fmt.Fprintln(stdio.Stdout(), "Success")
 	}
 }
 
@@ -386,7 +385,7 @@
 		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 5f9bd01..58d8d34 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -109,10 +109,7 @@
 		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 @@
 
 	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 @@
 		Logger:  log,
 		Metrics: met,
 		Tracer:  trace,
-		Writer:  writer,
+		Writer:  c.stdio().Stdout(),
 		Status:  stat,
 	}}
 
@@ -312,13 +309,13 @@
 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 242e3af..1d23fec 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -22,14 +22,13 @@
 	"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 249e898..7ff98ef 100644
--- a/ui/build/context.go
+++ b/ui/build/context.go
@@ -16,12 +16,12 @@
 
 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 @@
 
 	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 4335667..266130f 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -249,7 +249,7 @@
 	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 683e3e3..b533b0d 100644
--- a/ui/terminal/Android.bp
+++ b/ui/terminal/Android.bp
@@ -21,7 +21,7 @@
         "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 f2fcba7..08ef373 100644
--- a/ui/terminal/dumb_status.go
+++ b/ui/terminal/dumb_status.go
@@ -16,19 +16,20 @@
 
 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 5edc21a..a52fdc2 100644
--- a/ui/terminal/smart_status.go
+++ b/ui/terminal/smart_status.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"io"
 	"strings"
 	"sync"
 
@@ -23,7 +24,7 @@
 )
 
 type smartStatusOutput struct {
-	writer    Writer
+	writer    io.Writer
 	formatter formatter
 
 	lock sync.Mutex
@@ -34,7 +35,7 @@
 // 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 @@
 	// 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 481c511..69a2a09 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 @@
 //
 // 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 e032c1f..c81e837 100644
--- a/ui/terminal/status_test.go
+++ b/ui/terminal/status_test.go
@@ -89,17 +89,9 @@
 		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 @@
 
 			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 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 @@
 	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 0000000..dec2963
--- /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 26e0e34..0000000
--- 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{}