| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library pub.command; | 5 library pub.command; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 import 'package:args/args.dart'; | 10 import 'package:args/args.dart'; |
| 11 import 'package:path/path.dart' as path; | 11 import 'package:path/path.dart' as path; |
| 12 | 12 |
| 13 import 'command/build.dart'; | 13 import 'command/build.dart'; |
| 14 import 'command/cache.dart'; | 14 import 'command/cache.dart'; |
| 15 import 'command/deps.dart'; | 15 import 'command/deps.dart'; |
| 16 import 'command/get.dart'; | 16 import 'command/get.dart'; |
| 17 import 'command/global.dart'; | 17 import 'command/global.dart'; |
| 18 import 'command/help.dart'; | 18 import 'command/help.dart'; |
| 19 import 'command/lish.dart'; | 19 import 'command/lish.dart'; |
| 20 import 'command/list_package_dirs.dart'; | 20 import 'command/list_package_dirs.dart'; |
| 21 import 'command/run.dart'; | 21 import 'command/run.dart'; |
| 22 import 'command/serve.dart'; | 22 import 'command/serve.dart'; |
| 23 import 'command/upgrade.dart'; | 23 import 'command/upgrade.dart'; |
| 24 import 'command/uploader.dart'; | 24 import 'command/uploader.dart'; |
| 25 import 'command/version.dart'; | 25 import 'command/version.dart'; |
| 26 import 'entrypoint.dart'; | 26 import 'entrypoint.dart'; |
| 27 import 'exceptions.dart'; | 27 import 'exceptions.dart'; |
| 28 import 'exit_codes.dart' as exit_codes; | |
| 29 import 'log.dart' as log; | 28 import 'log.dart' as log; |
| 30 import 'global_packages.dart'; | 29 import 'global_packages.dart'; |
| 31 import 'system_cache.dart'; | 30 import 'system_cache.dart'; |
| 32 import 'utils.dart'; | 31 import 'utils.dart'; |
| 33 | 32 |
| 34 /// The base class for commands for the pub executable. | 33 /// The base class for commands for the pub executable. |
| 35 /// | 34 /// |
| 36 /// A command may either be a "leaf" command or it may be a parent for a set | 35 /// A command may either be a "leaf" command or it may be a parent for a set |
| 37 /// of subcommands. Only leaf commands are ever actually invoked. If a command | 36 /// of subcommands. Only leaf commands are ever actually invoked. If a command |
| 38 /// has subcommands, then one of those must always be chosen. | 37 /// has subcommands, then one of those must always be chosen. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 61 buffer.writeln( | 60 buffer.writeln( |
| 62 'See http://dartlang.org/tools/pub for detailed documentation.'); | 61 'See http://dartlang.org/tools/pub for detailed documentation.'); |
| 63 | 62 |
| 64 log.message(buffer); | 63 log.message(buffer); |
| 65 } | 64 } |
| 66 | 65 |
| 67 /// Fails with a usage error [message] when trying to select from one of | 66 /// Fails with a usage error [message] when trying to select from one of |
| 68 /// [commands]. | 67 /// [commands]. |
| 69 static void usageErrorWithCommands(Map<String, PubCommand> commands, | 68 static void usageErrorWithCommands(Map<String, PubCommand> commands, |
| 70 String message) { | 69 String message) { |
| 71 throw new UsageException(message, _listCommands(commands)); | 70 throw new UsageException(message)..bindUsage(_listCommands(commands)); |
| 72 } | 71 } |
| 73 | 72 |
| 74 /// Writes [commands] in a nicely formatted list to [buffer]. | 73 /// Writes [commands] in a nicely formatted list to [buffer]. |
| 75 static String _listCommands(Map<String, PubCommand> commands) { | 74 static String _listCommands(Map<String, PubCommand> commands) { |
| 76 // If there are no subcommands, do nothing. | 75 // If there are no subcommands, do nothing. |
| 77 if (commands.isEmpty) return ""; | 76 if (commands.isEmpty) return ""; |
| 78 | 77 |
| 79 // Don't include aliases. | 78 // Don't include aliases. |
| 80 var names = commands.keys | 79 var names = commands.keys |
| 81 .where((name) => !commands[name].aliases.contains(name)); | 80 .where((name) => !commands[name].aliases.contains(name)); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 _cache = new SystemCache.withSources(cacheDir, isOffline: isOffline); | 183 _cache = new SystemCache.withSources(cacheDir, isOffline: isOffline); |
| 185 _globals = new GlobalPackages(_cache); | 184 _globals = new GlobalPackages(_cache); |
| 186 | 185 |
| 187 if (requiresEntrypoint) { | 186 if (requiresEntrypoint) { |
| 188 // TODO(rnystrom): Will eventually need better logic to walk up | 187 // TODO(rnystrom): Will eventually need better logic to walk up |
| 189 // subdirectories until we hit one that looks package-like. For now, | 188 // subdirectories until we hit one that looks package-like. For now, |
| 190 // just assume the cwd is it. | 189 // just assume the cwd is it. |
| 191 entrypoint = new Entrypoint(path.current, cache); | 190 entrypoint = new Entrypoint(path.current, cache); |
| 192 } | 191 } |
| 193 | 192 |
| 194 return syncFuture(onRun); | 193 return syncFuture(onRun).catchError((error) { |
| 194 if (error is UsageException) error.bindUsage(_getUsage()); |
| 195 throw error; |
| 196 }); |
| 195 } | 197 } |
| 196 | 198 |
| 197 /// Override this to perform the specific command. | 199 /// Override this to perform the specific command. |
| 198 /// | 200 /// |
| 199 /// Return a future that completes when the command is done or fails if the | 201 /// Return a future that completes when the command is done or fails if the |
| 200 /// command fails. If the command is synchronous, it may return `null`. Only | 202 /// command fails. If the command is synchronous, it may return `null`. Only |
| 201 /// leaf command should override this. | 203 /// leaf command should override this. |
| 202 Future onRun() { | 204 Future onRun() { |
| 203 // Leaf commands should override this and non-leaf commands should never | 205 // Leaf commands should override this and non-leaf commands should never |
| 204 // call it. | 206 // call it. |
| 205 assert(false); | 207 assert(false); |
| 206 return null; | 208 return null; |
| 207 } | 209 } |
| 208 | 210 |
| 209 /// Displays usage information for this command. | 211 /// Displays usage information for this command. |
| 210 /// | 212 /// |
| 211 /// If [description] is omitted, defaults to the command's description. | 213 /// If [description] is omitted, defaults to the command's description. |
| 212 void printUsage([String description]) { | 214 void printUsage([String description]) { |
| 213 if (description == null) description = this.description; | 215 if (description == null) description = this.description; |
| 214 log.message('$description\n\n${_getUsage()}'); | 216 log.message('$description\n\n${_getUsage()}'); |
| 215 } | 217 } |
| 216 | 218 |
| 217 // TODO(rnystrom): Use this in other places handle usage failures. | |
| 218 /// Throw a [UsageException] for a usage error of this command with | |
| 219 /// [message]. | |
| 220 void usageError(String message) { | |
| 221 throw new UsageException(message, _getUsage()); | |
| 222 } | |
| 223 | |
| 224 /// Parses a user-supplied integer [intString] named [name]. | 219 /// Parses a user-supplied integer [intString] named [name]. |
| 225 /// | 220 /// |
| 226 /// If the parsing fails, prints a usage message and exits. | 221 /// If the parsing fails, prints a usage message and exits. |
| 227 int parseInt(String intString, String name) { | 222 int parseInt(String intString, String name) { |
| 228 try { | 223 try { |
| 229 return int.parse(intString); | 224 return int.parse(intString); |
| 230 } on FormatException catch (_) { | 225 } on FormatException catch (_) { |
| 231 usageError('Could not parse $name "$intString".'); | 226 usageError('Could not parse $name "$intString".'); |
| 232 } | 227 } |
| 233 } | 228 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 | 314 |
| 320 /// Registers a [command] with [name] on [parser]. | 315 /// Registers a [command] with [name] on [parser]. |
| 321 void _registerCommand(String name, PubCommand command, ArgParser parser) { | 316 void _registerCommand(String name, PubCommand command, ArgParser parser) { |
| 322 parser.addCommand(name, command.commandParser); | 317 parser.addCommand(name, command.commandParser); |
| 323 | 318 |
| 324 // Recursively wire up any subcommands. | 319 // Recursively wire up any subcommands. |
| 325 command.subcommands.forEach((name, subcommand) { | 320 command.subcommands.forEach((name, subcommand) { |
| 326 _registerCommand(name, subcommand, command.commandParser); | 321 _registerCommand(name, subcommand, command.commandParser); |
| 327 }); | 322 }); |
| 328 } | 323 } |
| OLD | NEW |