experimentalUI: agressively buffer

To update the progress bar, we first have to remove it and then write the
new one. For this to look smooth, the control sequence removing the old progress
bar and the characters of the new progress bar have to arrive "in one go" at the
(actual) terminal. As AnsiTerminal sends each control sequence as a separate write
to the underlying stream, we have to buffer the underlying stream. Therefore,
if the experimental UI is used, buffer that stream unconditionally until flushed,
and not by line. For the experimental UI this is save, as it flushes the stream
appropriately.

For the old UI, we keep the line buffering, as the old UI relies on an implicit flush
whenever a new-line character is written.

Change-Id: I3a914e4b93ce17c3de05df0d860cf98849c3b4a1
PiperOrigin-RevId: 161935218
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
index fc84ebd..cbd8e56 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java
@@ -55,6 +55,7 @@
 import com.google.devtools.common.options.OptionsParser;
 import com.google.devtools.common.options.OptionsParsingException;
 import com.google.devtools.common.options.OptionsProvider;
+import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
@@ -428,11 +429,11 @@
     }
 
     if (!commandAnnotation.binaryStdOut()) {
-      outErr = lineBufferOut(outErr);
+      outErr = bufferOut(outErr, eventHandlerOptions.experimentalUi);
     }
 
     if (!commandAnnotation.binaryStdErr()) {
-      outErr = lineBufferErr(outErr);
+      outErr = bufferErr(outErr, eventHandlerOptions.experimentalUi);
     }
 
     CommonCommandOptions commonOptions = options.getOptions(CommonCommandOptions.class);
@@ -723,13 +724,23 @@
     accumulator.add(commandAnnotation.name());
   }
 
-  private OutErr lineBufferOut(OutErr outErr) {
-    OutputStream wrappedOut = new LineBufferedOutputStream(outErr.getOutputStream());
+  private OutErr bufferOut(OutErr outErr, boolean fully) {
+    OutputStream wrappedOut;
+    if (fully) {
+      wrappedOut = new BufferedOutputStream(outErr.getOutputStream());
+    } else {
+      wrappedOut = new LineBufferedOutputStream(outErr.getOutputStream());
+    }
     return OutErr.create(wrappedOut, outErr.getErrorStream());
   }
 
-  private OutErr lineBufferErr(OutErr outErr) {
-    OutputStream wrappedErr = new LineBufferedOutputStream(outErr.getErrorStream());
+  private OutErr bufferErr(OutErr outErr, boolean fully) {
+    OutputStream wrappedErr;
+    if (fully) {
+      wrappedErr = new BufferedOutputStream(outErr.getErrorStream());
+    } else {
+      wrappedErr = new LineBufferedOutputStream(outErr.getErrorStream());
+    }
     return OutErr.create(outErr.getOutputStream(), wrappedErr);
   }
 
@@ -902,4 +913,4 @@
     closeSilently(logOutputStream);
     logOutputStream = null;
   }
-}
\ No newline at end of file
+}