OLD | NEW |
(Empty) | |
| 1 Parses raw command-line arguments into a set of options and values. |
| 2 |
| 3 This library supports [GNU][] and [POSIX][] style options, and it works |
| 4 in both server-side and client-side apps. |
| 5 |
| 6 ## Defining options |
| 7 |
| 8 First create an [ArgParser][]: |
| 9 |
| 10 var parser = new ArgParser(); |
| 11 |
| 12 Then define a set of options on that parser using [addOption()][addOption] and |
| 13 [addFlag()][addFlag]. Here's the minimal way to create an option named "name": |
| 14 |
| 15 parser.addOption('name'); |
| 16 |
| 17 When an option can only be set or unset (as opposed to taking a string value), |
| 18 use a flag: |
| 19 |
| 20 ```dart |
| 21 parser.addFlag('name'); |
| 22 ``` |
| 23 |
| 24 Flag options, by default, accept a 'no-' prefix to negate the option. You can |
| 25 disable the 'no-' prefix using the `negatable` parameter: |
| 26 |
| 27 ```dart |
| 28 parser.addFlag('name', negatable: false); |
| 29 ``` |
| 30 |
| 31 *Note:* From here on out, "option" refers to both regular options and flags. In |
| 32 cases where the distinction matters, we'll use "non-flag option." |
| 33 |
| 34 Options can have an optional single-character abbreviation, specified with the |
| 35 `abbr` parameter: |
| 36 |
| 37 ```dart |
| 38 parser.addOption('mode', abbr: 'm'); |
| 39 parser.addFlag('verbose', abbr: 'v'); |
| 40 ``` |
| 41 |
| 42 Options can also have a default value, specified with the `defaultsTo` |
| 43 parameter. The default value is used when arguments don't specify the option. |
| 44 |
| 45 ```dart |
| 46 parser.addOption('mode', defaultsTo: 'debug'); |
| 47 parser.addFlag('verbose', defaultsTo: false); |
| 48 ``` |
| 49 |
| 50 The default value for non-flag options can be any string. For flags, it must |
| 51 be a `bool`. |
| 52 |
| 53 To validate a non-flag option, you can use the `allowed` parameter to provide an |
| 54 allowed set of values. When you do, the parser throws a [FormatException] if the |
| 55 value for an option is not in the allowed set. Here's an example of specifying |
| 56 allowed values: |
| 57 |
| 58 ```dart |
| 59 parser.addOption('mode', allowed: ['debug', 'release']); |
| 60 ``` |
| 61 |
| 62 You can use the `callback` parameter to associate a function with an option. |
| 63 Later, when parsing occurs, the callback function is invoked with the value of |
| 64 the option: |
| 65 |
| 66 ```dart |
| 67 parser.addOption('mode', callback: (mode) => print('Got mode $mode')); |
| 68 parser.addFlag('verbose', callback: (verbose) { |
| 69 if (verbose) print('Verbose'); |
| 70 }); |
| 71 ``` |
| 72 |
| 73 The callbacks for all options are called whenever a set of arguments is parsed. |
| 74 If an option isn't provided in the args, its callback is passed the default |
| 75 value, or `null` if no default value is set. |
| 76 |
| 77 ## Parsing arguments |
| 78 |
| 79 Once you have an [ArgParser][] set up with some options and flags, you use it by |
| 80 calling [ArgParser.parse()][parse] with a set of arguments: |
| 81 |
| 82 ```dart |
| 83 var results = parser.parse(['some', 'command', 'line', 'args']); |
| 84 ``` |
| 85 |
| 86 These arguments usually come from the arguments to `main()`. For example: |
| 87 |
| 88 main(List<String> args) { |
| 89 // ... |
| 90 var results = parser.parse(args); |
| 91 } |
| 92 |
| 93 However, you can pass in any list of strings. The `parse()` method returns an |
| 94 instance of [ArgResults][], a map-like object that contains the values of the |
| 95 parsed options. |
| 96 |
| 97 ```dart |
| 98 var parser = new ArgParser(); |
| 99 parser.addOption('mode'); |
| 100 parser.addFlag('verbose', defaultsTo: true); |
| 101 var results = parser.parse(['--mode', 'debug', 'something', 'else']); |
| 102 |
| 103 print(results['mode']); // debug |
| 104 print(results['verbose']); // true |
| 105 ``` |
| 106 |
| 107 By default, the `parse()` method stops as soon as it reaches `--` by itself or |
| 108 anything that the parser doesn't recognize as an option, flag, or option value. |
| 109 If arguments still remain, they go into [ArgResults.rest][rest]. |
| 110 |
| 111 ```dart |
| 112 print(results.rest); // ['something', 'else'] |
| 113 ``` |
| 114 |
| 115 To continue to parse options found after non-option arguments, pass |
| 116 `allowTrailingOptions: true` when creating the [ArgParser][]. |
| 117 |
| 118 ## Specifying options |
| 119 |
| 120 To actually pass in options and flags on the command line, use GNU or POSIX |
| 121 style. Consider this option: |
| 122 |
| 123 ```dart |
| 124 parser.addOption('name', abbr: 'n'); |
| 125 ``` |
| 126 |
| 127 You can specify its value on the command line using any of the following: |
| 128 |
| 129 ``` |
| 130 --name=somevalue |
| 131 --name somevalue |
| 132 -nsomevalue |
| 133 -n somevalue |
| 134 ``` |
| 135 |
| 136 Consider this flag: |
| 137 |
| 138 ```dart |
| 139 parser.addFlag('name', abbr: 'n'); |
| 140 ``` |
| 141 |
| 142 You can set it to true using one of the following: |
| 143 |
| 144 ``` |
| 145 --name |
| 146 -n |
| 147 ``` |
| 148 |
| 149 You can set it to false using the following: |
| 150 |
| 151 ``` |
| 152 --no-name |
| 153 ``` |
| 154 |
| 155 Multiple flag abbreviations can be collapsed into a single argument. Say you |
| 156 define these flags: |
| 157 |
| 158 ```dart |
| 159 parser |
| 160 ..addFlag('verbose', abbr: 'v') |
| 161 ..addFlag('french', abbr: 'f') |
| 162 ..addFlag('iambic-pentameter', abbr: 'i'); |
| 163 ``` |
| 164 |
| 165 You can set all three flags at once: |
| 166 |
| 167 ``` |
| 168 -vfi |
| 169 ``` |
| 170 |
| 171 By default, an option has only a single value, with later option values |
| 172 overriding earlier ones; for example: |
| 173 |
| 174 ```dart |
| 175 var parser = new ArgParser(); |
| 176 parser.addOption('mode'); |
| 177 var results = parser.parse(['--mode', 'on', '--mode', 'off']); |
| 178 print(results['mode']); // prints 'off' |
| 179 ``` |
| 180 |
| 181 If you need multiple values, set the `allowMultiple` parameter. In that case the |
| 182 option can occur multiple times, and the `parse()` method returns a list of |
| 183 values: |
| 184 |
| 185 ```dart |
| 186 var parser = new ArgParser(); |
| 187 parser.addOption('mode', allowMultiple: true); |
| 188 var results = parser.parse(['--mode', 'on', '--mode', 'off']); |
| 189 print(results['mode']); // prints '[on, off]' |
| 190 ``` |
| 191 |
| 192 By default, values for a multi-valued option may also be separated with commas: |
| 193 |
| 194 ```dart |
| 195 var parser = new ArgParser(); |
| 196 parser.addOption('mode', allowMultiple: true); |
| 197 var results = parser.parse(['--mode', 'on,off']); |
| 198 print(results['mode']); // prints '[on, off]' |
| 199 ``` |
| 200 |
| 201 This can be disabled by passing `splitCommas: false`. |
| 202 |
| 203 ## Defining commands ## |
| 204 |
| 205 In addition to *options*, you can also define *commands*. A command is a named |
| 206 argument that has its own set of options. For example, consider this shell |
| 207 command: |
| 208 |
| 209 ``` |
| 210 $ git commit -a |
| 211 ``` |
| 212 |
| 213 The executable is `git`, the command is `commit`, and the `-a` option is an |
| 214 option passed to the command. You can add a command using the [addCommand][] |
| 215 method: |
| 216 |
| 217 ```dart |
| 218 var parser = new ArgParser(); |
| 219 var command = parser.addCommand('commit'); |
| 220 ``` |
| 221 |
| 222 It returns another [ArgParser][], which you can then use to define options |
| 223 specific to that command. If you already have an [ArgParser][] for the command's |
| 224 options, you can pass it in: |
| 225 |
| 226 ```dart |
| 227 var parser = new ArgParser(); |
| 228 var command = new ArgParser(); |
| 229 parser.addCommand('commit', command); |
| 230 ``` |
| 231 |
| 232 The [ArgParser][] for a command can then define options or flags: |
| 233 |
| 234 ```dart |
| 235 command.addFlag('all', abbr: 'a'); |
| 236 ``` |
| 237 |
| 238 You can add multiple commands to the same parser so that a user can select one |
| 239 from a range of possible commands. When parsing an argument list, you can then |
| 240 determine which command was entered and what options were provided for it. |
| 241 |
| 242 ```dart |
| 243 var results = parser.parse(['commit', '-a']); |
| 244 print(results.command.name); // "commit" |
| 245 print(results.command['all']); // true |
| 246 ``` |
| 247 |
| 248 Options for a command must appear after the command in the argument list. For |
| 249 example, given the above parser, `"git -a commit"` is *not* valid. The parser |
| 250 tries to find the right-most command that accepts an option. For example: |
| 251 |
| 252 ```dart |
| 253 var parser = new ArgParser(); |
| 254 parser.addFlag('all', abbr: 'a'); |
| 255 var command = parser.addCommand('commit'); |
| 256 command.addFlag('all', abbr: 'a'); |
| 257 |
| 258 var results = parser.parse(['commit', '-a']); |
| 259 print(results.command['all']); // true |
| 260 ``` |
| 261 |
| 262 Here, both the top-level parser and the `"commit"` command can accept a `"-a"` |
| 263 (which is probably a bad command line interface, admittedly). In that case, when |
| 264 `"-a"` appears after `"commit"`, it is applied to that command. If it appears to |
| 265 the left of `"commit"`, it is given to the top-level parser. |
| 266 |
| 267 ## Dispatching Commands |
| 268 |
| 269 If you're writing a command-based application, you can use the [CommandRunner][] |
| 270 and [Command][] classes to help structure it. [CommandRunner][] has built-in |
| 271 support for dispatching to [Command][]s based on command-line arguments, as well |
| 272 as handling `--help` flags and invalid arguments. For example: |
| 273 |
| 274 ```dart |
| 275 var runner = new CommandRunner("git", "Distributed version control.") |
| 276 ..addCommand(new CommitCommand()) |
| 277 ..addCommand(new StashCommand()) |
| 278 ..run(['commit', '-a']); // Calls [CommitCommand.run()] |
| 279 ``` |
| 280 |
| 281 Custom commands are defined by extending the [Command][] class. For example: |
| 282 |
| 283 ```dart |
| 284 class CommitCommand extends Command { |
| 285 // The [name] and [description] properties must be defined by every |
| 286 // subclass. |
| 287 final name = "commit"; |
| 288 final description = "Record changes to the repository."; |
| 289 |
| 290 CommitCommand() { |
| 291 // [argParser] is automatically created by the parent class. |
| 292 argParser.addFlag('all', abbr: 'a'); |
| 293 } |
| 294 |
| 295 // [run] may also return a Future. |
| 296 void run() { |
| 297 // [options] is set before [run()] is called and contains the options |
| 298 // passed to this command. |
| 299 print(options['all']); |
| 300 } |
| 301 } |
| 302 ``` |
| 303 |
| 304 Commands can also have subcommands, which are added with [addSubcommand][]. A |
| 305 command with subcommands can't run its own code, so [run][] doesn't need to be |
| 306 implemented. For example: |
| 307 |
| 308 ```dart |
| 309 class StashCommand extends Command { |
| 310 final String name = "stash"; |
| 311 final String description = "Stash changes in the working directory."; |
| 312 |
| 313 StashCommand() { |
| 314 addSubcommand(new StashSaveCommand()); |
| 315 addSubcommand(new StashListCommand()); |
| 316 } |
| 317 } |
| 318 ``` |
| 319 |
| 320 [CommandRunner][] automatically adds a `help` command that displays usage |
| 321 information for commands, as well as support for the `--help` flag for all |
| 322 commands. If it encounters an error parsing the arguments or processing a |
| 323 command, it throws a [UsageError][]; your `main()` method should catch these and |
| 324 print them appropriately. For example: |
| 325 |
| 326 ```dart |
| 327 runner.run(arguments).catchError((error) { |
| 328 if (error is! UsageError) throw error; |
| 329 print(error); |
| 330 exit(64); // Exit code 64 indicates a usage error. |
| 331 }); |
| 332 ``` |
| 333 |
| 334 ## Displaying usage |
| 335 |
| 336 You can automatically generate nice help text, suitable for use as the output of |
| 337 `--help`. To display good usage information, you should provide some help text |
| 338 when you create your options. |
| 339 |
| 340 To define help text for an entire option, use the `help:` parameter: |
| 341 |
| 342 ```dart |
| 343 parser.addOption('mode', help: 'The compiler configuration', |
| 344 allowed: ['debug', 'release']); |
| 345 parser.addFlag('verbose', help: 'Show additional diagnostic info'); |
| 346 ``` |
| 347 |
| 348 For non-flag options, you can also provide a help string for the parameter: |
| 349 |
| 350 ```dart |
| 351 parser.addOption('out', help: 'The output path', valueHelp: 'path', |
| 352 allowed: ['debug', 'release']); |
| 353 ``` |
| 354 |
| 355 For non-flag options, you can also provide detailed help for each expected value |
| 356 by using the `allowedHelp:` parameter: |
| 357 |
| 358 ```dart |
| 359 parser.addOption('arch', help: 'The architecture to compile for', |
| 360 allowedHelp: { |
| 361 'ia32': 'Intel x86', |
| 362 'arm': 'ARM Holding 32-bit chip' |
| 363 }); |
| 364 ``` |
| 365 |
| 366 To display the help, use the [getUsage()][getUsage] method: |
| 367 |
| 368 ```dart |
| 369 print(parser.getUsage()); |
| 370 ``` |
| 371 |
| 372 The resulting string looks something like this: |
| 373 |
| 374 ``` |
| 375 --mode The compiler configuration |
| 376 [debug, release] |
| 377 |
| 378 --out=<path> The output path |
| 379 --[no-]verbose Show additional diagnostic info |
| 380 --arch The architecture to compile for |
| 381 [arm] ARM Holding 32-bit chip |
| 382 [ia32] Intel x86 |
| 383 ``` |
| 384 |
| 385 [posix]: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html
#tag_12_02 |
| 386 [gnu]: http://www.gnu.org/prep/standards/standards.html#Command_002dLine-Interfa
ces |
| 387 [ArgParser]: http://www.dartdocs.org/documentation/args/latest/index.html#args/a
rgs.ArgParser |
| 388 [ArgResults]: http://www.dartdocs.org/documentation/args/latest/index.html#args/
args.ArgResults |
| 389 [CommandRunner]: http://www.dartdocs.org/documentation/args/latest/index.html#ar
gs/args.CommandRunner |
| 390 [Command]: http://www.dartdocs.org/documentation/args/latest/index.html#args/arg
s.Command |
| 391 [UsageError]: http://www.dartdocs.org/documentation/args/latest/index.html#args/
args.UsageError |
| 392 [addOption]: http://www.dartdocs.org/documentation/args/latest/index.html#args/a
rgs.ArgParser@id_addOption |
| 393 [addFlag]: http://www.dartdocs.org/documentation/args/latest/index.html#args/arg
s.ArgParser@id_addFlag |
| 394 [parse]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.
ArgParser@id_parse |
| 395 [rest]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.A
rgResults@id_rest |
| 396 [addCommand]: http://www.dartdocs.org/documentation/args/latest/index.html#args/
args.ArgParser@id_addCommand |
| 397 [getUsage]: http://www.dartdocs.org/documentation/args/latest/index.html#args/ar
gs.ArgParser@id_getUsage |
| 398 [addSubcommand]: http://www.dartdocs.org/documentation/args/latest/index.html#ar
gs/args.Command@id_addSubcommand |
| 399 [run]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.Co
mmand@id_run |
OLD | NEW |