Commit 34e466f1 authored by Dan Rubel's avatar Dan Rubel Committed by GitHub

Refactor flutter command exit code - part 3 of 3 (#6838)

* Remove the workaround that pinned args to v0.13.6
This reverts most of the changes in commit 6331b6c8
* throw exception if exit code is not an integer
* rework command infrastructure to throw ToolExit when non-zero exitCode
* convert commands to return Future<Null>
* cleanup remaining commands to use throwToolExit for non-zero exit code
* remove isUnusual exception message
* add type annotations for updated args package
parent ece851d5
name: flutter_automated_tests name: flutter_automated_tests
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
flutter_test: flutter_test:
......
...@@ -2,12 +2,6 @@ name: complex_layout ...@@ -2,12 +2,6 @@ name: complex_layout
description: A new flutter project. description: A new flutter project.
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
flutter_driver: flutter_driver:
......
name: microbenchmarks name: microbenchmarks
description: A new flutter project. description: A new flutter project.
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
flutter_test: flutter_test:
......
...@@ -8,12 +8,7 @@ environment: ...@@ -8,12 +8,7 @@ environment:
sdk: '>=1.12.0 <2.0.0' sdk: '>=1.12.0 <2.0.0'
dependencies: dependencies:
args: ^0.13.4
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
meta: ^1.0.3 meta: ^1.0.3
path: ^1.3.0 path: ^1.3.0
stack_trace: ^1.4.0 stack_trace: ^1.4.0
......
name: flutter_manual_tests name: flutter_manual_tests
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
......
...@@ -2,10 +2,5 @@ name: dev_tools ...@@ -2,10 +2,5 @@ name: dev_tools
description: Various repository development tools for flutter. description: Various repository development tools for flutter.
dependencies: dependencies:
args: ^0.13.4
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
path: ^1.3.0 path: ^1.3.0
name: flutter_gallery name: flutter_gallery
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
collection: '>=1.9.1 <2.0.0' collection: '>=1.9.1 <2.0.0'
intl: '>=0.14.0 <0.15.0' intl: '>=0.14.0 <0.15.0'
string_scanner: ^1.0.0 string_scanner: ^1.0.0
......
name: hello_services name: hello_services
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
......
name: hello_world name: hello_world
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
......
name: flutter_examples_layers name: flutter_examples_layers
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
......
name: stocks name: stocks
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
intl: '>=0.14.0 <0.15.0' intl: '>=0.14.0 <0.15.0'
......
...@@ -5,12 +5,6 @@ description: A framework for writing Flutter applications ...@@ -5,12 +5,6 @@ description: A framework for writing Flutter applications
homepage: http://flutter.io homepage: http://flutter.io
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
collection: '>=1.9.1 <2.0.0' collection: '>=1.9.1 <2.0.0'
intl: '>=0.14.0 <0.15.0' intl: '>=0.14.0 <0.15.0'
meta: ^1.0.3 meta: ^1.0.3
......
...@@ -8,12 +8,6 @@ environment: ...@@ -8,12 +8,6 @@ environment:
sdk: '>=1.19.0 <2.0.0' sdk: '>=1.19.0 <2.0.0'
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
file: '^0.1.0' file: '^0.1.0'
json_rpc_2: '^2.0.0' json_rpc_2: '^2.0.0'
matcher: '>=0.12.0 <1.0.0' matcher: '>=0.12.0 <1.0.0'
......
...@@ -5,12 +5,6 @@ author: Flutter Authors <flutter-dev@googlegroups.com> ...@@ -5,12 +5,6 @@ author: Flutter Authors <flutter-dev@googlegroups.com>
homepage: http://flutter.io homepage: http://flutter.io
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
flutter: flutter:
sdk: flutter sdk: flutter
markdown: '^0.9.0' markdown: '^0.9.0'
......
name: flutter_test name: flutter_test
dependencies: dependencies:
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
quiver: ^0.21.4 quiver: ^0.21.4
# The flutter tools depend on very specific internal implementation # The flutter tools depend on very specific internal implementation
......
...@@ -94,8 +94,8 @@ Future<Null> main(List<String> args) async { ...@@ -94,8 +94,8 @@ Future<Null> main(List<String> args) async {
if (context[HotRunnerConfig] == null) if (context[HotRunnerConfig] == null)
context[HotRunnerConfig] = new HotRunnerConfig(); context[HotRunnerConfig] = new HotRunnerConfig();
dynamic result = await runner.run(args); await runner.run(args);
_exit(result is int ? result : 1); _exit(0);
}, onError: (dynamic error, Chain chain) { }, onError: (dynamic error, Chain chain) {
if (error is UsageException) { if (error is UsageException) {
stderr.writeln(error.message); stderr.writeln(error.message);
...@@ -114,10 +114,6 @@ Future<Null> main(List<String> args) async { ...@@ -114,10 +114,6 @@ Future<Null> main(List<String> args) async {
stderr.writeln(chain.terse.toString()); stderr.writeln(chain.terse.toString());
stderr.writeln(); stderr.writeln();
} }
if (error.isUnusual) {
stderr.writeln('If this problem persists, please report the problem at');
stderr.writeln('https://github.com/flutter/flutter/issues/new');
}
_exit(error.exitCode ?? 1); _exit(error.exitCode ?? 1);
} else if (error is ProcessExit) { } else if (error is ProcessExit) {
// We've caught an exit code. // We've caught an exit code.
......
...@@ -27,8 +27,8 @@ String _homeDirPath; ...@@ -27,8 +27,8 @@ String _homeDirPath;
/// where the tool should exit with a clear message to the user /// where the tool should exit with a clear message to the user
/// and no stack trace unless the --verbose option is specified. /// and no stack trace unless the --verbose option is specified.
/// For example: network errors /// For example: network errors
void throwToolExit(String message, { int exitCode, bool isUnusual: false }) { void throwToolExit(String message, { int exitCode }) {
throw new ToolExit(message, exitCode: exitCode, isUnusual: isUnusual); throw new ToolExit(message, exitCode: exitCode );
} }
/// Specialized exception for expected situations /// Specialized exception for expected situations
...@@ -37,11 +37,10 @@ void throwToolExit(String message, { int exitCode, bool isUnusual: false }) { ...@@ -37,11 +37,10 @@ void throwToolExit(String message, { int exitCode, bool isUnusual: false }) {
/// For example: network errors /// For example: network errors
class ToolExit implements Exception { class ToolExit implements Exception {
ToolExit(this.message, { this.exitCode, this.isUnusual: false }); ToolExit(this.message, { this.exitCode });
final String message; final String message;
final int exitCode; final int exitCode;
final bool isUnusual;
@override @override
String toString() => "Exception: $message"; String toString() => "Exception: $message";
......
...@@ -24,7 +24,6 @@ Future<List<int>> fetchUrl(Uri url) async { ...@@ -24,7 +24,6 @@ Future<List<int>> fetchUrl(Uri url) async {
'Download failed: $url\n' 'Download failed: $url\n'
' because (${response.statusCode}) ${response.reasonPhrase}', ' because (${response.statusCode}) ${response.reasonPhrase}',
exitCode: kNetworkProblemExitCode, exitCode: kNetworkProblemExitCode,
isUnusual: true,
); );
} }
...@@ -38,7 +37,6 @@ Future<List<int>> fetchUrl(Uri url) async { ...@@ -38,7 +37,6 @@ Future<List<int>> fetchUrl(Uri url) async {
throw new ToolExit( throw new ToolExit(
'Download failed: $url\n $e', 'Download failed: $url\n $e',
exitCode: kNetworkProblemExitCode, exitCode: kNetworkProblemExitCode,
isUnusual: true,
); );
} }
} }
...@@ -53,7 +53,7 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -53,7 +53,7 @@ class AnalyzeCommand extends FlutterCommand {
} }
@override @override
Future<int> runCommand() { Future<Null> runCommand() {
if (argResults['watch']) { if (argResults['watch']) {
return new AnalyzeContinuously(argResults, runner.getRepoAnalysisEntryPoints()).analyze(); return new AnalyzeContinuously(argResults, runner.getRepoAnalysisEntryPoints()).analyze();
} else { } else {
......
...@@ -20,7 +20,7 @@ abstract class AnalyzeBase { ...@@ -20,7 +20,7 @@ abstract class AnalyzeBase {
AnalyzeBase(this.argResults); AnalyzeBase(this.argResults);
/// Called by [AnalyzeCommand] to start the analysis process. /// Called by [AnalyzeCommand] to start the analysis process.
Future<int> analyze(); Future<Null> analyze();
void dumpErrors(Iterable<String> errors) { void dumpErrors(Iterable<String> errors) {
if (argResults['write'] != null) { if (argResults['write'] != null) {
......
...@@ -31,7 +31,7 @@ class AnalyzeContinuously extends AnalyzeBase { ...@@ -31,7 +31,7 @@ class AnalyzeContinuously extends AnalyzeBase {
Status analysisStatus; Status analysisStatus;
@override @override
Future<int> analyze() async { Future<Null> analyze() async {
List<String> directories; List<String> directories;
if (argResults['flutter-repo']) { if (argResults['flutter-repo']) {
...@@ -58,7 +58,6 @@ class AnalyzeContinuously extends AnalyzeBase { ...@@ -58,7 +58,6 @@ class AnalyzeContinuously extends AnalyzeBase {
if (exitCode != 0) if (exitCode != 0)
throwToolExit(message, exitCode: exitCode); throwToolExit(message, exitCode: exitCode);
printStatus(message); printStatus(message);
return 0;
} }
void _handleAnalysisStatus(AnalysisServer server, bool isAnalyzing) { void _handleAnalysisStatus(AnalysisServer server, bool isAnalyzing) {
......
...@@ -28,7 +28,7 @@ class AnalyzeOnce extends AnalyzeBase { ...@@ -28,7 +28,7 @@ class AnalyzeOnce extends AnalyzeBase {
AnalyzeOnce(ArgResults argResults, this.repoPackages) : super(argResults); AnalyzeOnce(ArgResults argResults, this.repoPackages) : super(argResults);
@override @override
Future<int> analyze() async { Future<Null> analyze() async {
Stopwatch stopwatch = new Stopwatch()..start(); Stopwatch stopwatch = new Stopwatch()..start();
Set<Directory> pubSpecDirectories = new HashSet<Directory>(); Set<Directory> pubSpecDirectories = new HashSet<Directory>();
List<File> dartFiles = <File>[]; List<File> dartFiles = <File>[];
...@@ -205,7 +205,6 @@ class AnalyzeOnce extends AnalyzeBase { ...@@ -205,7 +205,6 @@ class AnalyzeOnce extends AnalyzeBase {
printStatus('No analyzer warnings! (ran in ${elapsed}s)'); printStatus('No analyzer warnings! (ran in ${elapsed}s)');
} }
} }
return 0;
} }
List<String> flutterRootComponents; List<String> flutterRootComponents;
......
...@@ -33,26 +33,26 @@ class BuildCommand extends FlutterCommand { ...@@ -33,26 +33,26 @@ class BuildCommand extends FlutterCommand {
final String description = 'Flutter build commands.'; final String description = 'Flutter build commands.';
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
commandValidator(); commandValidator();
return super.verifyThenRunCommand(); return super.verifyThenRunCommand();
} }
@override @override
Future<int> runCommand() => new Future<int>.value(0); Future<Null> runCommand() async { }
} }
abstract class BuildSubCommand extends FlutterCommand { abstract class BuildSubCommand extends FlutterCommand {
@override @override
@mustCallSuper @mustCallSuper
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
commandValidator(); commandValidator();
return super.verifyThenRunCommand(); return super.verifyThenRunCommand();
} }
@override @override
@mustCallSuper @mustCallSuper
Future<int> runCommand() async { Future<Null> runCommand() async {
if (isRunningOnBot) { if (isRunningOnBot) {
File dotPackages = new File('.packages'); File dotPackages = new File('.packages');
printStatus('Contents of .packages:'); printStatus('Contents of .packages:');
...@@ -68,7 +68,6 @@ abstract class BuildSubCommand extends FlutterCommand { ...@@ -68,7 +68,6 @@ abstract class BuildSubCommand extends FlutterCommand {
else else
printError('File not found: ${pubspecLock.absolute.path}'); printError('File not found: ${pubspecLock.absolute.path}');
} }
return 0;
} }
} }
...@@ -80,24 +79,23 @@ class BuildCleanCommand extends FlutterCommand { ...@@ -80,24 +79,23 @@ class BuildCleanCommand extends FlutterCommand {
final String description = 'Delete the build/ directory.'; final String description = 'Delete the build/ directory.';
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
commandValidator(); commandValidator();
return super.verifyThenRunCommand(); return super.verifyThenRunCommand();
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
Directory buildDir = new Directory(getBuildDirectory()); Directory buildDir = new Directory(getBuildDirectory());
printStatus("Deleting '${buildDir.path}${Platform.pathSeparator}'."); printStatus("Deleting '${buildDir.path}${Platform.pathSeparator}'.");
if (!buildDir.existsSync()) if (!buildDir.existsSync())
return 0; return;
try { try {
buildDir.deleteSync(recursive: true); buildDir.deleteSync(recursive: true);
} catch (error) { } catch (error) {
throwToolExit(error.toString()); throwToolExit(error.toString());
} }
return 0;
} }
} }
...@@ -43,7 +43,7 @@ class BuildAotCommand extends BuildSubCommand { ...@@ -43,7 +43,7 @@ class BuildAotCommand extends BuildSubCommand {
final String description = "Build an ahead-of-time compiled snapshot of your app's Dart code."; final String description = "Build an ahead-of-time compiled snapshot of your app's Dart code.";
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
await super.runCommand(); await super.runCommand();
String targetPlatform = argResults['target-platform']; String targetPlatform = argResults['target-platform'];
TargetPlatform platform = getTargetPlatformForName(targetPlatform); TargetPlatform platform = getTargetPlatformForName(targetPlatform);
...@@ -65,7 +65,6 @@ class BuildAotCommand extends BuildSubCommand { ...@@ -65,7 +65,6 @@ class BuildAotCommand extends BuildSubCommand {
throwToolExit(null); throwToolExit(null);
printStatus('Built to $outputPath${Platform.pathSeparator}.'); printStatus('Built to $outputPath${Platform.pathSeparator}.');
return 0;
} }
} }
......
...@@ -224,7 +224,7 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -224,7 +224,7 @@ class BuildApkCommand extends BuildSubCommand {
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
await super.runCommand(); await super.runCommand();
TargetPlatform targetPlatform = _getTargetPlatform(argResults['target-arch']); TargetPlatform targetPlatform = _getTargetPlatform(argResults['target-arch']);
...@@ -258,7 +258,6 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -258,7 +258,6 @@ class BuildApkCommand extends BuildSubCommand {
) )
); );
} }
return 0;
} }
} }
......
...@@ -37,7 +37,7 @@ class BuildFlxCommand extends BuildSubCommand { ...@@ -37,7 +37,7 @@ class BuildFlxCommand extends BuildSubCommand {
'they are used by some Flutter Android and iOS runtimes.'; 'they are used by some Flutter Android and iOS runtimes.';
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
await super.runCommand(); await super.runCommand();
String outputPath = argResults['output-file']; String outputPath = argResults['output-file'];
...@@ -53,6 +53,5 @@ class BuildFlxCommand extends BuildSubCommand { ...@@ -53,6 +53,5 @@ class BuildFlxCommand extends BuildSubCommand {
includeRobotoFonts: argResults['include-roboto-fonts'], includeRobotoFonts: argResults['include-roboto-fonts'],
reportLicensedPackages: argResults['report-licensed-packages'] reportLicensedPackages: argResults['report-licensed-packages']
); );
return 0;
} }
} }
...@@ -39,7 +39,7 @@ class BuildIOSCommand extends BuildSubCommand { ...@@ -39,7 +39,7 @@ class BuildIOSCommand extends BuildSubCommand {
final String description = 'Build an iOS application bundle (Mac OS X host only).'; final String description = 'Build an iOS application bundle (Mac OS X host only).';
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
bool forSimulator = argResults['simulator']; bool forSimulator = argResults['simulator'];
defaultBuildMode = forSimulator ? BuildMode.debug : BuildMode.release; defaultBuildMode = forSimulator ? BuildMode.debug : BuildMode.release;
...@@ -83,7 +83,5 @@ class BuildIOSCommand extends BuildSubCommand { ...@@ -83,7 +83,5 @@ class BuildIOSCommand extends BuildSubCommand {
if (result.output != null) if (result.output != null)
printStatus('Built ${result.output}.'); printStatus('Built ${result.output}.');
return 0;
} }
} }
...@@ -21,7 +21,7 @@ class ChannelCommand extends FlutterCommand { ...@@ -21,7 +21,7 @@ class ChannelCommand extends FlutterCommand {
String get invocation => '${runner.executableName} $name [<channel-name>]'; String get invocation => '${runner.executableName} $name [<channel-name>]';
@override @override
Future<int> runCommand() { Future<Null> runCommand() {
switch (argResults.rest.length) { switch (argResults.rest.length) {
case 0: case 0:
return _listChannels(); return _listChannels();
...@@ -32,7 +32,7 @@ class ChannelCommand extends FlutterCommand { ...@@ -32,7 +32,7 @@ class ChannelCommand extends FlutterCommand {
} }
} }
Future<int> _listChannels() async { Future<Null> _listChannels() async {
String currentBranch = runSync( String currentBranch = runSync(
<String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'], <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
workingDirectory: Cache.flutterRoot); workingDirectory: Cache.flutterRoot);
...@@ -52,10 +52,9 @@ class ChannelCommand extends FlutterCommand { ...@@ -52,10 +52,9 @@ class ChannelCommand extends FlutterCommand {
); );
if (result != 0) if (result != 0)
throwToolExit('List channels failed: $result', exitCode: result); throwToolExit('List channels failed: $result', exitCode: result);
return 0;
} }
Future<int> _switchChannel(String branchName) async { Future<Null> _switchChannel(String branchName) async {
printStatus('Switching to flutter channel named $branchName'); printStatus('Switching to flutter channel named $branchName');
int result = await runCommandAndStreamOutput( int result = await runCommandAndStreamOutput(
<String>['git', 'checkout', branchName], <String>['git', 'checkout', branchName],
...@@ -63,6 +62,5 @@ class ChannelCommand extends FlutterCommand { ...@@ -63,6 +62,5 @@ class ChannelCommand extends FlutterCommand {
); );
if (result != 0) if (result != 0)
throwToolExit('Switch channel failed: $result', exitCode: result); throwToolExit('Switch channel failed: $result', exitCode: result);
return 0;
} }
} }
...@@ -46,7 +46,7 @@ class ConfigCommand extends FlutterCommand { ...@@ -46,7 +46,7 @@ class ConfigCommand extends FlutterCommand {
String get usagePath => null; String get usagePath => null;
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
if (argResults.wasParsed('analytics')) { if (argResults.wasParsed('analytics')) {
bool value = argResults['analytics']; bool value = argResults['analytics'];
flutterUsage.enabled = value; flutterUsage.enabled = value;
...@@ -61,8 +61,6 @@ class ConfigCommand extends FlutterCommand { ...@@ -61,8 +61,6 @@ class ConfigCommand extends FlutterCommand {
if (argResults.arguments.isEmpty) if (argResults.arguments.isEmpty)
printStatus(usage); printStatus(usage);
return 0;
} }
void _updateConfig(String keyName, String keyValue) { void _updateConfig(String keyName, String keyValue) {
......
...@@ -46,7 +46,7 @@ class CreateCommand extends FlutterCommand { ...@@ -46,7 +46,7 @@ class CreateCommand extends FlutterCommand {
String get invocation => "${runner.executableName} $name <output directory>"; String get invocation => "${runner.executableName} $name <output directory>";
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
if (argResults.rest.isEmpty) if (argResults.rest.isEmpty)
throwToolExit('No option specified for the output directory.\n$usage', exitCode: 2); throwToolExit('No option specified for the output directory.\n$usage', exitCode: 2);
...@@ -134,7 +134,6 @@ Your main program file is lib/main.dart in the $relativePath directory. ...@@ -134,7 +134,6 @@ Your main program file is lib/main.dart in the $relativePath directory.
"directory in order to launch your app."); "directory in order to launch your app.");
printStatus("Your main program file is: $relativePath/lib/main.dart"); printStatus("Your main program file is: $relativePath/lib/main.dart");
} }
return 0;
} }
int _renderTemplates(String projectName, String projectDescription, String dirPath, int _renderTemplates(String projectName, String projectDescription, String dirPath,
......
...@@ -43,7 +43,7 @@ class DaemonCommand extends FlutterCommand { ...@@ -43,7 +43,7 @@ class DaemonCommand extends FlutterCommand {
final bool hidden; final bool hidden;
@override @override
Future<int> runCommand() { Future<Null> runCommand() {
printStatus('Starting device daemon...'); printStatus('Starting device daemon...');
AppContext appContext = new AppContext(); AppContext appContext = new AppContext();
...@@ -60,7 +60,6 @@ class DaemonCommand extends FlutterCommand { ...@@ -60,7 +60,6 @@ class DaemonCommand extends FlutterCommand {
int code = await daemon.onExit; int code = await daemon.onExit;
if (code != null) if (code != null)
throwToolExit(null, exitCode: code); throwToolExit(null, exitCode: code);
return 0;
}, onError: _handleError); }, onError: _handleError);
} }
......
...@@ -18,7 +18,7 @@ class DevicesCommand extends FlutterCommand { ...@@ -18,7 +18,7 @@ class DevicesCommand extends FlutterCommand {
final String description = 'List all connected devices.'; final String description = 'List all connected devices.';
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
if (!doctor.canListAnything) { if (!doctor.canListAnything) {
throwToolExit( throwToolExit(
"Unable to locate a development device; please run 'flutter doctor' for " "Unable to locate a development device; please run 'flutter doctor' for "
...@@ -37,6 +37,5 @@ class DevicesCommand extends FlutterCommand { ...@@ -37,6 +37,5 @@ class DevicesCommand extends FlutterCommand {
printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n'); printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n');
Device.printDevices(devices); Device.printDevices(devices);
} }
return 0;
} }
} }
...@@ -15,8 +15,7 @@ class DoctorCommand extends FlutterCommand { ...@@ -15,8 +15,7 @@ class DoctorCommand extends FlutterCommand {
final String description = 'Show information about the installed tooling.'; final String description = 'Show information about the installed tooling.';
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
await doctor.diagnose(); await doctor.diagnose();
return 0;
} }
} }
...@@ -90,13 +90,13 @@ class DriveCommand extends RunCommandBase { ...@@ -90,13 +90,13 @@ class DriveCommand extends RunCommandBase {
int get debugPort => int.parse(argResults['debug-port']); int get debugPort => int.parse(argResults['debug-port']);
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
commandValidator(); commandValidator();
return super.verifyThenRunCommand(); return super.verifyThenRunCommand();
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
String testFile = _getTestFile(); String testFile = _getTestFile();
if (testFile == null) if (testFile == null)
throwToolExit(null); throwToolExit(null);
...@@ -149,7 +149,6 @@ class DriveCommand extends RunCommandBase { ...@@ -149,7 +149,6 @@ class DriveCommand extends RunCommandBase {
printStatus('Leaving the application running.'); printStatus('Leaving the application running.');
} }
} }
return 0;
} }
String _getTestFile() { String _getTestFile() {
......
...@@ -25,7 +25,7 @@ class FormatCommand extends FlutterCommand { ...@@ -25,7 +25,7 @@ class FormatCommand extends FlutterCommand {
String get invocation => "${runner.executableName} $name <one or more paths>"; String get invocation => "${runner.executableName} $name <one or more paths>";
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
if (argResults.rest.isEmpty) { if (argResults.rest.isEmpty) {
throwToolExit( throwToolExit(
'No files specified to be formatted.\n' 'No files specified to be formatted.\n'
...@@ -43,6 +43,5 @@ class FormatCommand extends FlutterCommand { ...@@ -43,6 +43,5 @@ class FormatCommand extends FlutterCommand {
int result = await runCommandAndStreamOutput(cmd); int result = await runCommandAndStreamOutput(cmd);
if (result != 0) if (result != 0)
throwToolExit('Formatting failed: $result', exitCode: result); throwToolExit('Formatting failed: $result', exitCode: result);
return 0;
} }
} }
...@@ -21,7 +21,7 @@ class InstallCommand extends FlutterCommand { ...@@ -21,7 +21,7 @@ class InstallCommand extends FlutterCommand {
Device device; Device device;
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
commandValidator(); commandValidator();
device = await findTargetDevice(); device = await findTargetDevice();
if (device == null) if (device == null)
...@@ -30,7 +30,7 @@ class InstallCommand extends FlutterCommand { ...@@ -30,7 +30,7 @@ class InstallCommand extends FlutterCommand {
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform); ApplicationPackage package = applicationPackages.getPackageForPlatform(device.platform);
Cache.releaseLockEarly(); Cache.releaseLockEarly();
...@@ -39,7 +39,6 @@ class InstallCommand extends FlutterCommand { ...@@ -39,7 +39,6 @@ class InstallCommand extends FlutterCommand {
if (!installApp(device, package)) if (!installApp(device, package))
throwToolExit('Install failed'); throwToolExit('Install failed');
return 0;
} }
} }
......
...@@ -29,7 +29,7 @@ class LogsCommand extends FlutterCommand { ...@@ -29,7 +29,7 @@ class LogsCommand extends FlutterCommand {
Device device; Device device;
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
device = await findTargetDevice(); device = await findTargetDevice();
if (device == null) if (device == null)
throwToolExit(null); throwToolExit(null);
...@@ -37,7 +37,7 @@ class LogsCommand extends FlutterCommand { ...@@ -37,7 +37,7 @@ class LogsCommand extends FlutterCommand {
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
if (argResults['clear']) if (argResults['clear'])
device.clearLogs(); device.clearLogs();
...@@ -76,6 +76,5 @@ class LogsCommand extends FlutterCommand { ...@@ -76,6 +76,5 @@ class LogsCommand extends FlutterCommand {
subscription.cancel(); subscription.cancel();
if (result != 0) if (result != 0)
throwToolExit('Error listening to $logReader logs.'); throwToolExit('Error listening to $logReader logs.');
return 0;
} }
} }
...@@ -25,13 +25,13 @@ class PackagesCommand extends FlutterCommand { ...@@ -25,13 +25,13 @@ class PackagesCommand extends FlutterCommand {
final String description = 'Commands for managing Flutter packages.'; final String description = 'Commands for managing Flutter packages.';
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
commandValidator(); commandValidator();
return super.verifyThenRunCommand(); return super.verifyThenRunCommand();
} }
@override @override
Future<int> runCommand() => new Future<int>.value(0); Future<Null> runCommand() async { }
} }
class PackagesGetCommand extends FlutterCommand { class PackagesGetCommand extends FlutterCommand {
...@@ -52,7 +52,7 @@ class PackagesGetCommand extends FlutterCommand { ...@@ -52,7 +52,7 @@ class PackagesGetCommand extends FlutterCommand {
"${runner.executableName} packages $name [<target directory>]"; "${runner.executableName} packages $name [<target directory>]";
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
if (argResults.rest.length > 1) if (argResults.rest.length > 1)
throwToolExit('Too many arguments.\n$usage'); throwToolExit('Too many arguments.\n$usage');
...@@ -69,6 +69,5 @@ class PackagesGetCommand extends FlutterCommand { ...@@ -69,6 +69,5 @@ class PackagesGetCommand extends FlutterCommand {
// TODO: If the user is using a local build, we should use the packages from their build instead of the cache. // TODO: If the user is using a local build, we should use the packages from their build instead of the cache.
await pubGet(directory: target, upgrade: upgrade, checkLastModified: false); await pubGet(directory: target, upgrade: upgrade, checkLastModified: false);
return 0;
} }
} }
...@@ -20,7 +20,7 @@ class PrecacheCommand extends FlutterCommand { ...@@ -20,7 +20,7 @@ class PrecacheCommand extends FlutterCommand {
final String description = 'Populates the Flutter tool\'s cache of binary artifacts.'; final String description = 'Populates the Flutter tool\'s cache of binary artifacts.';
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
if (argResults['all-platforms']) if (argResults['all-platforms'])
cache.includeAllPlatforms = true; cache.includeAllPlatforms = true;
...@@ -28,7 +28,5 @@ class PrecacheCommand extends FlutterCommand { ...@@ -28,7 +28,5 @@ class PrecacheCommand extends FlutterCommand {
printStatus('Already up-to-date.'); printStatus('Already up-to-date.');
else else
await cache.updateAll(); await cache.updateAll();
return 0;
} }
} }
...@@ -148,7 +148,7 @@ class RunCommand extends RunCommandBase { ...@@ -148,7 +148,7 @@ class RunCommand extends RunCommandBase {
argResults['use-application-binary'] != null; argResults['use-application-binary'] != null;
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
commandValidator(); commandValidator();
device = await findTargetDevice(); device = await findTargetDevice();
if (device == null) if (device == null)
...@@ -157,7 +157,7 @@ class RunCommand extends RunCommandBase { ...@@ -157,7 +157,7 @@ class RunCommand extends RunCommandBase {
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
...@@ -238,6 +238,5 @@ class RunCommand extends RunCommandBase { ...@@ -238,6 +238,5 @@ class RunCommand extends RunCommandBase {
); );
if (result != 0) if (result != 0)
throwToolExit(null, exitCode: result); throwToolExit(null, exitCode: result);
return 0;
} }
} }
...@@ -52,7 +52,7 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -52,7 +52,7 @@ class ScreenshotCommand extends FlutterCommand {
Device device; Device device;
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
if (argResults[_kSkia] != null) { if (argResults[_kSkia] != null) {
if (argResults[_kOut] != null && argResults[_kSkiaServe] != null) if (argResults[_kOut] != null && argResults[_kSkiaServe] != null)
throwToolExit('Cannot specify both --$_kOut and --$_kSkiaServe'); throwToolExit('Cannot specify both --$_kOut and --$_kSkiaServe');
...@@ -69,7 +69,7 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -69,7 +69,7 @@ class ScreenshotCommand extends FlutterCommand {
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
File outputFile; File outputFile;
if (argResults.wasParsed(_kOut)) if (argResults.wasParsed(_kOut))
outputFile = new File(argResults[_kOut]); outputFile = new File(argResults[_kOut]);
...@@ -81,7 +81,7 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -81,7 +81,7 @@ class ScreenshotCommand extends FlutterCommand {
} }
} }
Future<int> runScreenshot(File outputFile) async { Future<Null> runScreenshot(File outputFile) async {
outputFile ??= getUniqueFile(Directory.current, 'flutter', 'png'); outputFile ??= getUniqueFile(Directory.current, 'flutter', 'png');
try { try {
if (!await device.takeScreenshot(outputFile)) if (!await device.takeScreenshot(outputFile))
...@@ -90,10 +90,9 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -90,10 +90,9 @@ class ScreenshotCommand extends FlutterCommand {
throwToolExit('Error taking screenshot: $error'); throwToolExit('Error taking screenshot: $error');
} }
await showOutputFileInfo(outputFile); await showOutputFileInfo(outputFile);
return 0;
} }
Future<int> runSkia(File outputFile) async { Future<Null> runSkia(File outputFile) async {
Uri skpUri = new Uri(scheme: 'http', host: '127.0.0.1', Uri skpUri = new Uri(scheme: 'http', host: '127.0.0.1',
port: int.parse(argResults[_kSkia]), port: int.parse(argResults[_kSkia]),
path: '/skp'); path: '/skp');
...@@ -136,7 +135,6 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -136,7 +135,6 @@ class ScreenshotCommand extends FlutterCommand {
throwToolExit('\nIt appears the output file contains an error message, not valid skia output.\n\n$errorHelpText'); throwToolExit('\nIt appears the output file contains an error message, not valid skia output.\n\n$errorHelpText');
} }
} }
return 0;
} }
Future<Null> showOutputFileInfo(File outputFile) async { Future<Null> showOutputFileInfo(File outputFile) async {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import '../base/common.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../globals.dart'; import '../globals.dart';
...@@ -26,7 +27,7 @@ class SetupCommand extends FlutterCommand { ...@@ -26,7 +27,7 @@ class SetupCommand extends FlutterCommand {
final bool hidden; final bool hidden;
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
printStatus('Running Flutter setup...'); printStatus('Running Flutter setup...');
// setup brew on mac // setup brew on mac
...@@ -57,9 +58,9 @@ class SetupCommand extends FlutterCommand { ...@@ -57,9 +58,9 @@ class SetupCommand extends FlutterCommand {
printStatus('\nThe flutter command is available on the path.'); printStatus('\nThe flutter command is available on the path.');
} }
if (goodInstall) if (!goodInstall)
printStatus('\nFlutter setup complete!'); throwToolExit(null);
return goodInstall ? 0 : 1; printStatus('\nFlutter setup complete!');
} }
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'dart:async'; import 'dart:async';
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../device.dart'; import '../device.dart';
import '../globals.dart'; import '../globals.dart';
...@@ -20,24 +21,23 @@ class StopCommand extends FlutterCommand { ...@@ -20,24 +21,23 @@ class StopCommand extends FlutterCommand {
Device device; Device device;
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
if (!commandValidator()) commandValidator();
return 1;
device = await findTargetDevice(); device = await findTargetDevice();
if (device == null) if (device == null)
return 1; throwToolExit(null);
return super.verifyThenRunCommand(); return super.verifyThenRunCommand();
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
ApplicationPackage app = applicationPackages.getPackageForPlatform(device.platform); ApplicationPackage app = applicationPackages.getPackageForPlatform(device.platform);
if (app == null) { if (app == null) {
String platformName = getNameForTargetPlatform(device.platform); String platformName = getNameForTargetPlatform(device.platform);
printError('No Flutter application for $platformName found in the current directory.'); throwToolExit('No Flutter application for $platformName found in the current directory.');
return 1;
} }
printStatus('Stopping apps on ${device.name}.'); printStatus('Stopping apps on ${device.name}.');
return await device.stopApp(app) ? 0 : 1; if (!await device.stopApp(app))
throwToolExit(null);
} }
} }
...@@ -8,6 +8,7 @@ import 'dart:io'; ...@@ -8,6 +8,7 @@ import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:test/src/executable.dart' as executable; // ignore: implementation_imports import 'package:test/src/executable.dart' as executable; // ignore: implementation_imports
import '../base/common.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../cache.dart'; import '../cache.dart';
...@@ -38,14 +39,12 @@ class TestCommand extends FlutterCommand { ...@@ -38,14 +39,12 @@ class TestCommand extends FlutterCommand {
); );
commandValidator = () { commandValidator = () {
if (!FileSystemEntity.isFileSync('pubspec.yaml')) { if (!FileSystemEntity.isFileSync('pubspec.yaml')) {
printError( throwToolExit(
'Error: No pubspec.yaml file found in the current working directory.\n' 'Error: No pubspec.yaml file found in the current working directory.\n'
'Run this command from the root of your project. Test files must be\n' 'Run this command from the root of your project. Test files must be\n'
'called *_test.dart and must reside in the package\'s \'test\'\n' 'called *_test.dart and must reside in the package\'s \'test\'\n'
'directory (or one of its subdirectories).'); 'directory (or one of its subdirectories).');
return false;
} }
return true;
}; };
} }
...@@ -142,20 +141,17 @@ class TestCommand extends FlutterCommand { ...@@ -142,20 +141,17 @@ class TestCommand extends FlutterCommand {
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
List<String> testArgs = argResults.rest.map((String testPath) => path.absolute(testPath)).toList(); List<String> testArgs = argResults.rest.map((String testPath) => path.absolute(testPath)).toList();
if (!commandValidator()) commandValidator();
return 1;
Directory testDir; Directory testDir;
if (testArgs.isEmpty) { if (testArgs.isEmpty) {
testDir = _currentPackageTestDir; testDir = _currentPackageTestDir;
if (!testDir.existsSync()) { if (!testDir.existsSync())
printError("Test directory '${testDir.path}' not found."); throwToolExit("Test directory '${testDir.path}' not found.");
return 1;
}
testArgs.addAll(_findTests(testDir)); testArgs.addAll(_findTests(testDir));
} }
...@@ -169,10 +165,8 @@ class TestCommand extends FlutterCommand { ...@@ -169,10 +165,8 @@ class TestCommand extends FlutterCommand {
loader.installHook(); loader.installHook();
loader.shellPath = tools.getHostToolPath(HostTool.SkyShell); loader.shellPath = tools.getHostToolPath(HostTool.SkyShell);
if (!FileSystemEntity.isFileSync(loader.shellPath)) { if (!FileSystemEntity.isFileSync(loader.shellPath))
printError('Cannot find Flutter shell at ${loader.shellPath}'); throwToolExit('Cannot find Flutter shell at ${loader.shellPath}');
return 1;
}
Cache.releaseLockEarly(); Cache.releaseLockEarly();
...@@ -183,9 +177,10 @@ class TestCommand extends FlutterCommand { ...@@ -183,9 +177,10 @@ class TestCommand extends FlutterCommand {
if (collector.enabled) { if (collector.enabled) {
if (!await _collectCoverageData(collector, mergeCoverageData: argResults['merge-coverage'])) if (!await _collectCoverageData(collector, mergeCoverageData: argResults['merge-coverage']))
return 1; throwToolExit(null);
} }
return result; if (result != 0)
throwToolExit(null);
} }
} }
...@@ -46,14 +46,13 @@ class TraceCommand extends FlutterCommand { ...@@ -46,14 +46,13 @@ class TraceCommand extends FlutterCommand {
'with --start and later with --stop.'; 'with --start and later with --stop.';
@override @override
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
if (!commandValidator()) commandValidator();
return 1;
return super.verifyThenRunCommand(); return super.verifyThenRunCommand();
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
int observatoryPort = int.parse(argResults['debug-port']); int observatoryPort = int.parse(argResults['debug-port']);
Tracing tracing; Tracing tracing;
...@@ -61,8 +60,7 @@ class TraceCommand extends FlutterCommand { ...@@ -61,8 +60,7 @@ class TraceCommand extends FlutterCommand {
try { try {
tracing = await Tracing.connect(observatoryPort); tracing = await Tracing.connect(observatoryPort);
} catch (error) { } catch (error) {
printError('Error connecting to observatory: $error'); throwToolExit('Error connecting to observatory: $error');
return 1;
} }
Cache.releaseLockEarly(); Cache.releaseLockEarly();
...@@ -81,8 +79,6 @@ class TraceCommand extends FlutterCommand { ...@@ -81,8 +79,6 @@ class TraceCommand extends FlutterCommand {
} else { } else {
await tracing.startTracing(); await tracing.startTracing();
} }
return 0;
} }
Future<Null> _stopTracing(Tracing tracing) async { Future<Null> _stopTracing(Tracing tracing) async {
......
...@@ -46,24 +46,19 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -46,24 +46,19 @@ class UpdatePackagesCommand extends FlutterCommand {
} }
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
try { final Stopwatch timer = new Stopwatch()..start();
final Stopwatch timer = new Stopwatch()..start(); int count = 0;
int count = 0; final bool upgrade = argResults['upgrade'];
final bool upgrade = argResults['upgrade'];
for (Directory dir in runner.getRepoPackages()) { for (Directory dir in runner.getRepoPackages()) {
await pubGet(directory: dir.path, upgrade: upgrade, checkLastModified: false); await pubGet(directory: dir.path, upgrade: upgrade, checkLastModified: false);
count++; count++;
} }
await _downloadCoverageData(); await _downloadCoverageData();
final double seconds = timer.elapsedMilliseconds / 1000.0; final double seconds = timer.elapsedMilliseconds / 1000.0;
printStatus('\nRan \'pub\' $count time${count == 1 ? "" : "s"} and fetched coverage data in ${seconds.toStringAsFixed(1)}s.'); printStatus('\nRan \'pub\' $count time${count == 1 ? "" : "s"} and fetched coverage data in ${seconds.toStringAsFixed(1)}s.');
return 0;
} on int catch (code) {
return code;
}
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import '../base/common.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../dart/pub.dart'; import '../dart/pub.dart';
...@@ -21,14 +22,13 @@ class UpgradeCommand extends FlutterCommand { ...@@ -21,14 +22,13 @@ class UpgradeCommand extends FlutterCommand {
final String description = 'Upgrade your copy of Flutter.'; final String description = 'Upgrade your copy of Flutter.';
@override @override
Future<int> runCommand() async { Future<Null> runCommand() async {
try { try {
runCheckedSync(<String>[ runCheckedSync(<String>[
'git', 'rev-parse', '@{u}' 'git', 'rev-parse', '@{u}'
], workingDirectory: Cache.flutterRoot); ], workingDirectory: Cache.flutterRoot);
} catch (e) { } catch (e) {
printError('Unable to upgrade Flutter: no upstream repository configured.'); throwToolExit('Unable to upgrade Flutter: no upstream repository configured.');
return 1;
} }
FlutterVersion version = new FlutterVersion(Cache.flutterRoot); FlutterVersion version = new FlutterVersion(Cache.flutterRoot);
...@@ -48,7 +48,7 @@ class UpgradeCommand extends FlutterCommand { ...@@ -48,7 +48,7 @@ class UpgradeCommand extends FlutterCommand {
); );
if (code != 0) if (code != 0)
return code; throwToolExit(null, exitCode: code);
await buildUnlinkedForPackages(Cache.flutterRoot); await buildUnlinkedForPackages(Cache.flutterRoot);
...@@ -79,8 +79,6 @@ class UpgradeCommand extends FlutterCommand { ...@@ -79,8 +79,6 @@ class UpgradeCommand extends FlutterCommand {
printStatus(''); printStatus('');
printStatus('Running flutter doctor...'); printStatus('Running flutter doctor...');
await doctor.diagnose(); await doctor.diagnose();
return 0;
} }
// dev/benchmarks/complex_layout/lib/main.dart | 24 +- // dev/benchmarks/complex_layout/lib/main.dart | 24 +-
......
...@@ -9,6 +9,7 @@ import 'package:args/command_runner.dart'; ...@@ -9,6 +9,7 @@ import 'package:args/command_runner.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../dart/package_map.dart'; import '../dart/package_map.dart';
import '../dart/pub.dart'; import '../dart/pub.dart';
...@@ -18,9 +19,9 @@ import '../globals.dart'; ...@@ -18,9 +19,9 @@ import '../globals.dart';
import '../usage.dart'; import '../usage.dart';
import 'flutter_command_runner.dart'; import 'flutter_command_runner.dart';
typedef bool Validator(); typedef void Validator();
abstract class FlutterCommand extends Command { abstract class FlutterCommand extends Command<Null> {
FlutterCommand() { FlutterCommand() {
commandValidator = commonCommandValidator; commandValidator = commonCommandValidator;
} }
...@@ -107,18 +108,17 @@ abstract class FlutterCommand extends Command { ...@@ -107,18 +108,17 @@ abstract class FlutterCommand extends Command {
/// and [runCommand] to execute the command /// and [runCommand] to execute the command
/// so that this method can record and report the overall time to analytics. /// so that this method can record and report the overall time to analytics.
@override @override
Future<int> run() { Future<Null> run() {
Stopwatch stopwatch = new Stopwatch()..start(); Stopwatch stopwatch = new Stopwatch()..start();
UsageTimer analyticsTimer = usagePath == null ? null : flutterUsage.startTimer(name); UsageTimer analyticsTimer = usagePath == null ? null : flutterUsage.startTimer(name);
if (flutterUsage.isFirstRun) if (flutterUsage.isFirstRun)
flutterUsage.printUsage(); flutterUsage.printUsage();
return verifyThenRunCommand().then((int exitCode) { return verifyThenRunCommand().whenComplete(() {
int ms = stopwatch.elapsedMilliseconds; int ms = stopwatch.elapsedMilliseconds;
printTrace("'flutter $name' took ${ms}ms; exiting with code $exitCode."); printTrace("'flutter $name' took ${ms}ms.");
analyticsTimer?.finish(); analyticsTimer?.finish();
return exitCode;
}); });
} }
...@@ -130,7 +130,7 @@ abstract class FlutterCommand extends Command { ...@@ -130,7 +130,7 @@ abstract class FlutterCommand extends Command {
/// then call this method to execute the command /// then call this method to execute the command
/// rather than calling [runCommand] directly. /// rather than calling [runCommand] directly.
@mustCallSuper @mustCallSuper
Future<int> verifyThenRunCommand() async { Future<Null> verifyThenRunCommand() async {
// Populate the cache. We call this before pub get below so that the sky_engine // Populate the cache. We call this before pub get below so that the sky_engine
// package is available in the flutter cache for pub to find. // package is available in the flutter cache for pub to find.
await cache.updateAll(); await cache.updateAll();
...@@ -144,11 +144,11 @@ abstract class FlutterCommand extends Command { ...@@ -144,11 +144,11 @@ abstract class FlutterCommand extends Command {
if (commandPath != null) if (commandPath != null)
flutterUsage.sendCommand(usagePath); flutterUsage.sendCommand(usagePath);
return await runCommand(); await runCommand();
} }
/// Subclasses must implement this to execute the command. /// Subclasses must implement this to execute the command.
Future<int> runCommand(); Future<Null> runCommand();
/// Find and return the target [Device] based upon currently connected /// Find and return the target [Device] based upon currently connected
/// devices and criteria entered by the user on the command line. /// devices and criteria entered by the user on the command line.
...@@ -203,35 +203,28 @@ abstract class FlutterCommand extends Command { ...@@ -203,35 +203,28 @@ abstract class FlutterCommand extends Command {
// This is a field so that you can modify the value for testing. // This is a field so that you can modify the value for testing.
Validator commandValidator; Validator commandValidator;
bool commonCommandValidator() { void commonCommandValidator() {
if (!PackageMap.isUsingCustomPackagesPath) { if (!PackageMap.isUsingCustomPackagesPath) {
// Don't expect a pubspec.yaml file if the user passed in an explicit .packages file path. // Don't expect a pubspec.yaml file if the user passed in an explicit .packages file path.
if (!FileSystemEntity.isFileSync('pubspec.yaml')) { if (!FileSystemEntity.isFileSync('pubspec.yaml')) {
printError('Error: No pubspec.yaml file found.\n' throw new ToolExit('Error: No pubspec.yaml file found.\n'
'This command should be run from the root of your Flutter project.\n' 'This command should be run from the root of your Flutter project.\n'
'Do not run this command from the root of your git clone of Flutter.'); 'Do not run this command from the root of your git clone of Flutter.');
return false;
} }
} }
if (_usesTargetOption) { if (_usesTargetOption) {
String targetPath = targetFile; String targetPath = targetFile;
if (!FileSystemEntity.isFileSync(targetPath)) { if (!FileSystemEntity.isFileSync(targetPath))
printError('Target file "$targetPath" not found.'); throw new ToolExit('Target file "$targetPath" not found.');
return false;
}
} }
// Validate the current package map only if we will not be running "pub get" later. // Validate the current package map only if we will not be running "pub get" later.
if (!(_usesPubOption && argResults['pub'])) { if (!(_usesPubOption && argResults['pub'])) {
String error = new PackageMap(PackageMap.globalPackagesPath).checkValid(); String error = new PackageMap(PackageMap.globalPackagesPath).checkValid();
if (error != null) { if (error != null)
printError(error); throw new ToolExit(error);
return false;
}
} }
return true;
} }
ApplicationPackageStore applicationPackages; ApplicationPackageStore applicationPackages;
......
...@@ -25,7 +25,7 @@ const String kSnapshotFileName = 'flutter_tools.snapshot'; // in //flutter/bin/c ...@@ -25,7 +25,7 @@ const String kSnapshotFileName = 'flutter_tools.snapshot'; // in //flutter/bin/c
const String kFlutterToolsScriptFileName = 'flutter_tools.dart'; // in //flutter/packages/flutter_tools/bin/ const String kFlutterToolsScriptFileName = 'flutter_tools.dart'; // in //flutter/packages/flutter_tools/bin/
const String kFlutterEnginePackageName = 'sky_engine'; const String kFlutterEnginePackageName = 'sky_engine';
class FlutterCommandRunner extends CommandRunner { class FlutterCommandRunner extends CommandRunner<Null> {
FlutterCommandRunner({ bool verboseHelp: false }) : super( FlutterCommandRunner({ bool verboseHelp: false }) : super(
'flutter', 'flutter',
'Manage your Flutter app development.\n' 'Manage your Flutter app development.\n'
...@@ -124,7 +124,7 @@ class FlutterCommandRunner extends CommandRunner { ...@@ -124,7 +124,7 @@ class FlutterCommandRunner extends CommandRunner {
} }
@override @override
Future<dynamic> run(Iterable<String> args) { Future<Null> run(Iterable<String> args) {
// Have an invocation of 'build' print out it's sub-commands. // Have an invocation of 'build' print out it's sub-commands.
if (args.length == 1 && args.first == 'build') if (args.length == 1 && args.first == 'build')
args = <String>['build', '-h']; args = <String>['build', '-h'];
...@@ -133,7 +133,7 @@ class FlutterCommandRunner extends CommandRunner { ...@@ -133,7 +133,7 @@ class FlutterCommandRunner extends CommandRunner {
} }
@override @override
Future<int> runCommand(ArgResults globalResults) async { Future<Null> runCommand(ArgResults globalResults) async {
// Check for verbose. // Check for verbose.
if (globalResults['verbose']) if (globalResults['verbose'])
context[Logger] = new VerboseLogger(); context[Logger] = new VerboseLogger();
...@@ -153,8 +153,7 @@ class FlutterCommandRunner extends CommandRunner { ...@@ -153,8 +153,7 @@ class FlutterCommandRunner extends CommandRunner {
if (globalResults['suppress-analytics']) if (globalResults['suppress-analytics'])
flutterUsage.suppressAnalytics = true; flutterUsage.suppressAnalytics = true;
if (!_checkFlutterCopy()) _checkFlutterCopy();
return 1;
if (globalResults.wasParsed('packages')) if (globalResults.wasParsed('packages'))
PackageMap.globalPackagesPath = path.normalize(path.absolute(globalResults['packages'])); PackageMap.globalPackagesPath = path.normalize(path.absolute(globalResults['packages']));
...@@ -176,10 +175,10 @@ class FlutterCommandRunner extends CommandRunner { ...@@ -176,10 +175,10 @@ class FlutterCommandRunner extends CommandRunner {
if (globalResults['version']) { if (globalResults['version']) {
flutterUsage.sendCommand('version'); flutterUsage.sendCommand('version');
printStatus(FlutterVersion.getVersion(Cache.flutterRoot).toString()); printStatus(FlutterVersion.getVersion(Cache.flutterRoot).toString());
return 0; return;
} }
return await super.runCommand(globalResults); await super.runCommand(globalResults);
} }
String _tryEnginePath(String enginePath) { String _tryEnginePath(String enginePath) {
...@@ -285,7 +284,7 @@ class FlutterCommandRunner extends CommandRunner { ...@@ -285,7 +284,7 @@ class FlutterCommandRunner extends CommandRunner {
return result; return result;
} }
bool _checkFlutterCopy() { void _checkFlutterCopy() {
// If the current directory is contained by a flutter repo, check that it's // If the current directory is contained by a flutter repo, check that it's
// the same flutter that is currently running. // the same flutter that is currently running.
String directory = path.normalize(path.absolute(Directory.current.path)); String directory = path.normalize(path.absolute(Directory.current.path));
...@@ -334,8 +333,6 @@ class FlutterCommandRunner extends CommandRunner { ...@@ -334,8 +333,6 @@ class FlutterCommandRunner extends CommandRunner {
} }
} }
} }
return true;
} }
// Check if `bin/flutter` and `bin/cache/engine.stamp` exist. // Check if `bin/flutter` and `bin/cache/engine.stamp` exist.
......
...@@ -9,12 +9,7 @@ environment: ...@@ -9,12 +9,7 @@ environment:
dependencies: dependencies:
archive: ^1.0.20 archive: ^1.0.20
args: ^0.13.4
# version 0.13.6+1 does not return the value from the command
# causing flutter tools to always have exit code 0
# see https://github.com/flutter/flutter/issues/6766
args: 0.13.6
coverage: ^0.8.0 coverage: ^0.8.0
crypto: '>=1.1.1 <3.0.0' crypto: '>=1.1.1 <3.0.0'
file: ^0.1.0 file: ^0.1.0
......
...@@ -39,22 +39,19 @@ void main() { ...@@ -39,22 +39,19 @@ void main() {
flutterUsage.enabled = false; flutterUsage.enabled = false;
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
expect(count, 0); expect(count, 0);
flutterUsage.enabled = true; flutterUsage.enabled = true;
code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
expect(count, flutterUsage.isFirstRun ? 0 : 2); expect(count, flutterUsage.isFirstRun ? 0 : 2);
count = 0; count = 0;
flutterUsage.enabled = false; flutterUsage.enabled = false;
DoctorCommand doctorCommand = new DoctorCommand(); DoctorCommand doctorCommand = new DoctorCommand();
runner = createTestCommandRunner(doctorCommand); runner = createTestCommandRunner(doctorCommand);
code = await runner.run(<String>['doctor']); await runner.run(<String>['doctor']);
expect(code, 0);
expect(count, 0); expect(count, 0);
}, overrides: <Type, dynamic>{ }, overrides: <Type, dynamic>{
Usage: new Usage() Usage: new Usage()
...@@ -67,7 +64,7 @@ void main() { ...@@ -67,7 +64,7 @@ void main() {
flutterUsage.enabled = false; flutterUsage.enabled = false;
ConfigCommand command = new ConfigCommand(); ConfigCommand command = new ConfigCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
await runner.run(<String>['config']); await runner.run(<String>['config']);
expect(count, 0); expect(count, 0);
......
...@@ -37,8 +37,7 @@ void main() { ...@@ -37,8 +37,7 @@ void main() {
applyMocksToCommand(command); applyMocksToCommand(command);
return createTestCommandRunner(command).run( return createTestCommandRunner(command).run(
<String>['analyze', '--no-current-package', '--no-current-directory', dartFileA.path, dartFileB.path] <String>['analyze', '--no-current-package', '--no-current-directory', dartFileA.path, dartFileB.path]
).then((int code) { ).then((_) {
expect(code, 0);
expect(testLogger.statusText, startsWith('Analyzing 2 files...\nNo analyzer warnings!')); expect(testLogger.statusText, startsWith('Analyzing 2 files...\nNo analyzer warnings!'));
}); });
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/commands/channel.dart'; import 'package:flutter_tools/src/commands/channel.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
...@@ -15,14 +13,13 @@ void main() { ...@@ -15,14 +13,13 @@ void main() {
group('channel', () { group('channel', () {
testUsingContext('list', () async { testUsingContext('list', () async {
ChannelCommand command = new ChannelCommand(); ChannelCommand command = new ChannelCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
expect(await runner.run(<String>['channel']), 0); await runner.run(<String>['channel']);
BufferLogger logger = context[Logger]; expect(testLogger.errorText, hasLength(0));
expect(logger.errorText, hasLength(0));
// The bots may return an empty list of channels (network hiccup?) // The bots may return an empty list of channels (network hiccup?)
// and when run locally the list of branches might be different // and when run locally the list of branches might be different
// so we check for the header text rather than any specific channel name. // so we check for the header text rather than any specific channel name.
expect(logger.statusText, contains('Flutter channels:')); expect(testLogger.statusText, contains('Flutter channels:'));
}); });
}); });
} }
...@@ -43,10 +43,9 @@ void main() { ...@@ -43,10 +43,9 @@ void main() {
Cache.flutterRoot = '../..'; Cache.flutterRoot = '../..';
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
void expectExists(String relPath) { void expectExists(String relPath) {
expect(FileSystemEntity.isFileSync('${temp.path}/$relPath'), true); expect(FileSystemEntity.isFileSync('${temp.path}/$relPath'), true);
...@@ -74,13 +73,11 @@ void main() { ...@@ -74,13 +73,11 @@ void main() {
Cache.flutterRoot = '../..'; Cache.flutterRoot = '../..';
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
}); });
// Verify that we help the user correct an option ordering issue // Verify that we help the user correct an option ordering issue
...@@ -88,7 +85,7 @@ void main() { ...@@ -88,7 +85,7 @@ void main() {
Cache.flutterRoot = '../..'; Cache.flutterRoot = '../..';
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
try { try {
await runner.run(<String>['create', temp.path, '--pub']); await runner.run(<String>['create', temp.path, '--pub']);
...@@ -103,7 +100,7 @@ void main() { ...@@ -103,7 +100,7 @@ void main() {
testUsingContext('fails when file exists', () async { testUsingContext('fails when file exists', () async {
Cache.flutterRoot = '../..'; Cache.flutterRoot = '../..';
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
File existingFile = new File("${temp.path.toString()}/bad"); File existingFile = new File("${temp.path.toString()}/bad");
if (!existingFile.existsSync()) existingFile.createSync(); if (!existingFile.existsSync()) existingFile.createSync();
try { try {
...@@ -119,12 +116,11 @@ void main() { ...@@ -119,12 +116,11 @@ void main() {
Future<Null> _createAndAnalyzeProject(Directory dir, List<String> createArgs) async { Future<Null> _createAndAnalyzeProject(Directory dir, List<String> createArgs) async {
Cache.flutterRoot = '../..'; Cache.flutterRoot = '../..';
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
List<String> args = <String>['create']; List<String> args = <String>['create'];
args.addAll(createArgs); args.addAll(createArgs);
args.add(dir.path); args.add(dir.path);
int code = await runner.run(args); await runner.run(args);
expect(code, 0);
String mainPath = path.join(dir.path, 'lib', 'main.dart'); String mainPath = path.join(dir.path, 'lib', 'main.dart');
expect(new File(mainPath).existsSync(), true); expect(new File(mainPath).existsSync(), true);
......
...@@ -12,19 +12,15 @@ import 'src/context.dart'; ...@@ -12,19 +12,15 @@ import 'src/context.dart';
void main() { void main() {
group('devices', () { group('devices', () {
testUsingContext('returns 0 when called', () { testUsingContext('returns 0 when called', () async {
DevicesCommand command = new DevicesCommand(); DevicesCommand command = new DevicesCommand();
return createTestCommandRunner(command).run(<String>['devices']).then((int code) { await createTestCommandRunner(command).run(<String>['devices']);
expect(code, 0);
});
}); });
testUsingContext('no error when no connected devices', () { testUsingContext('no error when no connected devices', () async {
DevicesCommand command = new DevicesCommand(); DevicesCommand command = new DevicesCommand();
return createTestCommandRunner(command).run(<String>['devices']).then((int code) { await createTestCommandRunner(command).run(<String>['devices']);
expect(code, 0); expect(testLogger.statusText, contains('No devices detected'));
expect(testLogger.statusText, contains('No devices detected'));
});
}, overrides: <Type, dynamic>{ }, overrides: <Type, dynamic>{
AndroidSdk: null, AndroidSdk: null,
DeviceManager: new DeviceManager() DeviceManager: new DeviceManager()
......
...@@ -8,11 +8,9 @@ import 'package:file/file.dart'; ...@@ -8,11 +8,9 @@ import 'package:file/file.dart';
import 'package:flutter_tools/src/android/android_device.dart'; import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart'; import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/commands/drive.dart'; import 'package:flutter_tools/src/commands/drive.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/globals.dart';
import 'package:flutter_tools/src/ios/simulators.dart'; import 'package:flutter_tools/src/ios/simulators.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
...@@ -164,11 +162,8 @@ void main() { ...@@ -164,11 +162,8 @@ void main() {
'drive', 'drive',
'--target=$testApp', '--target=$testApp',
]; ];
return createTestCommandRunner(command).run(args).then((int code) { await createTestCommandRunner(command).run(args);
expect(code, 0); expect(testLogger.errorText, isEmpty);
BufferLogger buffer = logger;
expect(buffer.errorText, isEmpty);
});
}); });
testUsingContext('returns exitCode set by test runner', () async { testUsingContext('returns exitCode set by test runner', () async {
......
...@@ -30,10 +30,9 @@ void main() { ...@@ -30,10 +30,9 @@ void main() {
Future<Null> createProject() async { Future<Null> createProject() async {
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
} }
testUsingContext('a file', () async { testUsingContext('a file', () async {
...@@ -44,9 +43,8 @@ void main() { ...@@ -44,9 +43,8 @@ void main() {
srcFile.writeAsStringSync(original.replaceFirst('main()', 'main( )')); srcFile.writeAsStringSync(original.replaceFirst('main()', 'main( )'));
FormatCommand command = new FormatCommand(); FormatCommand command = new FormatCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['format', srcFile.path]); await runner.run(<String>['format', srcFile.path]);
expect(code, 0);
String formatted = srcFile.readAsStringSync(); String formatted = srcFile.readAsStringSync();
expect(formatted, original); expect(formatted, original);
......
...@@ -12,7 +12,7 @@ import 'src/mocks.dart'; ...@@ -12,7 +12,7 @@ import 'src/mocks.dart';
void main() { void main() {
group('install', () { group('install', () {
testUsingContext('returns 0 when Android is connected and ready for an install', () { testUsingContext('returns 0 when Android is connected and ready for an install', () async {
InstallCommand command = new InstallCommand(); InstallCommand command = new InstallCommand();
applyMocksToCommand(command); applyMocksToCommand(command);
...@@ -21,12 +21,10 @@ void main() { ...@@ -21,12 +21,10 @@ void main() {
when(device.installApp(any)).thenReturn(true); when(device.installApp(any)).thenReturn(true);
testDeviceManager.addDevice(device); testDeviceManager.addDevice(device);
return createTestCommandRunner(command).run(<String>['install']).then((int code) { await createTestCommandRunner(command).run(<String>['install']);
expect(code, 0);
});
}); });
testUsingContext('returns 0 when iOS is connected and ready for an install', () { testUsingContext('returns 0 when iOS is connected and ready for an install', () async {
InstallCommand command = new InstallCommand(); InstallCommand command = new InstallCommand();
applyMocksToCommand(command); applyMocksToCommand(command);
...@@ -35,9 +33,7 @@ void main() { ...@@ -35,9 +33,7 @@ void main() {
when(device.installApp(any)).thenReturn(true); when(device.installApp(any)).thenReturn(true);
testDeviceManager.addDevice(device); testDeviceManager.addDevice(device);
return createTestCommandRunner(command).run(<String>['install']).then((int code) { await createTestCommandRunner(command).run(<String>['install']);
expect(code, 0);
});
}); });
}); });
} }
...@@ -27,20 +27,18 @@ void main() { ...@@ -27,20 +27,18 @@ void main() {
Future<Null> createProject() async { Future<Null> createProject() async {
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
} }
Future<Null> runCommand(String verb) async { Future<Null> runCommand(String verb) async {
await createProject(); await createProject();
PackagesCommand command = new PackagesCommand(); PackagesCommand command = new PackagesCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['packages', verb, temp.path]); await runner.run(<String>['packages', verb, temp.path]);
expect(code, 0);
} }
void expectExists(String relPath) { void expectExists(String relPath) {
......
...@@ -6,7 +6,7 @@ import 'package:args/command_runner.dart'; ...@@ -6,7 +6,7 @@ import 'package:args/command_runner.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/runner/flutter_command_runner.dart'; import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
CommandRunner createTestCommandRunner([FlutterCommand command]) { CommandRunner<Null> createTestCommandRunner([FlutterCommand command]) {
FlutterCommandRunner runner = new FlutterCommandRunner(); FlutterCommandRunner runner = new FlutterCommandRunner();
if (command != null) if (command != null)
runner.addCommand(command); runner.addCommand(command);
......
...@@ -14,27 +14,23 @@ import 'src/mocks.dart'; ...@@ -14,27 +14,23 @@ import 'src/mocks.dart';
void main() { void main() {
group('stop', () { group('stop', () {
testUsingContext('returns 0 when Android is connected and ready to be stopped', () { testUsingContext('returns 0 when Android is connected and ready to be stopped', () async {
StopCommand command = new StopCommand(); StopCommand command = new StopCommand();
applyMocksToCommand(command); applyMocksToCommand(command);
MockAndroidDevice device = new MockAndroidDevice(); MockAndroidDevice device = new MockAndroidDevice();
when(device.stopApp(any)).thenReturn(new Future<bool>.value(true)); when(device.stopApp(any)).thenReturn(new Future<bool>.value(true));
testDeviceManager.addDevice(device); testDeviceManager.addDevice(device);
return createTestCommandRunner(command).run(<String>['stop']).then((int code) { await createTestCommandRunner(command).run(<String>['stop']);
expect(code, 0);
});
}); });
testUsingContext('returns 0 when iOS is connected and ready to be stopped', () { testUsingContext('returns 0 when iOS is connected and ready to be stopped', () async {
StopCommand command = new StopCommand(); StopCommand command = new StopCommand();
applyMocksToCommand(command); applyMocksToCommand(command);
MockIOSDevice device = new MockIOSDevice(); MockIOSDevice device = new MockIOSDevice();
when(device.stopApp(any)).thenReturn(new Future<bool>.value(true)); when(device.stopApp(any)).thenReturn(new Future<bool>.value(true));
testDeviceManager.addDevice(device); testDeviceManager.addDevice(device);
return createTestCommandRunner(command).run(<String>['stop']).then((int code) { await createTestCommandRunner(command).run(<String>['stop']);
expect(code, 0);
});
}); });
}); });
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// 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.
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/commands/trace.dart'; import 'package:flutter_tools/src/commands/trace.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
...@@ -11,12 +12,15 @@ import 'src/mocks.dart'; ...@@ -11,12 +12,15 @@ import 'src/mocks.dart';
void main() { void main() {
group('trace', () { group('trace', () {
testUsingContext('returns 1 when no Android device is connected', () { testUsingContext('returns 1 when no Android device is connected', () async {
TraceCommand command = new TraceCommand(); TraceCommand command = new TraceCommand();
applyMocksToCommand(command); applyMocksToCommand(command);
return createTestCommandRunner(command).run(<String>['trace']).then((int code) { try {
expect(code, 1); await createTestCommandRunner(command).run(<String>['trace']);
}); fail('Exception expected');
} on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1);
}
}); });
}); });
} }
...@@ -49,9 +49,8 @@ void main() { ...@@ -49,9 +49,8 @@ void main() {
Future<Null> createProject() async { Future<Null> createProject() async {
CreateCommand command = new CreateCommand(); CreateCommand command = new CreateCommand();
CommandRunner runner = createTestCommandRunner(command); CommandRunner<Null> runner = createTestCommandRunner(command);
int code = await runner.run(<String>['create', '--no-pub', temp.path]); await runner.run(<String>['create', '--no-pub', temp.path]);
expect(code, 0);
} }
testUsingContext('in project', () async { testUsingContext('in project', () async {
......
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