Big +1 on having the support, I'm just trying to get my head around the proposal for now.

What does the validator do? I'd imagine the following call is all thats needed but the ... hints that I should be expecting
something more involved and have got the wrong end of the stick.
return optionsMap.keySet().contains(value);
Well the validators are independent of the OptionsMap, check out the
latest source in CVS, I checked in some a simple String validator.
It currently only works for any Option directly added to the Options
instance.  I need to add support for OptionGroups as well.

So if I understand correctly to support multiple commands with different options and aliases, a single argument "command" would be
used with options something like the following:


OptionsMap optionsMap = new OptionsMap();

    // checkout command
    optionsMap.add("checkout", checkoutOptions);
    optionsMap.add("co", checkoutOptions);
    optionsMap.add("get", checkoutOptions);

    // commit command
    optionsMap.add("commit", commitOptions);
    optionsMap.add("ci", commitOptions);
    optionsMap.add("com", commitOptions);

// ...

It seems to me that this is losing information as to which commands are the preferred name and which are the synonyms. From a
generated help point of view this is useful information and it also doesn't allow for descriptions to be attached to the different
commands.
I agree with your point regarding losing information. I don't think associating
descriptions with each alias is a good idea. I think only one alias should be
displayed in the help, it would be up to the user doc to specify the rest.


Instead of this approach I would suggest something along the following lines:
(Note this is just design phase talk, I haven't tried to implement this at all but will be happy to muck in. Presumably using a new
Command class but I'm not sure how it fits with AnonymousArgument yet)


Each separate command should get it's own Option.

checkoutCommand = cbuilder
.withOptions(checkoutOptions) // enter the suboptions once
.addAlias("co") // add as many alias / synonyms as needed
.addAlias("get")
.withDescription("Checks out a new working copy") // add some help text
.create("checkout")); // add the preferred name of the command


checkinCommand = cbuilder
.withOptions(checkinOptions) // enter the suboptions once
.addAlias("ci") // add as many alias / synonyms as needed
.addAlias("com")
.withDescription("Sends local changes to the server") // add some help text
.create("commit")); // add the preferred name of the command


...

I think the help should only print the "checkout" and "commit" and not worry
about the aliases.


To achieve CVS style operation these should be added to an exclusive group, but its possible that commands could be used in an
inclusive manner too.


    Set commands = new HashSet();
    commands.add(checkoutCommand);
    commands.add(checkinCommand);
    ...
    options.addOptionGroup(commands);

The previous proposal seemed to be targetting a usage line of:
    cvs [options] command [command-options]
But the structure described above should allow something like:
    cvs [options] checkout | commit | ...

I think the second style has too much information. For the case of CVS, it would be
very very long. I need to think a bit more about this, there could be a special built
in option e.g. cvs --help-commands. This produces the list of commands and their
descriptions.


And the HelpFormatter would be able to produce useful help along the lines of:

cvs [options] checkout | commit | ...

checkout | commit | ...

        checkout [co, get]  : Checks out a new working copy
            -A              : Reset sticky tags
            -P              : Prunes empty directory

        commit [ci, com]    : Sends local changes to the server
            -R              : Process directories recursively
            -m msg          : Log message

...

One other prickly issue: cvs views options before and after the command as entirely separate things. Even so far as to have the
same option "-d" mean different things depending on whether it comes before or after the "checkout" for instance. Do either
proposals allow this? (I don't think mine would). Do we want to support this?

Hmm, the current implementation doesn't support this. I don't know if we want
to support it, it is quite confusing.


Personally I think it was a mistake of CVS to do this
and that the position of the global options shouldn't matter but others may disagree.

I agree with you that its a mistake, but I will spend some time thinking about
it to see if it is possible to come up with a solution.


Thanks for all that information. I will post whatever I come up with (keeping
your ideas in mind) soon.


Thanks,
-John K


Rob



----- Original Message ----- From: "John Keyes" <[EMAIL PROTECTED]> To: "commons-dev" <[EMAIL PROTECTED]> Sent: Monday, June 09, 2003 9:18 AM Subject: [CLI] Support for CVS style command line


The CVS command line is defined as follows:


cvs [options] command [command-options]

Ideally I would like to have CLI support this implicity, i.e.
validate the 'command' value (this was a feature already
recommended by Mike McLean and modified by Max Rydahl Andersen)
and based on this value parse the remaining Options.

There are two steps in this:
   . value validation
   . mapping value to Options

So here's an example:

   ValueValidator commandValidator = new StringValidator() {
       public boolean validate(String value) {
           ...
       }
   }

   OptionsMap optionsMap = new OptionsMap();
   optionsMap.add("checkout", checkoutOptions);
   optionsMap.add("co", checkoutOptions);

   // this means that there is an Anonymous Argument which will
   // have one value and the HelpFormatter will spit 'command'
   // out in the help text, the value found in the args will
   // be validated by the specified validator
   Argument command = abuilder.withOptionMap(optionsMap)
                              .withValidator(commandValidator)
                              .createAnonymous("command",1);

   // args - "cvs co file.txt"
   CommandLine line = parser.parse(opts, args);

The parse would find 'co' as the Anonymous Argument, and then
validate that the value is allowable, when it confirms that it
is valuable then query the OptionsMap to see if there are any
Options specified for that value.  If there are Options, then
parse the remaining args (file.txt) using them.  If there
are no Options, then throw an exception as there is only
one value allowed for the anonymous argument.

What do people think of this?  Does it sound good?  Are there
any better ideas?

Cheers,
-John K

- - - - - - - - - - - - - - - - - - - - - - -
Jakarta Commons CLI
http://jakarta.apache.org/commons/cli

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]


- - - - - - - - - - - - - - - - - - - - - - -
Jakarta Commons CLI
http://jakarta.apache.org/commons/cli


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to