[ 
https://issues.apache.org/jira/browse/CLI-221?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18012890#comment-18012890
 ] 

Claude Warren commented on CLI-221:
-----------------------------------

[~jbudi] 

"After parsing" is a bit of a misnomer here.  converters are the final step in 
parsing.  though in some cases there is no converter so a "null" converter is 
the final step.

Currently the Option argument frame determines if a token is an option argument 
or not.  This does not change.  So the CommandLine.getArgs() method does not 
change.

Option converters do not decide how many arguments there are.  Option 
converters decide how to interpret the argument(s).

the methods on Option do the following.

hasArg() works as it does now.  It reports true if the option can take an 
argument.

getArgs() works as it does now and reports the number of arguments (tokens) 
that the option can hold.

numberOfArgs is a builder option that sets the result for getArgs()
h2. Some examples

most of the examples use the arguments *"--colors red,blue yellow,green b"* any 
deviation wll be listed in the example

*With option* 
Option.builder().option("c").longOpt("colors").hasArgs().build();
 
executing
final String [] colorValues = commandLine.getOptionValues(colors)
 
yields ["red,blue", "yellow,green", "b"]
 
*With option*
Option.builder().option("c").longOpt("colors").valueSeparator().hasArgs().build();
 
executing
final String [] colorValues = commandLine.getOptionValues(colors)
 
yields ["red,blue", "yellow,green", "b"]
 
*With option*
Option.builder().option("c").longOpt("colors").type(String[].class).converter(s 
-> s.split(",")).hasArgs().build();
 
executing colorValues = commandLine.getParsedOptionValues(colors)
 
yields [["red,blue"], ["yellow","green"], ["b"]]
 
{*}With option{*}{*}{*}
Option.builder().option("c").longOpt("colors").type(String[].class).converter(s 
-> s.split(",")).hasArgs().build();
 
executing

colorValues = commandLine.getParsedOptionValue(colors)
 
and input of "–colors red,blue -- yellow,green b"
Keeping in mind that all multi-argument options must end with a double dash, 
another option, or the end of the command line.
 
yields ["red" ,"blue"]
and leaves the remainder unprocessed.
 
*With option*
Option.builder().option("c").longOpt("colors").listValueSeparator().hasArgs().build();
 
executing
colorValues = commandLine.getOptionValues(colors)
 
yields ["red" ," blue"]
and leaves the remainder unprocessed.
 
*With option*
Option.builder().option("c").longOpt("colors").listValueSeparator().numberOfArgs(3).build();
 
executing
colorValues = commandLine.getOptionValues(colors)
 
yields["red", "blue"]
and leaves the remainder unprocessed.
 
h2. Summary

Using listValueSeparator breaks the current model in that it ignores the 
maximum number of arguments as specified in the option and limits it to one (1).
 
The current system can parse the arguments to an option to provide a list, or 
multiple lists.
 
The current system does have the requirement for multiple argument options to 
have a double dash to terminate the option if it proceeds any tokens that 
should be reported as args by the command line.
 
Perhaps issues with requiring the double dash and parsing numbers as options 
should be dealt with as contexts in which the parser will run.
 
While I see the benefit of having the ability to parse one string into a fixed 
number of options, I think that this solution creates more problems in that it 
changes limit on tokens processed.
 
A better solution, in my mind, is that to have the option parse the tokens into 
arguments and have the converter parse the arguments into objects.  A converter 
can be implemented so that it would throw an exception if too many objects were 
returned.
 
 
 
 
 

> cli's with last option as list type values and have argument are not parsed 
> correctly
> -------------------------------------------------------------------------------------
>
>                 Key: CLI-221
>                 URL: https://issues.apache.org/jira/browse/CLI-221
>             Project: Commons CLI
>          Issue Type: Bug
>          Components: Parser
>    Affects Versions: 1.2
>            Reporter: Gagan Jain
>            Priority: Major
>
> I have set the value separator for an option to be comma (',').
> Consider the following cli:
> cli definition : cmd1 -o1 <comma separated values> a1
> command name: 'cmd1'
> options: 'o1' accpets list of values separated by ','
> arguments: 'a1' single valued argument
> {code}cmd1 -o1 o1v1,o1v2,o1v3 a1v1{code}
> GnuParser parses this the cli with o1 having values {o1v1, o1v2, o1v3, a1v1} 
> instead of {o1v1,o1v2,o1v3}
> Bug seems to be in org.apache.commons.cli.Parser's class processArgs method.
> {code:java}
>     public void processArgs(Option opt, ListIterator iter) throws 
> ParseException
>     {
>         // loop until an option is found
>         while (iter.hasNext())
>         {
>             String str = (String) iter.next();
>             // found an Option, not an argument
>             if (getOptions().hasOption(str) && str.startsWith("-"))
>             {
>                 iter.previous();
>                 break;
>             }
>             // found a value
>             try
>             {
>                 
> opt.addValueForProcessing(Util.stripLeadingAndTrailingQuotes(str));
>             }
>             catch (RuntimeException exp)
>             {
>                 iter.previous();
>                 break;
>             }
>         }
>         if (opt.getValues() == null && !opt.hasOptionalArg())
>         {
>             throw new MissingArgumentException(opt);
>         }
>     }
> {code}
> In my opinion, if a value separator is defined for option, and is other than 
> space (' '), loop should break immediately after one iteration.
> Correct me, if I am wrong in my understanding.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to