@@ -52,91 +52,96 @@ class MyArgs(parser: ArgParser) {
5252
5353Various types of options can be parsed from the command line arguments:
5454
55- - Boolean flags are created by asking the parser for a ` flagging ` delegate. One
56- or more option names, either short or long style, must be provided:
55+ ### Boolean Flags
5756
58- ``` kotlin
59- val verbose by parser.flagging(" -v" , " --verbose" ,
60- help = " enable verbose mode" )
61- ```
57+ Boolean flags are created by asking the parser for a ` flagging ` delegate. One
58+ or more option names, either short or long style, must be provided:
6259
63- Here the presence of either ` -v ` or ` --verbose ` options in the
64- arguments will cause the ` Boolean ` property ` verbose ` to be ` true ` , otherwise
65- it will be ` false ` .
60+ ``` kotlin
61+ val verbose by parser.flagging(" -v" , " --verbose" ,
62+ help = " enable verbose mode" )
63+ ```
6664
67- - Single argument options are created by asking the parser for a
68- ` storing ` delegate.
65+ Here the presence of either ` -v ` or ` --verbose ` options in the
66+ arguments will cause the ` Boolean ` property ` verbose ` to be ` true ` , otherwise
67+ it will be ` false ` .
6968
70- ``` kotlin
71- val name by parser.storing(" -N" , " --name" ,
72- help = " name of the widget" )
73- ```
69+ ### Storing a Single Argument
7470
75- Here either ` -N ` or ` --name ` with an argument will cause ` name ` to have that
76- argument as its value .
71+ Single argument options are created by asking the parser for a
72+ ` storing ` delegate .
7773
78- A function can also be supplied to transform the argument into the desired
79- type. Here the ` size ` property will be an ` Int ` rather than a ` String ` :
74+ ``` kotlin
75+ val name by parser.storing(" -N" , " --name" ,
76+ help = " name of the widget" )
77+ ```
8078
81- ``` kotlin
82- val size by parser.storing(" -s" , " --size" ,
83- help = " size of the plumbus" ) { toInt() }
84- ```
79+ Here either ` -N ` or ` --name ` with an argument will cause ` name ` to have that
80+ argument as its value.
8581
86- - Options that add to a ` Collection ` each time they
87- appear in the arguments are created with using the ` adding ` delegate. Just like ` storing `
88- delegates, a transform function may optionally be supplied:
82+ A function can also be supplied to transform the argument into the desired
83+ type. Here the ` size ` property will be an ` Int ` rather than a ` String ` :
8984
90- ``` kotlin
91- val includeDirs by parser.adding(
92- " -I " , help = " directory to search for header files " ) { File ( this ) }
93- ```
85+ ``` kotlin
86+ val size by parser.storing( " -s " , " --size " ,
87+ help = " size of the plumbus " ) { toInt( ) }
88+ ```
9489
95- Now each time the ` -I ` option appears, its argument is appended to
96- ` includeDirs ` .
90+ ### Adding to a Collection
9791
98- - For choosing between a fixed set of values (typically, but not necessarily,
99- from an enum), a ` mapping ` delegate can be used:
92+ Options that add to a ` Collection ` each time they
93+ appear in the arguments are created with using the ` adding ` delegate. Just like ` storing `
94+ delegates, a transform function may optionally be supplied:
10095
101- ``` kotlin
102- val mode by parser.mapping(
103- " --fast" to Mode .FAST ,
104- " --small" to Mode .SMALL ,
105- " --quiet" to Mode .QUIET ,
106- help = " mode of operation" )
107- ```
96+ ``` kotlin
97+ val includeDirs by parser.adding(
98+ " -I" , help = " directory to search for header files" ) { File (this ) }
99+ ```
108100
109- Here the ` mode ` property will be set to the corresponding ` Mode ` value depending
110- on which of ` --fast ` , ` --small ` , and ` --quiet ` appears (last) in the arguments .
101+ Now each time the ` -I ` option appears, its argument is appended to
102+ ` includeDirs ` .
111103
112- ` mapping ` is one of the few cases where it is not possible to infer the option
113- name from the property name.
104+ ### Mapping from an option to a fixed value
114105
115- ## Modifying Delegates
106+ For choosing between a fixed set of values (typically, but not necessarily,
107+ from an enum), a ` mapping ` delegate can be used:
116108
117- The delegates returned by any of these methods also have a few methods for setting
118- optional attributes:
109+ ``` kotlin
110+ val mode by parser.mapping(
111+ " --fast" to Mode .FAST ,
112+ " --small" to Mode .SMALL ,
113+ " --quiet" to Mode .QUIET ,
114+ help = " mode of operation" )
115+ ```
119116
120- - Some types of options (notably ` storing ` and ` mapping ` ) have no
121- default value, and hence will be required options unless a default
122- value is provided. This is done with the ` default ` method:
117+ Here the ` mode ` property will be set to the corresponding ` Mode ` value depending
118+ on which of ` --fast ` , ` --small ` , and ` --quiet ` appears (last) in the arguments.
123119
124- ``` kotlin
125- val name by parser.storing(" -N" , " --name" , help= " ..." )
126- .default(" John Doe" )
127- ```
120+ ` mapping ` is one of the few cases where it is not possible to infer the option
121+ name from the property name.
128122
129- - Sometimes it's easier to validate an option at the end pf parsing, in which
130- case the ` addValidator ` method can be used.
123+ ### More advanced options
131124
132- ``` kotlin
133- val percentages by parser.adding(" --percentages" , help= " ..." ) { toInt() }
134- .addValidator {
135- if (sum() != 100 )
136- throw InvalidArgumentException (
137- " Percentages must add up to 100%" )
125+ For all other types of options, the ` option ` method should be used. The
126+ methods mentioned above are, in fact, convenience methods built on top of the
127+ ` option ` method.
128+
129+ For example, it is possible to create an option that has multiple arguments:
130+
131+ fun ArgParser.putting(vararg names: String, help: String) =
132+ option<MutableMap<String, String>>(* names,
133+ argNames = listOf("KEY", "VALUE"),
134+ help = help) {
135+ value.orElse { mutableMapOf<String, String>() }.apply {
136+ put(arguments.first(), arguments.last()) }
138137 }
139- ```
138+
139+ Note that the ` option ` method does not have an auto-naming overload. If you
140+ need this capability, create a ` DelegateProvider ` that creates your ` Delegate ` :
141+
142+ fun ArgParser.putting(help: String) =
143+ ArgParser.DelegateProvider { identifier ->
144+ putting(identifierToOptionName(identifier), help = help) }
140145
141146
142147## Positional Arguments
@@ -176,6 +181,40 @@ val sources by parser.positionalList("SOURCE", 1..Int.MAX_VALUE,
176181```
177182
178183
184+ ## Modifying Delegates
185+
186+ The delegates returned by any of these methods also have a few methods for setting
187+ optional attributes:
188+
189+ - Some types of delegates (notably ` storing ` , ` mapping ` , and ` positional ` ) have no
190+ default value, and hence will be required options unless a default
191+ value is provided. This is done with the ` default ` method:
192+
193+ ``` kotlin
194+ val name by parser.storing(" -N" , " --name" , help= " ..." ).default(" John Doe" )
195+ ```
196+
197+ Note that it * is* possible to use ` null ` for the default:
198+
199+ ``` kotlin
200+ val name by parser.storing(" -N" , " --name" , help= " ..." ).default(null )
201+ ```
202+
203+ The resulting value will be nullable (a ` String? ` in this case).
204+
205+ - Sometimes it's easier to validate an option at the end pf parsing, in which
206+ case the ` addValidator ` method can be used.
207+
208+ ``` kotlin
209+ val percentages by parser.adding(" --percentages" , help= " ..." ) { toInt() }
210+ .addValidator {
211+ if (sum() != 100 )
212+ throw InvalidArgumentException (
213+ " Percentages must add up to 100%" )
214+ }
215+ ```
216+
217+
179218## Error Handling
180219
181220Exceptions caused by user error will all derive from ` SystemExitException ` , and
@@ -265,9 +304,9 @@ my_program --foo ARGUMENT
265304
266305### Multi-argument Options
267306
268- Multi-argument options are supported, though not by any of the convenience
269- methods. Option-arguments after the first must be separate command-line
270- arguments, for both an long and short forms of an option.
307+ Multi-argument options are supported, though currently not by any of the
308+ convenience methods. Option-arguments after the first must be separate
309+ command-line arguments, for both an long and short forms of an option.
271310
272311### Positional Arguments
273312
@@ -313,11 +352,56 @@ And equally easy to create a program that behaves like `cp`:
313352 ```
314353
315354
316- <!--
317355## Help Formatting
318356
319- TODO: write an explanation of help formatting
320- -->
357+ By default, ` ArgParser ` will add a ` --help ` option (short name ` -h ` ) for
358+ displaying usage information. If this option is present the program will halt
359+ and print a help message like the one below, based on the ` ArgParser `
360+ configuration:
361+
362+ usage: program_name [-h] [-n] [-I INCLUDE]... -o OUTPUT
363+ [-v]... SOURCE... DEST
364+
365+
366+ This is the prologue. Lorem ipsum dolor sit amet, consectetur
367+ adipiscing elit. Aliquam malesuada maximus eros. Fusce
368+ luctus risus eget quam consectetur, eu auctor est
369+ ullamcorper. Maecenas eget suscipit dui, sed sodales erat.
370+ Phasellus.
371+
372+
373+ required arguments:
374+ -o OUTPUT, directory in which all output should
375+ --output OUTPUT be generated
376+
377+
378+ optional arguments:
379+ -h, --help show this help message and exit
380+
381+ -n, --dry-run don't do anything
382+
383+ -I INCLUDE, search in this directory for header
384+ --include INCLUDE files
385+
386+ -v, --verbose increase verbosity
387+
388+
389+ positional arguments:
390+ SOURCE source file
391+
392+ DEST destination file
393+
394+
395+ This is the epilogue. Lorem ipsum dolor sit amet,
396+ consectetur adipiscing elit. Donec vel tortor nunc. Sed eu
397+ massa sed turpis auctor faucibus. Donec vel pellentesque
398+ tortor. Ut ultrices tempus lectus fermentum vestibulum.
399+ Phasellus.
400+
401+ The creation of the ` --help ` option can be disabled by passing ` null ` as the
402+ ` helpFormatter ` when constructing the ` ArgParser ` , or configured by manually
403+ constructing a ` HelpFormatter ` instance. In the above example a
404+ ` DefaultHelpFormatter ` was created with the prologue and epilogue.
321405
322406
323407## Caveats
@@ -331,11 +415,33 @@ TODO: write an explanation of help formatting
331415 parsed. This means it's important that you don't attempt to create delegates
332416 on an ` ArgParser ` after any of its existing delegated properties have been
333417 read. Attempting to do so will cause an ` IllegalStateException ` . It would be
334- nice if Kotlin has facilities for doing some of the work of ` ArgParser ` at
418+ nice if Kotlin had facilities for doing some of the work of ` ArgParser ` at
335419 compile time rather than run time, but so far the run time errors seem to be
336420 reasonably easy to avoid.
337421
338422
423+ ## Configuring your Build
424+
425+ Kotlin-argparser binaries are hosted on Bintray's center. In Gradle, use
426+ something like this in your ` build.gradle ` :
427+
428+ buildscript {
429+ repositories {
430+ jcenter()
431+ }
432+ }
433+
434+ dependencies {
435+ compile "com.xenomachina:kotlin-argparser:$kotlin_argparser_version"
436+ }
437+
438+ More information on setting up your Gradle, Maven, or Ivy
439+ dependencies can be found under the "Maven build settings" heading on
440+ [ Kotlin-argparser's Bintray
441+ page] ( https://bintray.com/xenomachina/maven/kotlin-argparser/_latestVersion ) ,
442+ as well as the version of the latest release.
443+
444+
339445## Credits
340446
341447This library was created by [ Laurence Gonsalves] ( http://laurence.gonsalv.es ) .
0 commit comments