[flutter_tools] flutter run should allow exit when make choose for devices. (#64403)

This commit is contained in:
includecmath 2020-09-03 08:30:04 +08:00 committed by GitHub
parent 0b4dad6553
commit 6d46ff7e9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 10 deletions

View File

@ -285,6 +285,7 @@ class AnsiTerminal implements Terminal {
if (displayAcceptedCharacters) { if (displayAcceptedCharacters) {
logger.printStatus(' [${charactersToDisplay.join("|")}]', newline: false); logger.printStatus(' [${charactersToDisplay.join("|")}]', newline: false);
} }
// prompt ends with ': '
logger.printStatus(': ', emphasis: true, newline: false); logger.printStatus(': ', emphasis: true, newline: false);
} }
choice = await keystrokes.first; choice = await keystrokes.first;

View File

@ -256,7 +256,7 @@ class UserMessages {
'Found $count devices with name or id matching $deviceId:'; 'Found $count devices with name or id matching $deviceId:';
String get flutterMultipleDevicesFound => 'Multiple devices found:'; String get flutterMultipleDevicesFound => 'Multiple devices found:';
String flutterChooseDevice(int option, String name, String deviceId) => '[$option]: $name ($deviceId)'; String flutterChooseDevice(int option, String name, String deviceId) => '[$option]: $name ($deviceId)';
String get flutterChooseOne => 'Please choose one:'; String get flutterChooseOne => 'Please choose one (To quit, press "q/Q")';
String get flutterSpecifyDeviceWithAllOption => String get flutterSpecifyDeviceWithAllOption =>
'More than one device connected; please specify a device with ' 'More than one device connected; please specify a device with '
"the '-d <deviceId>' flag, or use '-d all' to act on all devices."; "the '-d <deviceId>' flag, or use '-d all' to act on all devices.";

View File

@ -14,6 +14,7 @@ import 'android/android_sdk.dart';
import 'android/android_workflow.dart'; import 'android/android_workflow.dart';
import 'application_package.dart'; import 'application_package.dart';
import 'artifacts.dart'; import 'artifacts.dart';
import 'base/common.dart';
import 'base/config.dart'; import 'base/config.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/dds.dart'; import 'base/dds.dart';
@ -283,6 +284,9 @@ abstract class DeviceManager {
Future<Device> _chooseOneOfAvailableDevices(List<Device> devices) async { Future<Device> _chooseOneOfAvailableDevices(List<Device> devices) async {
_displayDeviceOptions(devices); _displayDeviceOptions(devices);
final String userInput = await _readUserInput(devices.length); final String userInput = await _readUserInput(devices.length);
if (userInput.toLowerCase() == 'q') {
throwToolExit('');
}
return devices[int.parse(userInput)]; return devices[int.parse(userInput)];
} }
@ -297,7 +301,8 @@ abstract class DeviceManager {
Future<String> _readUserInput(int deviceCount) async { Future<String> _readUserInput(int deviceCount) async {
globals.terminal.usesTerminalUi = true; globals.terminal.usesTerminalUi = true;
final String result = await globals.terminal.promptForCharInput( final String result = await globals.terminal.promptForCharInput(
<String>[ for (int i = 0; i < deviceCount; i++) '$i' ], <String>[ for (int i = 0; i < deviceCount; i++) '$i', 'q', 'Q'],
displayAcceptedCharacters: false,
logger: globals.logger, logger: globals.logger,
prompt: userMessages.flutterChooseOne); prompt: userMessages.flutterChooseOne);
return result; return result;

View File

@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/artifacts.dart';
@ -208,7 +209,8 @@ void main() {
]; ];
when(mockStdio.stdinHasTerminal).thenReturn(true); when(mockStdio.stdinHasTerminal).thenReturn(true);
when(globals.terminal.promptForCharInput(<String>['0', '1'], when(globals.terminal.promptForCharInput(<String>['0', '1', 'q', 'Q'],
displayAcceptedCharacters: false,
logger: globals.logger, logger: globals.logger,
prompt: globals.userMessages.flutterChooseOne) prompt: globals.userMessages.flutterChooseOne)
).thenAnswer((Invocation invocation) async => '0'); ).thenAnswer((Invocation invocation) async => '0');
@ -232,7 +234,8 @@ void main() {
]; ];
when(mockStdio.stdinHasTerminal).thenReturn(true); when(mockStdio.stdinHasTerminal).thenReturn(true);
when(globals.terminal.promptForCharInput(<String>['0', '1'], when(globals.terminal.promptForCharInput(<String>['0', '1', 'q', 'Q'],
displayAcceptedCharacters: false,
logger: globals.logger, logger: globals.logger,
prompt: globals.userMessages.flutterChooseOne) prompt: globals.userMessages.flutterChooseOne)
).thenAnswer((Invocation invocation) async => '1'); ).thenAnswer((Invocation invocation) async => '1');
@ -256,7 +259,8 @@ void main() {
]; ];
when(mockStdio.stdinHasTerminal).thenReturn(true); when(mockStdio.stdinHasTerminal).thenReturn(true);
when(globals.terminal.promptForCharInput(<String>['0', '1'], when(globals.terminal.promptForCharInput(<String>['0', '1', 'q', 'Q'],
displayAcceptedCharacters: false,
logger: globals.logger, logger: globals.logger,
prompt: globals.userMessages.flutterChooseOne) prompt: globals.userMessages.flutterChooseOne)
).thenAnswer((Invocation invocation) async => '0'); ).thenAnswer((Invocation invocation) async => '0');
@ -280,7 +284,8 @@ void main() {
]; ];
when(mockStdio.stdinHasTerminal).thenReturn(true); when(mockStdio.stdinHasTerminal).thenReturn(true);
when(globals.terminal.promptForCharInput(<String>['0', '1'], when(globals.terminal.promptForCharInput(<String>['0', '1', 'q', 'Q'],
displayAcceptedCharacters: false,
logger: globals.logger, logger: globals.logger,
prompt: globals.userMessages.flutterChooseOne) prompt: globals.userMessages.flutterChooseOne)
).thenAnswer((Invocation invocation) async => '1'); ).thenAnswer((Invocation invocation) async => '1');
@ -307,7 +312,8 @@ void main() {
]; ];
when(mockStdio.stdinHasTerminal).thenReturn(true); when(mockStdio.stdinHasTerminal).thenReturn(true);
when(globals.terminal.promptForCharInput(<String>['0', '1', '2', '3'], when(globals.terminal.promptForCharInput(<String>['0', '1', '2', '3', 'q', 'Q'],
displayAcceptedCharacters: false,
logger: globals.logger, logger: globals.logger,
prompt: globals.userMessages.flutterChooseOne) prompt: globals.userMessages.flutterChooseOne)
).thenAnswer((Invocation invocation) async => '2'); ).thenAnswer((Invocation invocation) async => '2');
@ -325,6 +331,33 @@ void main() {
Cache: () => cache, Cache: () => cache,
}); });
testUsingContext('exit from choose one of available devices', () async {
final List<Device> devices = <Device>[
ephemeralOne,
ephemeralTwo,
];
when(mockStdio.stdinHasTerminal).thenReturn(true);
when(globals.terminal.promptForCharInput(<String>['0', '1', 'q', 'Q'],
displayAcceptedCharacters: false,
logger: globals.logger,
prompt: globals.userMessages.flutterChooseOne)
).thenAnswer((Invocation invocation) async => 'q');
try {
final DeviceManager deviceManager = TestDeviceManager(devices);
await deviceManager.findTargetDevices(FlutterProject.current());
} on ToolExit catch (e) {
expect(e.exitCode, null);
expect(e.message, '');
}
}, overrides: <Type, Generator>{
Stdio: () => mockStdio,
AnsiTerminal: () => MockTerminal(),
Artifacts: () => Artifacts.test(),
Cache: () => cache,
});
testUsingContext('Removes a single unsupported device', () async { testUsingContext('Removes a single unsupported device', () async {
final List<Device> devices = <Device>[ final List<Device> devices = <Device>[
unsupported, unsupported,