f99631b12c
After, what, five years? I finally got tired of reading pipe-separated machine-readable fields in analyzer test failures. This parses that and prints the failures in a sorted, human-friendly form. Change-Id: I1e7761bff8d1ffaf1734d065ddaa1e624e4509d9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147683 Commit-Queue: Bob Nystrom <rnystrom@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
100 lines
2.9 KiB
Dart
100 lines
2.9 KiB
Dart
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:io';
|
|
|
|
// TODO(rnystrom): Move all print calls to go through this. Unify with DebugLog.
|
|
/// Interface for the test runner printing output to the user.
|
|
///
|
|
/// It mainly exists to gracefully handle the inline progress indicator:
|
|
///
|
|
/// [00:08 | 100% | + 139 | - 3]
|
|
///
|
|
/// That does not print a newline at the end, but subsequent output should
|
|
/// insert the newline before writing itself. This tracks whether that needs to
|
|
/// be done.
|
|
class Terminal {
|
|
static bool _needsNewline = false;
|
|
|
|
/// Prints [obj] to its own line.
|
|
///
|
|
/// If this is called after a call to [writeLine], prints a newline first to
|
|
/// end that earlier line.
|
|
static void print(Object obj) {
|
|
finishLine();
|
|
stdout.writeln(obj);
|
|
}
|
|
|
|
/// Overwrites the current line with [obj].
|
|
///
|
|
/// Does not output a newline at the end.
|
|
static void writeLine(Object obj) {
|
|
stdout.write('\r$obj');
|
|
_needsNewline = true;
|
|
}
|
|
|
|
/// If the last output was from [writeLine], finishes it by writing a newline.
|
|
static void finishLine() {
|
|
if (_needsNewline) stdout.writeln();
|
|
_needsNewline = false;
|
|
}
|
|
}
|
|
|
|
/// The maximum line length for output.
|
|
///
|
|
/// If the test runner isn't attached to a terminal, defaults to 80 columns.
|
|
final int _lineLength = () {
|
|
try {
|
|
return stdout.terminalColumns;
|
|
} on StdoutException {
|
|
return 80;
|
|
}
|
|
}();
|
|
|
|
/// Wraps [text] so that it fits within [_lineLength], if there is a line length.
|
|
///
|
|
/// This preserves existing newlines and only splits words on spaces, not on
|
|
/// other sorts of whitespace or separators.
|
|
///
|
|
/// If [prefix] is passed, it's added at the beginning of any wrapped lines.
|
|
String wordWrap(String text, {String prefix}) {
|
|
prefix ??= '';
|
|
|
|
var buffer = StringBuffer();
|
|
var originalLines = text.split('\n');
|
|
var lengthSoFar = 0;
|
|
var needsNewline = false;
|
|
var needsSpace = false;
|
|
|
|
for (var i = 0; i < originalLines.length; i++) {
|
|
var originalLine = originalLines[i];
|
|
for (var word in originalLine.split(' ')) {
|
|
// If this word would push us over, split before it.
|
|
if (lengthSoFar + 1 + word.length > _lineLength) needsNewline = true;
|
|
|
|
if (needsNewline) {
|
|
buffer.writeln();
|
|
buffer.write(prefix);
|
|
lengthSoFar = prefix.length;
|
|
needsSpace = false;
|
|
} else if (needsSpace) {
|
|
buffer.write(' ');
|
|
lengthSoFar++;
|
|
}
|
|
|
|
buffer.write(word);
|
|
lengthSoFar += word.length;
|
|
|
|
// If the single word fills the entire line, we need to wrap after it too.
|
|
needsNewline = lengthSoFar > _lineLength;
|
|
needsSpace = !needsNewline;
|
|
}
|
|
|
|
if (needsNewline) buffer.writeln();
|
|
needsNewline = true;
|
|
}
|
|
|
|
return buffer.toString();
|
|
}
|