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'],