Unverified Commit 72ff553a authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] migrate io, process, logger, terminal (#78816)

parent 5a21e2d8
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
/// This file serves as the single point of entry into the `dart:io` APIs /// This file serves as the single point of entry into the `dart:io` APIs
/// within Flutter tools. /// within Flutter tools.
/// ///
...@@ -140,7 +138,7 @@ bool _inUnitTest() { ...@@ -140,7 +138,7 @@ bool _inUnitTest() {
/// Sets the [exit] function to a function that throws an exception rather /// Sets the [exit] function to a function that throws an exception rather
/// than exiting the process; this is intended for testing purposes. /// than exiting the process; this is intended for testing purposes.
@visibleForTesting @visibleForTesting
void setExitFunctionForTests([ ExitFunction exitFunction ]) { void setExitFunctionForTests([ ExitFunction? exitFunction ]) {
_exitFunction = exitFunction ?? (int exitCode) { _exitFunction = exitFunction ?? (int exitCode) {
throw ProcessExit(exitCode, immediate: true); throw ProcessExit(exitCode, immediate: true);
}; };
...@@ -235,12 +233,12 @@ class Stdio { ...@@ -235,12 +233,12 @@ class Stdio {
/// dart:io. /// dart:io.
@visibleForTesting @visibleForTesting
Stdio.test({ Stdio.test({
@required io.Stdout stdout, required io.Stdout stdout,
@required io.IOSink stderr, required io.IOSink stderr,
}) : _stdoutOverride = stdout, _stderrOverride = stderr; }) : _stdoutOverride = stdout, _stderrOverride = stderr;
io.Stdout _stdoutOverride; io.Stdout? _stdoutOverride;
io.IOSink _stderrOverride; io.IOSink? _stderrOverride;
// These flags exist to remember when the done Futures on stdout and stderr // These flags exist to remember when the done Futures on stdout and stderr
// complete to avoid trying to write to a closed stream sink, which would // complete to avoid trying to write to a closed stream sink, which would
...@@ -253,34 +251,34 @@ class Stdio { ...@@ -253,34 +251,34 @@ class Stdio {
@visibleForTesting @visibleForTesting
io.Stdout get stdout { io.Stdout get stdout {
if (_stdout != null) { if (_stdout != null) {
return _stdout; return _stdout!;
} }
_stdout = _stdoutOverride ?? io.stdout; _stdout = _stdoutOverride ?? io.stdout;
_stdout.done.then( _stdout!.done.then(
(void _) { _stdoutDone = true; }, (void _) { _stdoutDone = true; },
onError: (Object err, StackTrace st) { _stdoutDone = true; }, onError: (Object err, StackTrace st) { _stdoutDone = true; },
); );
return _stdout; return _stdout!;
} }
io.Stdout _stdout; io.Stdout? _stdout;
@visibleForTesting @visibleForTesting
io.IOSink get stderr { io.IOSink get stderr {
if (_stderr != null) { if (_stderr != null) {
return _stderr; return _stderr!;
} }
_stderr = _stderrOverride ?? io.stderr; _stderr = _stderrOverride ?? io.stderr;
_stderr.done.then( _stderr!.done.then(
(void _) { _stderrDone = true; }, (void _) { _stderrDone = true; },
onError: (Object err, StackTrace st) { _stderrDone = true; }, onError: (Object err, StackTrace st) { _stderrDone = true; },
); );
return _stderr; return _stderr!;
} }
io.IOSink _stderr; io.IOSink? _stderr;
bool get hasTerminal => io.stdout.hasTerminal; bool get hasTerminal => io.stdout.hasTerminal;
static bool _stdinHasTerminal; static bool? _stdinHasTerminal;
/// Determines whether there is a terminal attached. /// Determines whether there is a terminal attached.
/// ///
...@@ -290,7 +288,7 @@ class Stdio { ...@@ -290,7 +288,7 @@ class Stdio {
/// runtime errors such as "inappropriate ioctl for device" if not handled. /// runtime errors such as "inappropriate ioctl for device" if not handled.
bool get stdinHasTerminal { bool get stdinHasTerminal {
if (_stdinHasTerminal != null) { if (_stdinHasTerminal != null) {
return _stdinHasTerminal; return _stdinHasTerminal!;
} }
if (stdin is! io.Stdin) { if (stdin is! io.Stdin) {
return _stdinHasTerminal = false; return _stdinHasTerminal = false;
...@@ -309,15 +307,15 @@ class Stdio { ...@@ -309,15 +307,15 @@ class Stdio {
return _stdinHasTerminal = true; return _stdinHasTerminal = true;
} }
int get terminalColumns => hasTerminal ? stdout.terminalColumns : null; int? get terminalColumns => hasTerminal ? stdout.terminalColumns : null;
int get terminalLines => hasTerminal ? stdout.terminalLines : null; int? get terminalLines => hasTerminal ? stdout.terminalLines : null;
bool get supportsAnsiEscapes => hasTerminal && stdout.supportsAnsiEscapes; bool get supportsAnsiEscapes => hasTerminal && stdout.supportsAnsiEscapes;
/// Writes [message] to [stderr], falling back on [fallback] if the write /// Writes [message] to [stderr], falling back on [fallback] if the write
/// throws any exception. The default fallback calls [print] on [message]. /// throws any exception. The default fallback calls [print] on [message].
void stderrWrite( void stderrWrite(
String message, { String message, {
void Function(String, dynamic, StackTrace) fallback, void Function(String, dynamic, StackTrace)? fallback,
}) { }) {
if (!_stderrDone) { if (!_stderrDone) {
_stdioWrite(stderr, message, fallback: fallback); _stdioWrite(stderr, message, fallback: fallback);
...@@ -334,7 +332,7 @@ class Stdio { ...@@ -334,7 +332,7 @@ class Stdio {
/// throws any exception. The default fallback calls [print] on [message]. /// throws any exception. The default fallback calls [print] on [message].
void stdoutWrite( void stdoutWrite(
String message, { String message, {
void Function(String, dynamic, StackTrace) fallback, void Function(String, dynamic, StackTrace)? fallback,
}) { }) {
if (!_stdoutDone) { if (!_stdoutDone) {
_stdioWrite(stdout, message, fallback: fallback); _stdioWrite(stdout, message, fallback: fallback);
...@@ -349,7 +347,7 @@ class Stdio { ...@@ -349,7 +347,7 @@ class Stdio {
// Helper for [stderrWrite] and [stdoutWrite]. // Helper for [stderrWrite] and [stdoutWrite].
void _stdioWrite(io.IOSink sink, String message, { void _stdioWrite(io.IOSink sink, String message, {
void Function(String, dynamic, StackTrace) fallback, void Function(String, dynamic, StackTrace)? fallback,
}) { }) {
asyncGuard<void>(() async { asyncGuard<void>(() async {
sink.write(message); sink.write(message);
...@@ -447,7 +445,7 @@ typedef NetworkInterfaceLister = Future<List<NetworkInterface>> Function({ ...@@ -447,7 +445,7 @@ typedef NetworkInterfaceLister = Future<List<NetworkInterface>> Function({
io.InternetAddressType type, io.InternetAddressType type,
}); });
NetworkInterfaceLister _networkInterfaceListerOverride; NetworkInterfaceLister? _networkInterfaceListerOverride;
// Tests can set up a non-default network interface lister. // Tests can set up a non-default network interface lister.
@visibleForTesting @visibleForTesting
...@@ -469,7 +467,7 @@ Future<List<NetworkInterface>> listNetworkInterfaces({ ...@@ -469,7 +467,7 @@ Future<List<NetworkInterface>> listNetworkInterfaces({
io.InternetAddressType type = io.InternetAddressType.any, io.InternetAddressType type = io.InternetAddressType.any,
}) async { }) async {
if (_networkInterfaceListerOverride != null) { if (_networkInterfaceListerOverride != null) {
return _networkInterfaceListerOverride( return _networkInterfaceListerOverride!.call(
includeLoopback: includeLoopback, includeLoopback: includeLoopback,
includeLinkLocal: includeLinkLocal, includeLinkLocal: includeLinkLocal,
type: type, type: type,
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
...@@ -65,12 +63,12 @@ abstract class Logger { ...@@ -65,12 +63,12 @@ abstract class Logger {
/// `outputPreferences.wrapText` setting. /// `outputPreferences.wrapText` setting.
void printError( void printError(
String message, { String message, {
StackTrace stackTrace, StackTrace? stackTrace,
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}); });
/// Display normal output of the command. This should be used for things like /// Display normal output of the command. This should be used for things like
...@@ -103,12 +101,12 @@ abstract class Logger { ...@@ -103,12 +101,12 @@ abstract class Logger {
/// `outputPreferences.wrapText` setting. /// `outputPreferences.wrapText` setting.
void printStatus( void printStatus(
String message, { String message, {
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
bool newline, bool? newline,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}); });
/// Use this for verbose tracing output. Users can turn this output on in order /// Use this for verbose tracing output. Users can turn this output on in order
...@@ -126,20 +124,20 @@ abstract class Logger { ...@@ -126,20 +124,20 @@ abstract class Logger {
/// between the `message` and the progress indicator, if any. /// between the `message` and the progress indicator, if any.
Status startProgress( Status startProgress(
String message, { String message, {
String progressId, String? progressId,
bool multilineOutput = false, bool multilineOutput = false,
int progressIndicatorPadding = kDefaultStatusPadding, int progressIndicatorPadding = kDefaultStatusPadding,
}); });
/// A [SilentStatus] or an [AnsiSpinner] (depending on whether the /// A [SilentStatus] or an [AnsiSpinner] (depending on whether the
/// terminal is fancy enough), already started. /// terminal is fancy enough), already started.
Status startSpinner({ VoidCallback onFinish }); Status startSpinner({ VoidCallback? onFinish });
/// Send an event to be emitted. /// Send an event to be emitted.
/// ///
/// Only surfaces a value in machine modes, Loggers may ignore this message in /// Only surfaces a value in machine modes, Loggers may ignore this message in
/// non-machine modes. /// non-machine modes.
void sendEvent(String name, [Map<String, dynamic> args]) { } void sendEvent(String name, [Map<String, dynamic>? args]) { }
/// Clears all output. /// Clears all output.
void clear(); void clear();
...@@ -174,7 +172,14 @@ class DelegatingLogger implements Logger { ...@@ -174,7 +172,14 @@ class DelegatingLogger implements Logger {
bool get isVerbose => _delegate.isVerbose; bool get isVerbose => _delegate.isVerbose;
@override @override
void printError(String message, {StackTrace stackTrace, bool emphasis, TerminalColor color, int indent, int hangingIndent, bool wrap}) { void printError(String message, {
StackTrace? stackTrace,
bool? emphasis,
TerminalColor? color,
int? indent,
int? hangingIndent,
bool? wrap,
}) {
_delegate.printError( _delegate.printError(
message, message,
stackTrace: stackTrace, stackTrace: stackTrace,
...@@ -187,7 +192,14 @@ class DelegatingLogger implements Logger { ...@@ -187,7 +192,14 @@ class DelegatingLogger implements Logger {
} }
@override @override
void printStatus(String message, {bool emphasis, TerminalColor color, bool newline, int indent, int hangingIndent, bool wrap}) { void printStatus(String message, {
bool? emphasis,
TerminalColor? color,
bool? newline,
int? indent,
int? hangingIndent,
bool? wrap,
}) {
_delegate.printStatus(message, _delegate.printStatus(message,
emphasis: emphasis, emphasis: emphasis,
color: color, color: color,
...@@ -204,12 +216,16 @@ class DelegatingLogger implements Logger { ...@@ -204,12 +216,16 @@ class DelegatingLogger implements Logger {
} }
@override @override
void sendEvent(String name, [Map<String, dynamic> args]) { void sendEvent(String name, [Map<String, dynamic>? args]) {
_delegate.sendEvent(name, args); _delegate.sendEvent(name, args);
} }
@override @override
Status startProgress(String message, {String progressId, bool multilineOutput = false, int progressIndicatorPadding = kDefaultStatusPadding}) { Status startProgress(String message, {
String? progressId,
bool multilineOutput = false,
int progressIndicatorPadding = kDefaultStatusPadding,
}) {
return _delegate.startProgress(message, return _delegate.startProgress(message,
progressId: progressId, progressId: progressId,
multilineOutput: multilineOutput, multilineOutput: multilineOutput,
...@@ -218,7 +234,7 @@ class DelegatingLogger implements Logger { ...@@ -218,7 +234,7 @@ class DelegatingLogger implements Logger {
} }
@override @override
Status startSpinner({VoidCallback onFinish}) { Status startSpinner({VoidCallback? onFinish}) {
return _delegate.startSpinner(onFinish: onFinish); return _delegate.startSpinner(onFinish: onFinish);
} }
...@@ -240,7 +256,7 @@ T asLogger<T extends Logger>(Logger logger) { ...@@ -240,7 +256,7 @@ T asLogger<T extends Logger>(Logger logger) {
if (logger is T) { if (logger is T) {
return logger; return logger;
} else if (logger is DelegatingLogger) { } else if (logger is DelegatingLogger) {
logger = (logger as DelegatingLogger)._delegate; logger = logger._delegate;
} else { } else {
throw StateError('$original has no ancestor delegate of type $T'); throw StateError('$original has no ancestor delegate of type $T');
} }
...@@ -249,9 +265,9 @@ T asLogger<T extends Logger>(Logger logger) { ...@@ -249,9 +265,9 @@ T asLogger<T extends Logger>(Logger logger) {
class StdoutLogger extends Logger { class StdoutLogger extends Logger {
StdoutLogger({ StdoutLogger({
@required this.terminal, required this.terminal,
@required Stdio stdio, required Stdio stdio,
@required OutputPreferences outputPreferences, required OutputPreferences outputPreferences,
StopwatchFactory stopwatchFactory = const StopwatchFactory(), StopwatchFactory stopwatchFactory = const StopwatchFactory(),
}) })
: _stdio = stdio, : _stdio = stdio,
...@@ -265,7 +281,7 @@ class StdoutLogger extends Logger { ...@@ -265,7 +281,7 @@ class StdoutLogger extends Logger {
final Stdio _stdio; final Stdio _stdio;
final StopwatchFactory _stopwatchFactory; final StopwatchFactory _stopwatchFactory;
Status _status; Status? _status;
@override @override
bool get isVerbose => false; bool get isVerbose => false;
...@@ -279,15 +295,14 @@ class StdoutLogger extends Logger { ...@@ -279,15 +295,14 @@ class StdoutLogger extends Logger {
@override @override
void printError( void printError(
String message, { String message, {
StackTrace stackTrace, StackTrace? stackTrace,
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}) { }) {
_status?.pause(); _status?.pause();
message ??= '';
message = wrapText(message, message = wrapText(message,
indent: indent, indent: indent,
hangingIndent: hangingIndent, hangingIndent: hangingIndent,
...@@ -308,15 +323,14 @@ class StdoutLogger extends Logger { ...@@ -308,15 +323,14 @@ class StdoutLogger extends Logger {
@override @override
void printStatus( void printStatus(
String message, { String message, {
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
bool newline, bool? newline,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}) { }) {
_status?.pause(); _status?.pause();
message ??= '';
message = wrapText(message, message = wrapText(message,
indent: indent, indent: indent,
hangingIndent: hangingIndent, hangingIndent: hangingIndent,
...@@ -348,11 +362,10 @@ class StdoutLogger extends Logger { ...@@ -348,11 +362,10 @@ class StdoutLogger extends Logger {
@override @override
Status startProgress( Status startProgress(
String message, { String message, {
String progressId, String? progressId,
bool multilineOutput = false, bool multilineOutput = false,
int progressIndicatorPadding = kDefaultStatusPadding, int progressIndicatorPadding = kDefaultStatusPadding,
}) { }) {
assert(progressIndicatorPadding != null);
if (_status != null) { if (_status != null) {
// Ignore nested progresses; return a no-op status object. // Ignore nested progresses; return a no-op status object.
return SilentStatus( return SilentStatus(
...@@ -379,11 +392,11 @@ class StdoutLogger extends Logger { ...@@ -379,11 +392,11 @@ class StdoutLogger extends Logger {
stopwatch: _stopwatchFactory.createStopwatch(), stopwatch: _stopwatchFactory.createStopwatch(),
)..start(); )..start();
} }
return _status; return _status!;
} }
@override @override
Status startSpinner({ VoidCallback onFinish }) { Status startSpinner({ VoidCallback? onFinish }) {
if (terminal.supportsColor) { if (terminal.supportsColor) {
return AnsiSpinner( return AnsiSpinner(
onFinish: onFinish, onFinish: onFinish,
...@@ -403,7 +416,7 @@ class StdoutLogger extends Logger { ...@@ -403,7 +416,7 @@ class StdoutLogger extends Logger {
} }
@override @override
void sendEvent(String name, [Map<String, dynamic> args]) { } void sendEvent(String name, [Map<String, dynamic>? args]) { }
@override @override
void clear() { void clear() {
...@@ -423,9 +436,9 @@ class StdoutLogger extends Logger { ...@@ -423,9 +436,9 @@ class StdoutLogger extends Logger {
/// they will show up as the unrepresentable character symbol '�'. /// they will show up as the unrepresentable character symbol '�'.
class WindowsStdoutLogger extends StdoutLogger { class WindowsStdoutLogger extends StdoutLogger {
WindowsStdoutLogger({ WindowsStdoutLogger({
@required Terminal terminal, required Terminal terminal,
@required Stdio stdio, required Stdio stdio,
@required OutputPreferences outputPreferences, required OutputPreferences outputPreferences,
StopwatchFactory stopwatchFactory = const StopwatchFactory(), StopwatchFactory stopwatchFactory = const StopwatchFactory(),
}) : super( }) : super(
terminal: terminal, terminal: terminal,
...@@ -451,16 +464,16 @@ class WindowsStdoutLogger extends StdoutLogger { ...@@ -451,16 +464,16 @@ class WindowsStdoutLogger extends StdoutLogger {
class BufferLogger extends Logger { class BufferLogger extends Logger {
BufferLogger({ BufferLogger({
@required this.terminal, required this.terminal,
@required OutputPreferences outputPreferences, required OutputPreferences outputPreferences,
StopwatchFactory stopwatchFactory = const StopwatchFactory(), StopwatchFactory stopwatchFactory = const StopwatchFactory(),
}) : _outputPreferences = outputPreferences, }) : _outputPreferences = outputPreferences,
_stopwatchFactory = stopwatchFactory; _stopwatchFactory = stopwatchFactory;
/// Create a [BufferLogger] with test preferences. /// Create a [BufferLogger] with test preferences.
BufferLogger.test({ BufferLogger.test({
Terminal terminal, Terminal? terminal,
OutputPreferences outputPreferences, OutputPreferences? outputPreferences,
}) : terminal = terminal ?? Terminal.test(), }) : terminal = terminal ?? Terminal.test(),
_outputPreferences = outputPreferences ?? OutputPreferences.test(), _outputPreferences = outputPreferences ?? OutputPreferences.test(),
_stopwatchFactory = const StopwatchFactory(); _stopwatchFactory = const StopwatchFactory();
...@@ -496,12 +509,12 @@ class BufferLogger extends Logger { ...@@ -496,12 +509,12 @@ class BufferLogger extends Logger {
@override @override
void printError( void printError(
String message, { String message, {
StackTrace stackTrace, StackTrace? stackTrace,
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}) { }) {
_error.writeln(terminal.color( _error.writeln(terminal.color(
wrapText(message, wrapText(message,
...@@ -517,12 +530,12 @@ class BufferLogger extends Logger { ...@@ -517,12 +530,12 @@ class BufferLogger extends Logger {
@override @override
void printStatus( void printStatus(
String message, { String message, {
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
bool newline, bool? newline,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}) { }) {
if (newline != false) { if (newline != false) {
_status.writeln(wrapText(message, _status.writeln(wrapText(message,
...@@ -547,7 +560,7 @@ class BufferLogger extends Logger { ...@@ -547,7 +560,7 @@ class BufferLogger extends Logger {
@override @override
Status startProgress( Status startProgress(
String message, { String message, {
String progressId, String? progressId,
bool multilineOutput = false, bool multilineOutput = false,
int progressIndicatorPadding = kDefaultStatusPadding, int progressIndicatorPadding = kDefaultStatusPadding,
}) { }) {
...@@ -559,7 +572,7 @@ class BufferLogger extends Logger { ...@@ -559,7 +572,7 @@ class BufferLogger extends Logger {
} }
@override @override
Status startSpinner({VoidCallback onFinish}) { Status startSpinner({VoidCallback? onFinish}) {
return SilentStatus( return SilentStatus(
stopwatch: _stopwatchFactory.createStopwatch(), stopwatch: _stopwatchFactory.createStopwatch(),
onFinish: onFinish, onFinish: onFinish,
...@@ -575,8 +588,8 @@ class BufferLogger extends Logger { ...@@ -575,8 +588,8 @@ class BufferLogger extends Logger {
} }
@override @override
void sendEvent(String name, [Map<String, dynamic> args]) { void sendEvent(String name, [Map<String, dynamic>? args]) {
_events.write(json.encode(<String, Object>{ _events.write(json.encode(<String, Object?>{
'name': name, 'name': name,
'args': args 'args': args
})); }));
...@@ -602,12 +615,12 @@ class VerboseLogger extends DelegatingLogger { ...@@ -602,12 +615,12 @@ class VerboseLogger extends DelegatingLogger {
@override @override
void printError( void printError(
String message, { String message, {
StackTrace stackTrace, StackTrace? stackTrace,
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}) { }) {
_emit( _emit(
_LogType.error, _LogType.error,
...@@ -624,12 +637,12 @@ class VerboseLogger extends DelegatingLogger { ...@@ -624,12 +637,12 @@ class VerboseLogger extends DelegatingLogger {
@override @override
void printStatus( void printStatus(
String message, { String message, {
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
bool newline, bool? newline,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}) { }) {
_emit(_LogType.status, wrapText(message, _emit(_LogType.status, wrapText(message,
indent: indent, indent: indent,
...@@ -647,7 +660,7 @@ class VerboseLogger extends DelegatingLogger { ...@@ -647,7 +660,7 @@ class VerboseLogger extends DelegatingLogger {
@override @override
Status startProgress( Status startProgress(
String message, { String message, {
String progressId, String? progressId,
bool multilineOutput = false, bool multilineOutput = false,
int progressIndicatorPadding = kDefaultStatusPadding, int progressIndicatorPadding = kDefaultStatusPadding,
}) { }) {
...@@ -669,7 +682,7 @@ class VerboseLogger extends DelegatingLogger { ...@@ -669,7 +682,7 @@ class VerboseLogger extends DelegatingLogger {
)..start(); )..start();
} }
void _emit(_LogType type, String message, [ StackTrace stackTrace ]) { void _emit(_LogType type, String message, [ StackTrace? stackTrace ]) {
if (message.trim().isEmpty) { if (message.trim().isEmpty) {
return; return;
} }
...@@ -705,7 +718,7 @@ class VerboseLogger extends DelegatingLogger { ...@@ -705,7 +718,7 @@ class VerboseLogger extends DelegatingLogger {
} }
@override @override
void sendEvent(String name, [Map<String, dynamic> args]) { } void sendEvent(String name, [Map<String, dynamic>? args]) { }
} }
class PrefixedErrorLogger extends DelegatingLogger { class PrefixedErrorLogger extends DelegatingLogger {
...@@ -714,14 +727,14 @@ class PrefixedErrorLogger extends DelegatingLogger { ...@@ -714,14 +727,14 @@ class PrefixedErrorLogger extends DelegatingLogger {
@override @override
void printError( void printError(
String message, { String message, {
StackTrace stackTrace, StackTrace? stackTrace,
bool emphasis, bool? emphasis,
TerminalColor color, TerminalColor? color,
int indent, int? indent,
int hangingIndent, int? hangingIndent,
bool wrap, bool? wrap,
}) { }) {
if (message?.trim()?.isNotEmpty == true) { if (message.trim().isNotEmpty == true) {
message = 'ERROR: $message'; message = 'ERROR: $message';
} }
super.printError( super.printError(
...@@ -760,10 +773,10 @@ typedef SlowWarningCallback = String Function(); ...@@ -760,10 +773,10 @@ typedef SlowWarningCallback = String Function();
abstract class Status { abstract class Status {
Status({ Status({
this.onFinish, this.onFinish,
@required Stopwatch stopwatch, required Stopwatch stopwatch,
}) : _stopwatch = stopwatch; }) : _stopwatch = stopwatch;
final VoidCallback onFinish; final VoidCallback? onFinish;
@protected @protected
final Stopwatch _stopwatch; final Stopwatch _stopwatch;
...@@ -802,17 +815,15 @@ abstract class Status { ...@@ -802,17 +815,15 @@ abstract class Status {
void finish() { void finish() {
assert(_stopwatch.isRunning); assert(_stopwatch.isRunning);
_stopwatch.stop(); _stopwatch.stop();
if (onFinish != null) { onFinish?.call();
onFinish();
}
} }
} }
/// A [SilentStatus] shows nothing. /// A [SilentStatus] shows nothing.
class SilentStatus extends Status { class SilentStatus extends Status {
SilentStatus({ SilentStatus({
@required Stopwatch stopwatch, required Stopwatch stopwatch,
VoidCallback onFinish, VoidCallback? onFinish,
}) : super( }) : super(
onFinish: onFinish, onFinish: onFinish,
stopwatch: stopwatch, stopwatch: stopwatch,
...@@ -820,9 +831,7 @@ class SilentStatus extends Status { ...@@ -820,9 +831,7 @@ class SilentStatus extends Status {
@override @override
void finish() { void finish() {
if (onFinish != null) { onFinish?.call();
onFinish();
}
} }
} }
...@@ -831,13 +840,11 @@ class SilentStatus extends Status { ...@@ -831,13 +840,11 @@ class SilentStatus extends Status {
class SummaryStatus extends Status { class SummaryStatus extends Status {
SummaryStatus({ SummaryStatus({
this.message = '', this.message = '',
@required Stopwatch stopwatch, required Stopwatch stopwatch,
this.padding = kDefaultStatusPadding, this.padding = kDefaultStatusPadding,
VoidCallback onFinish, VoidCallback? onFinish,
@required Stdio stdio, required Stdio stdio,
}) : assert(message != null), }) : _stdio = stdio,
assert(padding != null),
_stdio = stdio,
super( super(
onFinish: onFinish, onFinish: onFinish,
stopwatch: stopwatch, stopwatch: stopwatch,
...@@ -899,10 +906,10 @@ class SummaryStatus extends Status { ...@@ -899,10 +906,10 @@ class SummaryStatus extends Status {
/// terminal spinner. When stopped or canceled, the animation erases itself. /// terminal spinner. When stopped or canceled, the animation erases itself.
class AnsiSpinner extends Status { class AnsiSpinner extends Status {
AnsiSpinner({ AnsiSpinner({
@required Stopwatch stopwatch, required Stopwatch stopwatch,
@required Terminal terminal, required Terminal terminal,
VoidCallback onFinish, VoidCallback? onFinish,
@required Stdio stdio, required Stdio stdio,
}) : _stdio = stdio, }) : _stdio = stdio,
_terminal = terminal, _terminal = terminal,
super( super(
...@@ -918,7 +925,7 @@ class AnsiSpinner extends Status { ...@@ -918,7 +925,7 @@ class AnsiSpinner extends Status {
bool timedOut = false; bool timedOut = false;
int ticks = 0; int ticks = 0;
Timer timer; Timer? timer;
// Windows console font has a limited set of Unicode characters. // Windows console font has a limited set of Unicode characters.
List<String> get _animation => !_terminal.supportsEmoji List<String> get _animation => !_terminal.supportsEmoji
...@@ -945,7 +952,7 @@ class AnsiSpinner extends Status { ...@@ -945,7 +952,7 @@ class AnsiSpinner extends Status {
void _startSpinner() { void _startSpinner() {
_writeToStdOut(_clear); // for _callback to backspace over _writeToStdOut(_clear); // for _callback to backspace over
timer = Timer.periodic(const Duration(milliseconds: 100), _callback); timer = Timer.periodic(const Duration(milliseconds: 100), _callback);
_callback(timer); _callback(timer!);
} }
void _callback(Timer timer) { void _callback(Timer timer) {
...@@ -960,8 +967,8 @@ class AnsiSpinner extends Status { ...@@ -960,8 +967,8 @@ class AnsiSpinner extends Status {
@override @override
void finish() { void finish() {
assert(timer != null); assert(timer != null);
assert(timer.isActive); assert(timer!.isActive);
timer.cancel(); timer?.cancel();
timer = null; timer = null;
_clearSpinner(); _clearSpinner();
super.finish(); super.finish();
...@@ -974,15 +981,15 @@ class AnsiSpinner extends Status { ...@@ -974,15 +981,15 @@ class AnsiSpinner extends Status {
@override @override
void pause() { void pause() {
assert(timer != null); assert(timer != null);
assert(timer.isActive); assert(timer!.isActive);
_clearSpinner(); _clearSpinner();
timer.cancel(); timer?.cancel();
} }
@override @override
void resume() { void resume() {
assert(timer != null); assert(timer != null);
assert(!timer.isActive); assert(!timer!.isActive);
_startSpinner(); _startSpinner();
} }
} }
...@@ -1000,10 +1007,10 @@ class AnsiStatus extends AnsiSpinner { ...@@ -1000,10 +1007,10 @@ class AnsiStatus extends AnsiSpinner {
this.message = '', this.message = '',
this.multilineOutput = false, this.multilineOutput = false,
this.padding = kDefaultStatusPadding, this.padding = kDefaultStatusPadding,
@required Stopwatch stopwatch, required Stopwatch stopwatch,
@required Terminal terminal, required Terminal terminal,
VoidCallback onFinish, VoidCallback? onFinish,
Stdio stdio, required Stdio stdio,
}) : assert(message != null), }) : assert(message != null),
assert(multilineOutput != null), assert(multilineOutput != null),
assert(padding != null), assert(padding != null),
...@@ -1023,7 +1030,7 @@ class AnsiStatus extends AnsiSpinner { ...@@ -1023,7 +1030,7 @@ class AnsiStatus extends AnsiSpinner {
@override @override
int get spinnerIndent => _kTimePadding - 1; int get spinnerIndent => _kTimePadding - 1;
int _totalMessageLength; int _totalMessageLength = 0;
@override @override
void start() { void start() {
......
...@@ -2,11 +2,8 @@ ...@@ -2,11 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:meta/meta.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
import '../convert.dart'; import '../convert.dart';
...@@ -27,7 +24,7 @@ typedef ShutdownHook = FutureOr<dynamic> Function(); ...@@ -27,7 +24,7 @@ typedef ShutdownHook = FutureOr<dynamic> Function();
abstract class ShutdownHooks { abstract class ShutdownHooks {
factory ShutdownHooks({ factory ShutdownHooks({
@required Logger logger, required Logger logger,
}) => _DefaultShutdownHooks( }) => _DefaultShutdownHooks(
logger: logger, logger: logger,
); );
...@@ -49,7 +46,7 @@ abstract class ShutdownHooks { ...@@ -49,7 +46,7 @@ abstract class ShutdownHooks {
class _DefaultShutdownHooks implements ShutdownHooks { class _DefaultShutdownHooks implements ShutdownHooks {
_DefaultShutdownHooks({ _DefaultShutdownHooks({
@required Logger logger, required Logger logger,
}) : _logger = logger; }) : _logger = logger;
final Logger _logger; final Logger _logger;
...@@ -137,8 +134,8 @@ typedef RunResultChecker = bool Function(int); ...@@ -137,8 +134,8 @@ typedef RunResultChecker = bool Function(int);
abstract class ProcessUtils { abstract class ProcessUtils {
factory ProcessUtils({ factory ProcessUtils({
@required ProcessManager processManager, required ProcessManager processManager,
@required Logger logger, required Logger logger,
}) => _DefaultProcessUtils( }) => _DefaultProcessUtils(
processManager: processManager, processManager: processManager,
logger: logger, logger: logger,
...@@ -236,8 +233,8 @@ abstract class ProcessUtils { ...@@ -236,8 +233,8 @@ abstract class ProcessUtils {
class _DefaultProcessUtils implements ProcessUtils { class _DefaultProcessUtils implements ProcessUtils {
_DefaultProcessUtils({ _DefaultProcessUtils({
@required ProcessManager processManager, required ProcessManager processManager,
@required Logger logger, required Logger logger,
}) : _processManager = processManager, }) : _processManager = processManager,
_logger = logger; _logger = logger;
...@@ -249,11 +246,11 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -249,11 +246,11 @@ class _DefaultProcessUtils implements ProcessUtils {
Future<RunResult> run( Future<RunResult> run(
List<String> cmd, { List<String> cmd, {
bool throwOnError = false, bool throwOnError = false,
RunResultChecker allowedFailures, RunResultChecker? allowedFailures,
String workingDirectory, String? workingDirectory,
bool allowReentrantFlutter = false, bool allowReentrantFlutter = false,
Map<String, String> environment, Map<String, String>? environment,
Duration timeout, Duration? timeout,
int timeoutRetries = 0, int timeoutRetries = 0,
}) async { }) async {
if (cmd == null || cmd.isEmpty) { if (cmd == null || cmd.isEmpty) {
...@@ -305,8 +302,8 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -305,8 +302,8 @@ class _DefaultProcessUtils implements ProcessUtils {
.listen(stderrBuffer.write) .listen(stderrBuffer.write)
.asFuture<void>(null); .asFuture<void>(null);
int exitCode; int? exitCode;
exitCode = await process.exitCode.timeout(timeout, onTimeout: () { exitCode = await process.exitCode.then<int?>((int x) => x).timeout(timeout, onTimeout: () {
// The process timed out. Kill it. // The process timed out. Kill it.
_processManager.killPid(process.pid); _processManager.killPid(process.pid);
return null; return null;
...@@ -324,7 +321,7 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -324,7 +321,7 @@ class _DefaultProcessUtils implements ProcessUtils {
stdioFuture = stdioFuture.timeout(const Duration(seconds: 1)); stdioFuture = stdioFuture.timeout(const Duration(seconds: 1));
} }
await stdioFuture; await stdioFuture;
} on Exception catch (_) { } on Exception {
// Ignore errors on the process' stdout and stderr streams. Just capture // Ignore errors on the process' stdout and stderr streams. Just capture
// whatever we got, and use the exit code // whatever we got, and use the exit code
} }
...@@ -365,10 +362,10 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -365,10 +362,10 @@ class _DefaultProcessUtils implements ProcessUtils {
List<String> cmd, { List<String> cmd, {
bool throwOnError = false, bool throwOnError = false,
bool verboseExceptions = false, bool verboseExceptions = false,
RunResultChecker allowedFailures, RunResultChecker? allowedFailures,
bool hideStdout = false, bool hideStdout = false,
String workingDirectory, String? workingDirectory,
Map<String, String> environment, Map<String, String>? environment,
bool allowReentrantFlutter = false, bool allowReentrantFlutter = false,
Encoding encoding = systemEncoding, Encoding encoding = systemEncoding,
}) { }) {
...@@ -420,9 +417,9 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -420,9 +417,9 @@ class _DefaultProcessUtils implements ProcessUtils {
@override @override
Future<Process> start( Future<Process> start(
List<String> cmd, { List<String> cmd, {
String workingDirectory, String? workingDirectory,
bool allowReentrantFlutter = false, bool allowReentrantFlutter = false,
Map<String, String> environment, Map<String, String>? environment,
}) { }) {
_traceCommand(cmd, workingDirectory: workingDirectory); _traceCommand(cmd, workingDirectory: workingDirectory);
return _processManager.start( return _processManager.start(
...@@ -435,14 +432,14 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -435,14 +432,14 @@ class _DefaultProcessUtils implements ProcessUtils {
@override @override
Future<int> stream( Future<int> stream(
List<String> cmd, { List<String> cmd, {
String workingDirectory, String? workingDirectory,
bool allowReentrantFlutter = false, bool allowReentrantFlutter = false,
String prefix = '', String prefix = '',
bool trace = false, bool trace = false,
RegExp filter, RegExp? filter,
RegExp stdoutErrorMatcher, RegExp? stdoutErrorMatcher,
StringConverter mapFunction, StringConverter? mapFunction,
Map<String, String> environment, Map<String, String>? environment,
}) async { }) async {
final Process process = await start( final Process process = await start(
cmd, cmd,
...@@ -503,7 +500,7 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -503,7 +500,7 @@ class _DefaultProcessUtils implements ProcessUtils {
@override @override
bool exitsHappySync( bool exitsHappySync(
List<String> cli, { List<String> cli, {
Map<String, String> environment, Map<String, String>? environment,
}) { }) {
_traceCommand(cli); _traceCommand(cli);
if (!_processManager.canRun(cli.first)) { if (!_processManager.canRun(cli.first)) {
...@@ -522,7 +519,7 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -522,7 +519,7 @@ class _DefaultProcessUtils implements ProcessUtils {
@override @override
Future<bool> exitsHappy( Future<bool> exitsHappy(
List<String> cli, { List<String> cli, {
Map<String, String> environment, Map<String, String>? environment,
}) async { }) async {
_traceCommand(cli); _traceCommand(cli);
if (!_processManager.canRun(cli.first)) { if (!_processManager.canRun(cli.first)) {
...@@ -538,8 +535,8 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -538,8 +535,8 @@ class _DefaultProcessUtils implements ProcessUtils {
} }
} }
Map<String, String> _environment(bool allowReentrantFlutter, [ Map<String, String>? _environment(bool allowReentrantFlutter, [
Map<String, String> environment, Map<String, String>? environment,
]) { ]) {
if (allowReentrantFlutter) { if (allowReentrantFlutter) {
if (environment == null) { if (environment == null) {
...@@ -552,7 +549,7 @@ class _DefaultProcessUtils implements ProcessUtils { ...@@ -552,7 +549,7 @@ class _DefaultProcessUtils implements ProcessUtils {
return environment; return environment;
} }
void _traceCommand(List<String> args, { String workingDirectory }) { void _traceCommand(List<String> args, { String? workingDirectory }) {
final String argsText = args.join(' '); final String argsText = args.join(' ');
if (workingDirectory == null) { if (workingDirectory == null) {
_logger.printTrace('executing: $argsText'); _logger.printTrace('executing: $argsText');
......
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart';
import '../convert.dart'; import '../convert.dart';
import 'io.dart' as io; import 'io.dart' as io;
import 'logger.dart'; import 'logger.dart';
...@@ -25,12 +21,12 @@ enum TerminalColor { ...@@ -25,12 +21,12 @@ enum TerminalColor {
/// console. /// console.
class OutputPreferences { class OutputPreferences {
OutputPreferences({ OutputPreferences({
bool wrapText, bool? wrapText,
int wrapColumn, int? wrapColumn,
bool showColor, bool? showColor,
io.Stdio stdio, io.Stdio? stdio,
}) : _stdio = stdio, }) : _stdio = stdio,
wrapText = wrapText ?? stdio.hasTerminal, wrapText = wrapText ?? stdio?.hasTerminal ?? false,
_overrideWrapColumn = wrapColumn, _overrideWrapColumn = wrapColumn,
showColor = showColor ?? false; showColor = showColor ?? false;
...@@ -38,7 +34,7 @@ class OutputPreferences { ...@@ -38,7 +34,7 @@ class OutputPreferences {
OutputPreferences.test({this.wrapText = false, int wrapColumn = kDefaultTerminalColumns, this.showColor = false}) OutputPreferences.test({this.wrapText = false, int wrapColumn = kDefaultTerminalColumns, this.showColor = false})
: _overrideWrapColumn = wrapColumn, _stdio = null; : _overrideWrapColumn = wrapColumn, _stdio = null;
final io.Stdio _stdio; final io.Stdio? _stdio;
/// If [wrapText] is true, then any text sent to the context's [Logger] /// If [wrapText] is true, then any text sent to the context's [Logger]
/// instance (e.g. from the [printError] or [printStatus] functions) will be /// instance (e.g. from the [printError] or [printStatus] functions) will be
...@@ -56,7 +52,7 @@ class OutputPreferences { ...@@ -56,7 +52,7 @@ class OutputPreferences {
/// (e.g. from the [printError] or [printStatus] functions) will be wrapped. /// (e.g. from the [printError] or [printStatus] functions) will be wrapped.
/// Ignored if [wrapText] is false. Defaults to the width of the output /// Ignored if [wrapText] is false. Defaults to the width of the output
/// terminal, or to [kDefaultTerminalColumns] if not writing to a terminal. /// terminal, or to [kDefaultTerminalColumns] if not writing to a terminal.
final int _overrideWrapColumn; final int? _overrideWrapColumn;
int get wrapColumn { int get wrapColumn {
return _overrideWrapColumn ?? _stdio?.terminalColumns ?? kDefaultTerminalColumns; return _overrideWrapColumn ?? _stdio?.terminalColumns ?? kDefaultTerminalColumns;
} }
...@@ -136,17 +132,17 @@ abstract class Terminal { ...@@ -136,17 +132,17 @@ abstract class Terminal {
/// If [usesTerminalUi] is false, throws a [StateError]. /// If [usesTerminalUi] is false, throws a [StateError].
Future<String> promptForCharInput( Future<String> promptForCharInput(
List<String> acceptedCharacters, { List<String> acceptedCharacters, {
@required Logger logger, required Logger logger,
String prompt, String? prompt,
int defaultChoiceIndex, int? defaultChoiceIndex,
bool displayAcceptedCharacters = true, bool displayAcceptedCharacters = true,
}); });
} }
class AnsiTerminal implements Terminal { class AnsiTerminal implements Terminal {
AnsiTerminal({ AnsiTerminal({
@required io.Stdio stdio, required io.Stdio stdio,
@required Platform platform, required Platform platform,
}) })
: _stdio = stdio, : _stdio = stdio,
_platform = platform; _platform = platform;
...@@ -178,10 +174,10 @@ class AnsiTerminal implements Terminal { ...@@ -178,10 +174,10 @@ class AnsiTerminal implements Terminal {
TerminalColor.grey: grey, TerminalColor.grey: grey,
}; };
static String colorCode(TerminalColor color) => _colorMap[color]; static String colorCode(TerminalColor color) => _colorMap[color]!;
@override @override
bool get supportsColor => _platform?.stdoutSupportsAnsi ?? false; bool get supportsColor => _platform.stdoutSupportsAnsi;
// Assume unicode emojis are supported when not on Windows. // Assume unicode emojis are supported when not on Windows.
// If we are on Windows, unicode emojis are supported in Windows Terminal, // If we are on Windows, unicode emojis are supported in Windows Terminal,
...@@ -236,7 +232,7 @@ class AnsiTerminal implements Terminal { ...@@ -236,7 +232,7 @@ class AnsiTerminal implements Terminal {
return message; return message;
} }
final StringBuffer buffer = StringBuffer(); final StringBuffer buffer = StringBuffer();
final String colorCodes = _colorMap[color]; final String colorCodes = _colorMap[color]!;
for (String line in message.split('\n')) { for (String line in message.split('\n')) {
// If there were resets in the string before, then keep them, but // If there were resets in the string before, then keep them, but
// restart the color right after. This prevents embedded resets from // restart the color right after. This prevents embedded resets from
...@@ -273,26 +269,23 @@ class AnsiTerminal implements Terminal { ...@@ -273,26 +269,23 @@ class AnsiTerminal implements Terminal {
@override @override
bool get stdinHasTerminal => _stdio.stdinHasTerminal; bool get stdinHasTerminal => _stdio.stdinHasTerminal;
Stream<String> _broadcastStdInString; Stream<String>? _broadcastStdInString;
@override @override
Stream<String> get keystrokes { Stream<String> get keystrokes {
_broadcastStdInString ??= _stdio.stdin.transform<String>(const AsciiDecoder(allowInvalid: true)).asBroadcastStream(); return _broadcastStdInString ??= _stdio.stdin.transform<String>(const AsciiDecoder(allowInvalid: true)).asBroadcastStream();
return _broadcastStdInString;
} }
@override @override
Future<String> promptForCharInput( Future<String> promptForCharInput(
List<String> acceptedCharacters, { List<String> acceptedCharacters, {
@required Logger logger, required Logger logger,
String prompt, String? prompt,
int defaultChoiceIndex, int? defaultChoiceIndex,
bool displayAcceptedCharacters = true, bool displayAcceptedCharacters = true,
}) async { }) async {
assert(acceptedCharacters != null);
assert(acceptedCharacters.isNotEmpty); assert(acceptedCharacters.isNotEmpty);
assert(prompt == null || prompt.isNotEmpty); assert(prompt == null || prompt.isNotEmpty);
assert(displayAcceptedCharacters != null);
if (!usesTerminalUi) { if (!usesTerminalUi) {
throw StateError('cannot prompt without a terminal ui'); throw StateError('cannot prompt without a terminal ui');
} }
...@@ -303,7 +296,7 @@ class AnsiTerminal implements Terminal { ...@@ -303,7 +296,7 @@ class AnsiTerminal implements Terminal {
charactersToDisplay[defaultChoiceIndex] = bolden(charactersToDisplay[defaultChoiceIndex]); charactersToDisplay[defaultChoiceIndex] = bolden(charactersToDisplay[defaultChoiceIndex]);
acceptedCharacters.add(''); acceptedCharacters.add('');
} }
String choice; String? choice;
singleCharMode = true; singleCharMode = true;
while (choice == null || choice.length > 1 || !acceptedCharacters.contains(choice)) { while (choice == null || choice.length > 1 || !acceptedCharacters.contains(choice)) {
if (prompt != null) { if (prompt != null) {
...@@ -329,7 +322,7 @@ class _TestTerminal implements Terminal { ...@@ -329,7 +322,7 @@ class _TestTerminal implements Terminal {
_TestTerminal({this.supportsColor = false, this.supportsEmoji = false}); _TestTerminal({this.supportsColor = false, this.supportsEmoji = false});
@override @override
bool usesTerminalUi; bool usesTerminalUi = false;
@override @override
String bolden(String message) => message; String bolden(String message) => message;
...@@ -345,9 +338,9 @@ class _TestTerminal implements Terminal { ...@@ -345,9 +338,9 @@ class _TestTerminal implements Terminal {
@override @override
Future<String> promptForCharInput(List<String> acceptedCharacters, { Future<String> promptForCharInput(List<String> acceptedCharacters, {
@required Logger logger, required Logger logger,
String prompt, String? prompt,
int defaultChoiceIndex, int? defaultChoiceIndex,
bool displayAcceptedCharacters = true, bool displayAcceptedCharacters = true,
}) { }) {
throw UnsupportedError('promptForCharInput not supported in the test terminal.'); throw UnsupportedError('promptForCharInput not supported in the test terminal.');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment