aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/util
diff options
context:
space:
mode:
authorGravatar Klaus Aehlig <aehlig@google.com>2016-02-29 09:53:48 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2016-02-29 17:39:54 +0000
commitb47288152eef10d39744fd633e43e3722d910b12 (patch)
tree7839a980cea6aa5bf6557f1b09dfaf038c5631d3 /src/main/java/com/google/devtools/build/lib/util
parentdb7a8163e47bd66cd0817981dde3ab215aa51b7b (diff)
Add wrapper class around AnsiTerminalWriter that breaks lines
In order to update Bazel's progress bar, the old one has to be removed first; this requires knowledge about the number of lines it currently uses. For small terminals, this requires us to take line breaks into account. While this normally works well, there are situations where our believe about the terminal width is smaller that the actual width of the terminal, causing the deletion of too many lines. This wrapper class provides a solution for this case by explicitly breaking lines at the given width. -- Change-Id: I9d33e389730568ab8c15ee082594de9b35abb71c Reviewed-on: https://bazel-review.googlesource.com/#/c/3023 MOS_MIGRATED_REVID=115827354
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/util')
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/io/LineWrappingAnsiTerminalWriter.java93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/io/LineWrappingAnsiTerminalWriter.java b/src/main/java/com/google/devtools/build/lib/util/io/LineWrappingAnsiTerminalWriter.java
new file mode 100644
index 0000000000..66c6d3b4c2
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/util/io/LineWrappingAnsiTerminalWriter.java
@@ -0,0 +1,93 @@
+// Copyright 2016 The Bazel Authors. 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 com.google.devtools.build.lib.util.io;
+
+import java.io.IOException;
+
+/**
+ * Wrap an {@link AnsiTerminalWriter} into one that breaks lines to use
+ * at most a first given number of columns of the terminal. In this way,
+ * all line breaks are predictable, even if we only have a lower bound
+ * on the number of columns of the underlying terminal. To simplify copy
+ * and paste of the terminal output, a continuation character is written
+ * into the last usable column when we break a line. Additionally, newline
+ * characters are translated into calls to the {@link AnsiTerminalWriter#newline()}
+ * method.
+ */
+public class LineWrappingAnsiTerminalWriter implements AnsiTerminalWriter {
+
+ private final AnsiTerminalWriter terminalWriter;
+ private final int width;
+ private final char continuationCharacter;
+ private int position;
+
+ public LineWrappingAnsiTerminalWriter(
+ AnsiTerminalWriter terminalWriter, int width, char continuationCharacter) {
+ this.terminalWriter = terminalWriter;
+ this.width = width;
+ this.continuationCharacter = continuationCharacter;
+ this.position = 0;
+ }
+
+ public LineWrappingAnsiTerminalWriter(AnsiTerminalWriter terminalWriter, int width) {
+ this(terminalWriter, width, '\\');
+ }
+
+ private void appendChar(char c) throws IOException {
+ if (c == '\n') {
+ terminalWriter.newline();
+ position = 0;
+ } else if (position + 2 < width) {
+ terminalWriter.append(Character.toString(c));
+ position++;
+ } else {
+ terminalWriter.append(new String(new char[] {c, continuationCharacter}));
+ terminalWriter.newline();
+ position = 0;
+ }
+ }
+
+ @Override
+ public AnsiTerminalWriter append(String text) throws IOException {
+ for (int i = 0; i < text.length(); i++) {
+ appendChar(text.charAt(i));
+ }
+ return this;
+ }
+
+ @Override
+ public AnsiTerminalWriter newline() throws IOException {
+ terminalWriter.newline();
+ position = 0;
+ return this;
+ }
+
+ @Override
+ public AnsiTerminalWriter okStatus() throws IOException {
+ terminalWriter.okStatus();
+ return this;
+ }
+
+ @Override
+ public AnsiTerminalWriter failStatus() throws IOException {
+ terminalWriter.failStatus();
+ return this;
+ }
+
+ @Override
+ public AnsiTerminalWriter normal() throws IOException {
+ terminalWriter.normal();
+ return this;
+ }
+}