Move all output through StatusOutput

Write log output through StatusOutput so that the status implementation
can synchronize it with its own output.

Test: status_test.go
Change-Id: I917bdeeea4759a12b6b4aa6d6d86ee18a2771723
diff --git a/ui/status/log.go b/ui/status/log.go
index 921aa44..7badac7 100644
--- a/ui/status/log.go
+++ b/ui/status/log.go
@@ -71,6 +71,11 @@
 	fmt.Fprintf(v.w, "%s%s\n", level.Prefix(), message)
 }
 
+func (v *verboseLog) Write(p []byte) (int, error) {
+	fmt.Fprint(v.w, string(p))
+	return len(p), nil
+}
+
 type errorLog struct {
 	w io.WriteCloser
 
@@ -134,3 +139,8 @@
 
 	fmt.Fprintf(e.w, "error: %s\n", message)
 }
+
+func (e *errorLog) Write(p []byte) (int, error) {
+	fmt.Fprint(e.w, string(p))
+	return len(p), nil
+}
diff --git a/ui/status/status.go b/ui/status/status.go
index 46ec72e..3d8cd7a 100644
--- a/ui/status/status.go
+++ b/ui/status/status.go
@@ -173,6 +173,9 @@
 	// Flush is called when your outputs should be flushed / closed. No
 	// output is expected after this call.
 	Flush()
+
+	// Write lets StatusOutput implement io.Writer
+	Write(p []byte) (n int, err error)
 }
 
 // Status is the multiplexer / accumulator between ToolStatus instances (via
diff --git a/ui/status/status_test.go b/ui/status/status_test.go
index e62785f..9494582 100644
--- a/ui/status/status_test.go
+++ b/ui/status/status_test.go
@@ -27,6 +27,11 @@
 func (c counterOutput) Message(level MsgLevel, msg string) {}
 func (c counterOutput) Flush()                             {}
 
+func (c counterOutput) Write(p []byte) (int, error) {
+	// Discard writes
+	return len(p), nil
+}
+
 func (c counterOutput) Expect(t *testing.T, counts Counts) {
 	if Counts(c) == counts {
 		return
diff --git a/ui/terminal/dumb_status.go b/ui/terminal/dumb_status.go
index 08ef373..201770f 100644
--- a/ui/terminal/dumb_status.go
+++ b/ui/terminal/dumb_status.go
@@ -64,3 +64,8 @@
 }
 
 func (s *dumbStatusOutput) Flush() {}
+
+func (s *dumbStatusOutput) Write(p []byte) (int, error) {
+	fmt.Fprint(s.writer, string(p))
+	return len(p), nil
+}
diff --git a/ui/terminal/smart_status.go b/ui/terminal/smart_status.go
index a52fdc2..9a4931c 100644
--- a/ui/terminal/smart_status.go
+++ b/ui/terminal/smart_status.go
@@ -104,6 +104,13 @@
 	s.requestLine()
 }
 
+func (s *smartStatusOutput) Write(p []byte) (int, error) {
+	s.lock.Lock()
+	defer s.lock.Unlock()
+	s.print(string(p))
+	return len(p), nil
+}
+
 func (s *smartStatusOutput) requestLine() {
 	if !s.haveBlankLine {
 		fmt.Fprintln(s.writer)
diff --git a/ui/tracer/status.go b/ui/tracer/status.go
index af50e2d..c831255 100644
--- a/ui/tracer/status.go
+++ b/ui/tracer/status.go
@@ -85,3 +85,8 @@
 
 func (s *statusOutput) Flush()                                        {}
 func (s *statusOutput) Message(level status.MsgLevel, message string) {}
+
+func (s *statusOutput) Write(p []byte) (int, error) {
+	// Discard writes
+	return len(p), nil
+}