| Index: sdk/lib/_internal/pub/bin/pub.dart
|
| diff --git a/sdk/lib/_internal/pub/bin/pub.dart b/sdk/lib/_internal/pub/bin/pub.dart
|
| index a589dcc8403a9ac31593a593ad2afb4545c1f627..ecc8318a9c686ec9342af187b5ab2d87dceb503a 100644
|
| --- a/sdk/lib/_internal/pub/bin/pub.dart
|
| +++ b/sdk/lib/_internal/pub/bin/pub.dart
|
| @@ -7,9 +7,11 @@ import 'dart:io';
|
|
|
| import 'package:args/args.dart';
|
| import 'package:path/path.dart' as path;
|
| +import 'package:stack_trace/stack_trace.dart';
|
|
|
| import '../lib/src/command.dart';
|
| import '../lib/src/exit_codes.dart' as exit_codes;
|
| +import '../lib/src/http.dart';
|
| import '../lib/src/io.dart';
|
| import '../lib/src/log.dart' as log;
|
| import '../lib/src/sdk.dart' as sdk;
|
| @@ -38,18 +40,6 @@ void main(List<String> arguments) {
|
| return;
|
| }
|
|
|
| - if (options.command == null) {
|
| - if (options.rest.isEmpty) {
|
| - // No command was chosen.
|
| - PubCommand.printGlobalUsage();
|
| - } else {
|
| - log.error('Could not find a command named "${options.rest[0]}".');
|
| - log.error('Run "pub help" to see available commands.');
|
| - flushThenExit(exit_codes.USAGE);
|
| - }
|
| - return;
|
| - }
|
| -
|
| if (options['trace']) {
|
| log.recordTranscript();
|
| }
|
| @@ -81,8 +71,125 @@ void main(List<String> arguments) {
|
| cacheDir = '${Platform.environment['HOME']}/.pub-cache';
|
| }
|
|
|
| - validatePlatform().then((_) {
|
| - PubCommand.commands[options.command.name].run(cacheDir, options, arguments);
|
| + validatePlatform().then((_) => runPub(cacheDir, options, arguments));
|
| +}
|
| +
|
| +/// Runs the appropriate pub command whose [arguments] have been parsed to
|
| +/// [options] using the system cache in [cacheDir].
|
| +///
|
| +/// Handles and correctly reports any errors that occur while running.
|
| +void runPub(String cacheDir, ArgResults options, List<String> arguments) {
|
| + var captureStackChains =
|
| + options['trace'] ||
|
| + options['verbose'] ||
|
| + options['verbosity'] == 'all';
|
| +
|
| + captureErrors(() => invokeCommand(cacheDir, options),
|
| + captureStackChains: captureStackChains).catchError((error, Chain chain) {
|
| + // This is basically the top-level exception handler so that we don't
|
| + // spew a stack trace on our users.
|
| + var message;
|
| +
|
| + log.error(getErrorMessage(error));
|
| + log.fine("Exception type: ${error.runtimeType}");
|
| +
|
| + if (options['trace'] || !isUserFacingException(error)) {
|
| + log.error(chain.terse);
|
| + } else {
|
| + log.fine(chain.terse);
|
| + }
|
| +
|
| + if (error is ApplicationException && error.innerError != null) {
|
| + var message = "Wrapped exception: ${error.innerError}";
|
| + if (error.innerTrace != null) message = "$message\n${error.innerTrace}";
|
| + log.fine(message);
|
| + }
|
| +
|
| + if (options['trace']) {
|
| + log.dumpTranscript();
|
| + } else if (!isUserFacingException(error)) {
|
| + log.error("""
|
| +This is an unexpected error. Please run
|
| +
|
| + pub --trace ${arguments.map((arg) => "'$arg'").join(' ')}
|
| +
|
| +and include the results in a bug report on http://dartbug.com/new.
|
| +""");
|
| + }
|
| +
|
| + return flushThenExit(chooseExitCode(error));
|
| + }).then((_) {
|
| + // Explicitly exit on success to ensure that any dangling dart:io handles
|
| + // don't cause the process to never terminate.
|
| + return flushThenExit(exit_codes.SUCCESS);
|
| + });
|
| +}
|
| +
|
| +/// Returns the appropriate exit code for [exception], falling back on 1 if no
|
| +/// appropriate exit code could be found.
|
| +int chooseExitCode(exception) {
|
| + if (exception is HttpException || exception is HttpException ||
|
| + exception is SocketException || exception is PubHttpException) {
|
| + return exit_codes.UNAVAILABLE;
|
| + } else if (exception is FormatException) {
|
| + return exit_codes.DATA;
|
| + } else if (exception is UsageException) {
|
| + return exit_codes.USAGE;
|
| + } else {
|
| + return 1;
|
| + }
|
| +}
|
| +
|
| +/// Walks the command tree and runs the selected pub command.
|
| +Future invokeCommand(String cacheDir, ArgResults mainOptions) {
|
| + var commands = PubCommand.mainCommands;
|
| + var command;
|
| + var commandString = "pub";
|
| + var options = mainOptions;
|
| +
|
| + while (commands.isNotEmpty) {
|
| + if (options.command == null) {
|
| + if (options.rest.isEmpty) {
|
| + if (command == null) {
|
| + // No top-level command was chosen.
|
| + PubCommand.printGlobalUsage();
|
| + return new Future.value();
|
| + }
|
| +
|
| + command.usageError('Missing subcommand for "$commandString".');
|
| + } else {
|
| + if (command == null) {
|
| + PubCommand.usageErrorWithCommands(commands,
|
| + 'Could not find a command named "${options.rest[0]}".');
|
| + }
|
| +
|
| + command.usageError('Could not find a subcommand named '
|
| + '"${options.rest[0]}" for "$commandString".');
|
| + }
|
| + }
|
| +
|
| + // Step into the command.
|
| + options = options.command;
|
| + command = commands[options.name];
|
| + commands = command.subcommands;
|
| + commandString += " ${options.name}";
|
| +
|
| + if (options['help']) {
|
| + command.printUsage();
|
| + return new Future.value();
|
| + }
|
| + }
|
| +
|
| + // Make sure there aren't unexpected arguments.
|
| + if (!command.takesArguments && options.rest.isNotEmpty) {
|
| + command.usageError(
|
| + 'Command "${options.name}" does not take any arguments.');
|
| + }
|
| +
|
| + return syncFuture(() {
|
| + return command.run(cacheDir, options);
|
| + }).whenComplete(() {
|
| + command.cache.deleteTempDir();
|
| });
|
| }
|
|
|
|
|