Stop wrapping adb, gradle and ios logger output, and update terminal wrapping column dynamically. (#23592)
Subcommand output (gradle, adb, etc) is no longer wrapped, and wrapping notices when the terminal column width changes dynamically now.
Fixes #23267.
Fixes #23266.
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index ea70f44..6b32109 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -440,7 +440,7 @@
final String result = (await runCheckedAsync(cmd)).stdout;
// This invocation returns 0 even when it fails.
if (result.contains('Error: ')) {
- printError(result.trim());
+ printError(result.trim(), wrap: false);
return LaunchResult.failed();
}
diff --git a/packages/flutter_tools/lib/src/android/apk.dart b/packages/flutter_tools/lib/src/android/apk.dart
index 5b30036..fc28d54 100644
--- a/packages/flutter_tools/lib/src/android/apk.dart
+++ b/packages/flutter_tools/lib/src/android/apk.dart
@@ -34,7 +34,9 @@
final List<String> validationResult = androidSdk.validateSdkWellFormed();
if (validationResult.isNotEmpty) {
- validationResult.forEach(printError);
+ for (String message in validationResult) {
+ printError(message, wrap: false);
+ }
throwToolExit('Try re-installing or updating your Android SDK.');
}
diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart
index 4187472..eb8d92f 100644
--- a/packages/flutter_tools/lib/src/base/logger.dart
+++ b/packages/flutter_tools/lib/src/base/logger.dart
@@ -40,6 +40,8 @@
/// If [hangingIndent] is specified, then any wrapped lines will be indented
/// by this much more than the first line, if wrapping is enabled in
/// [outputPreferences].
+ /// If [wrap] is specified, then it overrides the
+ /// [outputPreferences.wrapText] setting.
void printError(
String message, {
StackTrace stackTrace,
@@ -47,6 +49,7 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
});
/// Display normal output of the command. This should be used for things like
@@ -68,6 +71,8 @@
/// If [hangingIndent] is specified, then any wrapped lines will be indented
/// by this much more than the first line, if wrapping is enabled in
/// [outputPreferences].
+ /// If [wrap] is specified, then it overrides the
+ /// [outputPreferences.wrapText] setting.
void printStatus(
String message, {
bool emphasis,
@@ -75,6 +80,7 @@
bool newline,
int indent,
int hangingIndent,
+ bool wrap,
});
/// Use this for verbose tracing output. Users can turn this output on in order
@@ -111,9 +117,10 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
}) {
message ??= '';
- message = wrapText(message, indent: indent, hangingIndent: hangingIndent);
+ message = wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap);
_status?.cancel();
_status = null;
if (emphasis == true)
@@ -133,9 +140,10 @@
bool newline,
int indent,
int hangingIndent,
+ bool wrap,
}) {
message ??= '';
- message = wrapText(message, indent: indent, hangingIndent: hangingIndent);
+ message = wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap);
_status?.cancel();
_status = null;
if (emphasis == true)
@@ -232,9 +240,10 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
}) {
_error.writeln(terminal.color(
- wrapText(message, indent: indent, hangingIndent: hangingIndent),
+ wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap),
color ?? TerminalColor.red,
));
}
@@ -247,11 +256,12 @@
bool newline,
int indent,
int hangingIndent,
+ bool wrap,
}) {
if (newline != false)
- _status.writeln(wrapText(message, indent: indent, hangingIndent: hangingIndent));
+ _status.writeln(wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap));
else
- _status.write(wrapText(message, indent: indent, hangingIndent: hangingIndent));
+ _status.write(wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap));
}
@override
@@ -297,10 +307,11 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
}) {
_emit(
_LogType.error,
- wrapText(message, indent: indent, hangingIndent: hangingIndent),
+ wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap),
stackTrace,
);
}
@@ -313,8 +324,9 @@
bool newline,
int indent,
int hangingIndent,
+ bool wrap,
}) {
- _emit(_LogType.status, wrapText(message, indent: indent, hangingIndent: hangingIndent));
+ _emit(_LogType.status, wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap));
}
@override
diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart
index 5632752..37ef5bf 100644
--- a/packages/flutter_tools/lib/src/base/process.dart
+++ b/packages/flutter_tools/lib/src/base/process.dart
@@ -148,7 +148,7 @@
if (trace)
printTrace(message);
else
- printStatus(message);
+ printStatus(message, wrap: false);
}
});
final StreamSubscription<String> stderrSubscription = process.stderr
@@ -159,7 +159,7 @@
if (mapFunction != null)
line = mapFunction(line);
if (line != null)
- printError('$prefix$line');
+ printError('$prefix$line', wrap: false);
});
// Wait for stdout to be fully processed
diff --git a/packages/flutter_tools/lib/src/base/terminal.dart b/packages/flutter_tools/lib/src/base/terminal.dart
index bd7e349..8ad874c 100644
--- a/packages/flutter_tools/lib/src/base/terminal.dart
+++ b/packages/flutter_tools/lib/src/base/terminal.dart
@@ -45,7 +45,7 @@
int wrapColumn,
bool showColor,
}) : wrapText = wrapText ?? io.stdio?.hasTerminal ?? const io.Stdio().hasTerminal,
- wrapColumn = wrapColumn ?? io.stdio?.terminalColumns ?? const io.Stdio().terminalColumns ?? kDefaultTerminalColumns,
+ _overrideWrapColumn = wrapColumn,
showColor = showColor ?? platform.stdoutSupportsAnsi ?? false;
/// If [wrapText] is true, then any text sent to the context's [Logger]
@@ -64,8 +64,12 @@
/// To find out if we're writing to a terminal, it tries the context's stdio,
/// and if that's not set, it tries creating a new [io.Stdio] and asks it, if
/// that doesn't have an idea of the terminal width, then we just use a
- /// default of 100. It will be ignored if wrapText is false.
- final int wrapColumn;
+ /// default of 100. It will be ignored if [wrapText] is false.
+ final int _overrideWrapColumn;
+ int get wrapColumn {
+ return _overrideWrapColumn ?? io.stdio?.terminalColumns
+ ?? const io.Stdio().terminalColumns ?? kDefaultTerminalColumns;
+ }
/// Whether or not to output ANSI color codes when writing to the output
/// terminal. Defaults to whatever [platform.stdoutSupportsAnsi] says if
diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart
index b9cb836..0ed960e 100644
--- a/packages/flutter_tools/lib/src/base/utils.dart
+++ b/packages/flutter_tools/lib/src/base/utils.dart
@@ -313,7 +313,8 @@
/// Wraps a block of text into lines no longer than [columnWidth].
///
/// Tries to split at whitespace, but if that's not good enough to keep it
-/// under the limit, then it splits in the middle of a word.
+/// under the limit, then it splits in the middle of a word. If [columnWidth] is
+/// smaller than 10 columns, will wrap at 10 columns.
///
/// Preserves indentation (leading whitespace) for each line (delimited by '\n')
/// in the input, and will indent wrapped lines that same amount, adding
@@ -339,11 +340,12 @@
/// [outputPreferences.wrapColumn], which is set with the --wrap-column option.
///
/// If [outputPreferences.wrapText] is false, then the text will be returned
-/// unchanged.
+/// unchanged. If [shouldWrap] is specified, then it overrides the
+/// [outputPreferences.wrapText] setting.
///
/// The [indent] and [hangingIndent] must be smaller than [columnWidth] when
/// added together.
-String wrapText(String text, {int columnWidth, int hangingIndent, int indent}) {
+String wrapText(String text, {int columnWidth, int hangingIndent, int indent, bool shouldWrap}) {
if (text == null || text.isEmpty) {
return '';
}
@@ -366,6 +368,7 @@
final List<String> firstLineWrap = _wrapTextAsLines(
trimmedText,
columnWidth: columnWidth - leadingWhitespace.length,
+ shouldWrap: shouldWrap,
);
notIndented = <String>[firstLineWrap.removeAt(0)];
trimmedText = trimmedText.substring(notIndented[0].length).trimLeft();
@@ -373,12 +376,14 @@
notIndented.addAll(_wrapTextAsLines(
trimmedText,
columnWidth: columnWidth - leadingWhitespace.length - hangingIndent,
+ shouldWrap: shouldWrap,
));
}
} else {
notIndented = _wrapTextAsLines(
trimmedText,
columnWidth: columnWidth - leadingWhitespace.length,
+ shouldWrap: shouldWrap,
);
}
String hangingIndentString;
@@ -426,14 +431,16 @@
/// default will be [outputPreferences.wrapColumn].
///
/// If [outputPreferences.wrapText] is false, then the text will be returned
-/// simply split at the newlines, but not wrapped.
-List<String> _wrapTextAsLines(String text, {int start = 0, int columnWidth}) {
+/// simply split at the newlines, but not wrapped. If [shouldWrap] is specified,
+/// then it overrides the [outputPreferences.wrapText] setting.
+List<String> _wrapTextAsLines(String text, {int start = 0, int columnWidth, bool shouldWrap}) {
if (text == null || text.isEmpty) {
return <String>[''];
}
assert(columnWidth != null);
assert(columnWidth >= 0);
assert(start >= 0);
+ shouldWrap ??= outputPreferences.wrapText;
/// Returns true if the code unit at [index] in [text] is a whitespace
/// character.
@@ -495,7 +502,7 @@
for (String line in text.split('\n')) {
// If the line is short enough, even with ANSI codes, then we can just add
// add it and move on.
- if (line.length <= effectiveLength || !outputPreferences.wrapText) {
+ if (line.length <= effectiveLength || !shouldWrap) {
result.add(line);
continue;
}
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart
index 203315e..f8799ae 100644
--- a/packages/flutter_tools/lib/src/commands/daemon.dart
+++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -758,6 +758,7 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
}) {
_messageController.add(LogMessage('error', message, stackTrace));
}
@@ -770,6 +771,7 @@
bool newline = true,
int indent,
int hangingIndent,
+ bool wrap,
}) {
_messageController.add(LogMessage('status', message));
}
@@ -892,6 +894,7 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
}) {
if (parent != null) {
parent.printError(
@@ -900,6 +903,7 @@
emphasis: emphasis,
indent: indent,
hangingIndent: hangingIndent,
+ wrap: wrap,
);
} else {
if (stackTrace != null) {
@@ -925,6 +929,7 @@
bool newline = true,
int indent,
int hangingIndent,
+ bool wrap,
}) {
if (parent != null) {
parent.printStatus(
@@ -934,6 +939,7 @@
newline: newline,
indent: indent,
hangingIndent: hangingIndent,
+ wrap: wrap,
);
} else {
_sendLogEvent(<String, dynamic>{'log': message});
diff --git a/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart b/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
index c8cc995..7dc1a88 100644
--- a/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
+++ b/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
@@ -540,7 +540,7 @@
printTrace(args.join(' '));
final ProcessResult result = await processManager.run(args);
if (result.exitCode != 0) {
- printStatus('Command failed: $command\nstdout: ${result.stdout}\nstderr: ${result.stderr}');
+ printStatus('Command failed: $command\nstdout: ${result.stdout}\nstderr: ${result.stderr}', wrap: false);
return null;
}
printTrace(result.stdout);
diff --git a/packages/flutter_tools/lib/src/commands/logs.dart b/packages/flutter_tools/lib/src/commands/logs.dart
index de8283f..77759f6 100644
--- a/packages/flutter_tools/lib/src/commands/logs.dart
+++ b/packages/flutter_tools/lib/src/commands/logs.dart
@@ -51,7 +51,7 @@
// Start reading.
final StreamSubscription<String> subscription = logReader.logLines.listen(
- printStatus,
+ (String message) => printStatus(message, wrap: false),
onDone: () {
exitCompleter.complete(0);
},
diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart
index 6c5f69d..7df36b3 100644
--- a/packages/flutter_tools/lib/src/commands/update_packages.dart
+++ b/packages/flutter_tools/lib/src/commands/update_packages.dart
@@ -342,7 +342,7 @@
if (path != null)
buf.write(' <- ');
}
- printStatus(buf.toString());
+ printStatus(buf.toString(), wrap: false);
}
if (paths.isEmpty) {
diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart
index d032326..4c3f6b8 100644
--- a/packages/flutter_tools/lib/src/globals.dart
+++ b/packages/flutter_tools/lib/src/globals.dart
@@ -27,6 +27,7 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
}) {
logger.printError(
message,
@@ -35,6 +36,7 @@
color: color,
indent: indent,
hangingIndent: hangingIndent,
+ wrap: wrap,
);
}
@@ -54,6 +56,7 @@
TerminalColor color,
int indent,
int hangingIndent,
+ bool wrap,
}) {
logger.printStatus(
message,
@@ -62,6 +65,7 @@
newline: newline ?? true,
indent: indent,
hangingIndent: hangingIndent,
+ wrap: wrap,
);
}
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 9333feb..f7630d2 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -240,7 +240,7 @@
return;
_loggingSubscription = device.getLogReader(app: package).logLines.listen((String line) {
if (!line.contains('Observatory listening on http'))
- printStatus(line);
+ printStatus(line, wrap: false);
});
}
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index 1601610..d6369a0 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -253,9 +253,11 @@
contextOverrides[Logger] = VerboseLogger(logger);
}
- final int terminalColumns = io.stdio.terminalColumns;
- int wrapColumn = terminalColumns ?? kDefaultTerminalColumns;
- if (topLevelResults['wrap-column'] != null) {
+ // Don't set wrapColumns unless the user said to: if it's set, then all
+ // wrapping will occur at this width explicitly, and won't adapt if the
+ // terminal size changes during a run.
+ int wrapColumn;
+ if (topLevelResults.wasParsed('wrap-column')) {
try {
wrapColumn = int.parse(topLevelResults['wrap-column']);
if (wrapColumn < 0) {
@@ -272,7 +274,7 @@
// anything, unless the user explicitly said to.
final bool useWrapping = topLevelResults.wasParsed('wrap')
? topLevelResults['wrap']
- : terminalColumns == null ? false : topLevelResults['wrap'];
+ : io.stdio.terminalColumns == null ? false : topLevelResults['wrap'];
contextOverrides[OutputPreferences] = OutputPreferences(
wrapText: useWrapping,
showColor: topLevelResults['color'],