| 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 /** | 5 /** |
| 6 * This library lets you define parsers for parsing raw command-line arguments | 6 * This library lets you define parsers for parsing raw command-line arguments |
| 7 * into a set of options and values using [GNU][] and [POSIX][] style options. | 7 * into a set of options and values using [GNU][] and [POSIX][] style options. |
| 8 * | 8 * |
| 9 * ## Installing ## | 9 * ## Installing ## |
| 10 * | 10 * |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 * be followed by a single new line. Options with multi-line help text | 248 * be followed by a single new line. Options with multi-line help text |
| 249 * will be followed by two new lines. This provides spatial diversity between | 249 * will be followed by two new lines. This provides spatial diversity between |
| 250 * options. | 250 * options. |
| 251 * | 251 * |
| 252 * [posix]: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.h
tml#tag_12_02 | 252 * [posix]: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.h
tml#tag_12_02 |
| 253 * [gnu]: http://www.gnu.org/prep/standards/standards.html#Command_002dLine-Inte
rfaces | 253 * [gnu]: http://www.gnu.org/prep/standards/standards.html#Command_002dLine-Inte
rfaces |
| 254 * [pub]: http://pub.dartlang.org | 254 * [pub]: http://pub.dartlang.org |
| 255 */ | 255 */ |
| 256 library args; | 256 library args; |
| 257 | 257 |
| 258 import 'package:unmodifiable_collection/unmodifiable_collection.dart'; |
| 259 |
| 258 import 'src/parser.dart'; | 260 import 'src/parser.dart'; |
| 259 import 'src/usage.dart'; | 261 import 'src/usage.dart'; |
| 260 import 'src/options.dart'; | 262 import 'src/options.dart'; |
| 261 export 'src/options.dart'; | 263 export 'src/options.dart'; |
| 262 | 264 |
| 263 /** | 265 /** |
| 264 * A class for taking a list of raw command line arguments and parsing out | 266 * A class for taking a list of raw command line arguments and parsing out |
| 265 * options and flags from them. | 267 * options and flags from them. |
| 266 */ | 268 */ |
| 267 class ArgParser { | 269 class ArgParser { |
| 270 final Map<String, Option> _options; |
| 271 final Map<String, ArgParser> _commands; |
| 272 |
| 268 /** | 273 /** |
| 269 * The options that have been defined for this parser. | 274 * The options that have been defined for this parser. |
| 270 */ | 275 */ |
| 271 final Map<String, Option> options = <String, Option>{}; | 276 final Map<String, Option> options; |
| 272 | 277 |
| 273 /** | 278 /** |
| 274 * The commands that have been defined for this parser. | 279 * The commands that have been defined for this parser. |
| 275 */ | 280 */ |
| 276 final Map<String, ArgParser> commands = <String, ArgParser>{}; | 281 final Map<String, ArgParser> commands; |
| 277 | 282 |
| 278 /** Creates a new ArgParser. */ | 283 /** Creates a new ArgParser. */ |
| 279 ArgParser(); | 284 factory ArgParser() => |
| 285 new ArgParser._(<String, Option>{}, <String, ArgParser>{}); |
| 286 |
| 287 ArgParser._(Map<String, Option> options, Map<String, ArgParser> commands) : |
| 288 this._options = options, |
| 289 this.options = new UnmodifiableMapView(options), |
| 290 this._commands = commands, |
| 291 this.commands = new UnmodifiableMapView(commands); |
| 280 | 292 |
| 281 /** | 293 /** |
| 282 * Defines a command. | 294 * Defines a command. |
| 283 * | 295 * |
| 284 * A command is a named argument which may in turn define its own options and | 296 * A command is a named argument which may in turn define its own options and |
| 285 * subcommands using the given parser. If [parser] is omitted, implicitly | 297 * subcommands using the given parser. If [parser] is omitted, implicitly |
| 286 * creates a new one. Returns the parser for the command. | 298 * creates a new one. Returns the parser for the command. |
| 287 */ | 299 */ |
| 288 ArgParser addCommand(String name, [ArgParser parser]) { | 300 ArgParser addCommand(String name, [ArgParser parser]) { |
| 289 // Make sure the name isn't in use. | 301 // Make sure the name isn't in use. |
| 290 if (commands.containsKey(name)) { | 302 if (_commands.containsKey(name)) { |
| 291 throw new ArgumentError('Duplicate command "$name".'); | 303 throw new ArgumentError('Duplicate command "$name".'); |
| 292 } | 304 } |
| 293 | 305 |
| 294 if (parser == null) parser = new ArgParser(); | 306 if (parser == null) parser = new ArgParser(); |
| 295 commands[name] = parser; | 307 _commands[name] = parser; |
| 296 return parser; | 308 return parser; |
| 297 } | 309 } |
| 298 | 310 |
| 299 /** | 311 /** |
| 300 * Defines a flag. Throws an [ArgumentError] if: | 312 * Defines a flag. Throws an [ArgumentError] if: |
| 301 * | 313 * |
| 302 * * There is already an option named [name]. | 314 * * There is already an option named [name]. |
| 303 * * There is already an option using abbreviation [abbr]. | 315 * * There is already an option using abbreviation [abbr]. |
| 304 */ | 316 */ |
| 305 void addFlag(String name, {String abbr, String help, bool defaultsTo: false, | 317 void addFlag(String name, {String abbr, String help, bool defaultsTo: false, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 319 void callback(value), bool allowMultiple: false}) { | 331 void callback(value), bool allowMultiple: false}) { |
| 320 _addOption(name, abbr, help, allowed, allowedHelp, defaultsTo, | 332 _addOption(name, abbr, help, allowed, allowedHelp, defaultsTo, |
| 321 callback, isFlag: false, allowMultiple: allowMultiple); | 333 callback, isFlag: false, allowMultiple: allowMultiple); |
| 322 } | 334 } |
| 323 | 335 |
| 324 void _addOption(String name, String abbr, String help, List<String> allowed, | 336 void _addOption(String name, String abbr, String help, List<String> allowed, |
| 325 Map<String, String> allowedHelp, defaultsTo, | 337 Map<String, String> allowedHelp, defaultsTo, |
| 326 void callback(value), {bool isFlag, bool negatable: false, | 338 void callback(value), {bool isFlag, bool negatable: false, |
| 327 bool allowMultiple: false}) { | 339 bool allowMultiple: false}) { |
| 328 // Make sure the name isn't in use. | 340 // Make sure the name isn't in use. |
| 329 if (options.containsKey(name)) { | 341 if (_options.containsKey(name)) { |
| 330 throw new ArgumentError('Duplicate option "$name".'); | 342 throw new ArgumentError('Duplicate option "$name".'); |
| 331 } | 343 } |
| 332 | 344 |
| 333 // Make sure the abbreviation isn't too long or in use. | 345 // Make sure the abbreviation isn't too long or in use. |
| 334 if (abbr != null) { | 346 if (abbr != null) { |
| 335 var existing = findByAbbreviation(abbr); | 347 var existing = findByAbbreviation(abbr); |
| 336 if (existing != null) { | 348 if (existing != null) { |
| 337 throw new ArgumentError( | 349 throw new ArgumentError( |
| 338 'Abbreviation "$abbr" is already used by "${existing.name}".'); | 350 'Abbreviation "$abbr" is already used by "${existing.name}".'); |
| 339 } | 351 } |
| 340 } | 352 } |
| 341 | 353 |
| 342 options[name] = new Option(name, abbr, help, allowed, allowedHelp, | 354 _options[name] = new Option(name, abbr, help, allowed, allowedHelp, |
| 343 defaultsTo, callback, isFlag: isFlag, negatable: negatable, | 355 defaultsTo, callback, isFlag: isFlag, negatable: negatable, |
| 344 allowMultiple: allowMultiple); | 356 allowMultiple: allowMultiple); |
| 345 } | 357 } |
| 346 | 358 |
| 347 /** | 359 /** |
| 348 * Parses [args], a list of command-line arguments, matches them against the | 360 * Parses [args], a list of command-line arguments, matches them against the |
| 349 * flags and options defined by this parser, and returns the result. | 361 * flags and options defined by this parser, and returns the result. |
| 350 * | 362 * |
| 351 * If [allowTrailingOptions] is set, the parser will continue parsing even | 363 * If [allowTrailingOptions] is set, the parser will continue parsing even |
| 352 * after it finds an argument that is neither an option nor a command. | 364 * after it finds an argument that is neither an option nor a command. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 orElse: () => null); | 400 orElse: () => null); |
| 389 } | 401 } |
| 390 } | 402 } |
| 391 | 403 |
| 392 /** | 404 /** |
| 393 * The results of parsing a series of command line arguments using | 405 * The results of parsing a series of command line arguments using |
| 394 * [ArgParser.parse()]. Includes the parsed options and any remaining unparsed | 406 * [ArgParser.parse()]. Includes the parsed options and any remaining unparsed |
| 395 * command line arguments. | 407 * command line arguments. |
| 396 */ | 408 */ |
| 397 class ArgResults { | 409 class ArgResults { |
| 398 final Map _options; | 410 final Map<String, dynamic> _options; |
| 399 | 411 |
| 400 /** | 412 /** |
| 401 * If these are the results for parsing a command's options, this will be | 413 * If these are the results for parsing a command's options, this will be |
| 402 * the name of the command. For top-level results, this returns `null`. | 414 * the name of the command. For top-level results, this returns `null`. |
| 403 */ | 415 */ |
| 404 final String name; | 416 final String name; |
| 405 | 417 |
| 406 /** | 418 /** |
| 407 * The command that was selected, or `null` if none was. This will contain | 419 * The command that was selected, or `null` if none was. This will contain |
| 408 * the options that were selected for that command. | 420 * the options that were selected for that command. |
| 409 */ | 421 */ |
| 410 final ArgResults command; | 422 final ArgResults command; |
| 411 | 423 |
| 412 /** | 424 /** |
| 413 * The remaining command-line arguments that were not parsed as options or | 425 * The remaining command-line arguments that were not parsed as options or |
| 414 * flags. If `--` was used to separate the options from the remaining | 426 * flags. If `--` was used to separate the options from the remaining |
| 415 * arguments, it will not be included in this list. | 427 * arguments, it will not be included in this list. |
| 416 */ | 428 */ |
| 417 final List<String> rest; | 429 final List<String> rest; |
| 418 | 430 |
| 419 /** Creates a new [ArgResults]. */ | 431 /** Creates a new [ArgResults]. */ |
| 420 ArgResults(this._options, this.name, this.command, this.rest); | 432 ArgResults(this._options, this.name, this.command, List<String> rest) |
| 433 : this.rest = new UnmodifiableListView(rest); |
| 421 | 434 |
| 422 /** Gets the parsed command-line option named [name]. */ | 435 /** Gets the parsed command-line option named [name]. */ |
| 423 operator [](String name) { | 436 operator [](String name) { |
| 424 if (!_options.containsKey(name)) { | 437 if (!_options.containsKey(name)) { |
| 425 throw new ArgumentError( | 438 throw new ArgumentError( |
| 426 'Could not find an option named "$name".'); | 439 'Could not find an option named "$name".'); |
| 427 } | 440 } |
| 428 | 441 |
| 429 return _options[name]; | 442 return _options[name]; |
| 430 } | 443 } |
| 431 | 444 |
| 432 /** Get the names of the options as an [Iterable]. */ | 445 /** Get the names of the options as an [Iterable]. */ |
| 433 Iterable<String> get options => _options.keys; | 446 Iterable<String> get options => _options.keys; |
| 434 } | 447 } |
| 435 | 448 |
| OLD | NEW |