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 |