xenomachina / kotlin-argparser

Easy to use and concise yet powerful and robust command line argument parsing for Kotlin
GNU Lesser General Public License v2.1
482 stars 33 forks source link

Add support for a Java like parser mode #7

Open HaasJona opened 7 years ago

HaasJona commented 7 years ago

It would be nice to have a parser mode which parses all arguments as long arguments regardless of the amount of dashes, so you could have a parser that parses like typical java applications (for example consider java -version).

xenomachina commented 7 years ago

Thanks for the suggestion. Any ideas on how option names would be specified? Right now you include the dashes, like:

val verbose by parser.flagging("-v", "--verbose",

Would the client instead have to say "-verbose", or would or would "--verbose" be transformed into "-verbose"?

Also, right now it's also possible (though arguably inadvisable) to have single letter "long" options:

val short_a by parser.flagging("-a", ... 
val long_a by parser.flagging("--a", ...

I'm thinking this would be an error in a Java flag mode.

I'm not entirely clear on how option arguments are handled with Java-style options. Looking at the options of java, some, like -ea, -splash, seem to require an intervening colon, while others do not (-X, -D). It looks like it may be the case that long options use the colon, while short options do not, which is kind of similar tow how POSIX and GNU style options work, except they use "=" rather than ":" for long option arguments.

One thing I'm not sure how to resolve is that Java style options seem to let the option decide whether the first of its arguments must be in the same argument, as in -agentpath, or as a separate command line argument, as in -cp. In kotlin-argparser these would both be storing long options, and there is nowhere for the client to indicate this distinction. I'm inclined to just make it impossible to exactly emulate the options of java. So -cp:CLASSPATH would become legal, as would -agentpath AGENTPATH.

Playing around with this actually made me realize that there's a small bug with the existing parsing in that you cannot create an option that non-greedily takes an optional argument, like the -version option of java. I filed issue #8 about this.

HaasJona commented 7 years ago

Would the client instead have to say "-verbose", or would or would "--verbose" be transformed into "-verbose"?

I'd vote for

val verbose by parser.flagging("-v", "-verbose", ...)

or if you don't need/want the short form simply

val verbose by parser.flagging("-verbose", ...)

Main difference would be to always go into the first if branch here if Java mode is active and only one dash is there: https://github.com/xenomachina/kotlin-argparser/blob/master/src/main/kotlin/ArgParser.kt#L434

I'm not entirely clear on how option arguments are handled with Java-style options.

I'd keep it simple for now. Java isn't necessarily super consistent here. I'd personally only need this:

-a
-b -test -file=foo.txt
-abc=def variable1 variable2

no weird colons and so on.