TBR vkube_v23_test: restore PrefixLineWriter

Undoes v.io/c/18813 now that gosh prevent concurrent
writes to a writer passed to both AddStdoutWriter and
AddStderrWriter.

Change-Id: I910b3e49478d2138400e9503ee112f1f044090bc
diff --git a/services/cluster/vkube/vkube_v23_test.go b/services/cluster/vkube/vkube_v23_test.go
index 9dec1fb..4da6460 100644
--- a/services/cluster/vkube/vkube_v23_test.go
+++ b/services/cluster/vkube/vkube_v23_test.go
@@ -5,7 +5,6 @@
 package main_test
 
 import (
-	"bytes"
 	"flag"
 	"fmt"
 	"io/ioutil"
@@ -14,10 +13,11 @@
 	"os/exec"
 	"path/filepath"
 	"strings"
-	"sync"
 	"testing"
 	"text/template"
 
+	"v.io/x/lib/gosh"
+	"v.io/x/lib/textutil"
 	"v.io/x/ref/lib/v23test"
 	"v.io/x/ref/test/testutil"
 )
@@ -65,16 +65,17 @@
 				// Note, creds do not affect non-Vanadium commands.
 				c := sh.Cmd(name, args...).WithCredentials(creds)
 				c.ExitErrorIsOk = true
-				w := &writer{name: filepath.Base(name)}
-				c.AddStdoutWriter(w)
-				c.AddStderrWriter(w)
-				c.Run()
+				plw := textutil.PrefixLineWriter(os.Stdout, filepath.Base(name)+"> ")
+				c.AddStdoutWriter(gosh.NopWriteCloser(plw))
+				c.AddStderrWriter(gosh.NopWriteCloser(plw))
+				output := c.CombinedOutput()
+				plw.Flush()
 				if expectSuccess && c.Err != nil {
 					t.Error(testutil.FormatLogLine(2, "Unexpected failure: %s %s :%v", name, strings.Join(args, " "), c.Err))
 				} else if !expectSuccess && c.Err == nil {
 					t.Error(testutil.FormatLogLine(2, "Unexpected success %d: %s %s", name, strings.Join(args, " ")))
 				}
-				return w.output()
+				return output
 			}
 		}
 		gsutil      = cmd("gsutil", true)
@@ -261,51 +262,6 @@
 }`)).Execute(f, params)
 }
 
-// writer is an io.Writer that sends everything to stdout, each line prefixed
-// with "name> ".
-type writer struct {
-	sync.Mutex
-	name string
-	line bytes.Buffer
-	out  bytes.Buffer
-}
-
-func (w *writer) Write(p []byte) (n int, err error) {
-	w.Lock()
-	defer w.Unlock()
-	n = len(p)
-	w.out.Write(p)
-	for len(p) > 0 {
-		if w.line.Len() == 0 {
-			fmt.Fprintf(&w.line, "%s> ", w.name)
-		}
-		if off := bytes.IndexByte(p, '\n'); off != -1 {
-			off += 1
-			w.line.Write(p[:off])
-			w.line.WriteTo(os.Stdout)
-			p = p[off:]
-			continue
-		}
-		w.line.Write(p)
-		break
-	}
-	return
-}
-
-func (w *writer) Close() error {
-	return nil
-}
-
-func (w *writer) output() string {
-	w.Lock()
-	defer w.Unlock()
-	if w.line.Len() != 0 {
-		w.line.WriteString(" [no \\n at EOL]\n")
-		w.line.WriteTo(os.Stdout)
-	}
-	return w.out.String()
-}
-
 func TestMain(m *testing.M) {
 	os.Exit(v23test.Run(m.Run))
 }