You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Rob Oxspring <ro...@imapmail.org> on 2003/07/01 14:46:21 UTC

Re: [CLI] Do we have the correct model? (was Re: [CLI] Support for CVS style command line)

Sounds like a good plan to me.

Rob

----- Original Message ----- 
From: "John Keyes" <jb...@mac.com>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Sunday, June 29, 2003 11:10 PM
Subject: Re: [CLI] Do we have the correct model? (was Re: [CLI] Support for CVS style command line)


> Rob,
> 
> I've been looking at your code and I like the structure.  I'm willing  
> to add
> this to a new branch (so we can synchronize changes) and we can work on  
> it
> for the next couple of weeks and see how we think things are  
> progressing.
> 
> I think the first thing we should do is add the tests from the cli_1_x.
> This will allow us to get the API in place.  By this I mean adding the
> XXXBuilder classes and the CommandLineParser class.
> 
> Let me know what you think and I'll get the ball rolling,
> -John K
> 
> On Friday, Jun 20, 2003, at 00:27 Europe/Dublin, Rob Oxspring wrote:
> 
> > ----- Original Message -----
> > From: "John Keyes" <jb...@mac.com>
> > To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
> > Sent: Wednesday, June 18, 2003 10:21 PM
> > Subject: Re: [CLI] Do we have the correct model? (was Re: [CLI]  
> > Support for CVS style command line)
> >
> >
> >> Hi Rob,
> >>
> >> <snip/>
> >>
> >>> (I hope you don't regret the "bouncing the ideas around" comment too
> >>> much
> >>> John :o) )
> >>
> >> Is it too late to take it back ;)
> >>
> >>> OptionImpl vs. CommandImpl.  Although these two types of object share
> >>> the common feature of appearing on a command line and having a group
> >>> of child options, I'm not convinced that one is an extension of the
> >>> other.  As a result I've struggled to fit Command into the hierarchy.
> >>
> >> I've been struggling to find a clean entry point as well.  It might be
> >> the case that it cannot be done.
> >>
> >>> Option vs. Argument.  It might be just me but in the command "ant -f
> >>> file" I've always regarded it as an option -f with an argument file,
> >>> whereas the current model would have an argument "-f file".  This has
> >>> caused me occasional confusion and it seems that it
> >>> would sit easier if Argument were able to deal purely with the "file"
> >>> section and not have to deal with the option's properties.  If the
> >>> Argument were able to drop the option properties then it might also  
> >>> be
> >>> possible to mix Arguments and Commands together.
> >>
> >> I've always treated it as '-f file', and never thought of it in any
> >> other manner
> >> as the value is so tightly coupled to the option.  Correct me if my
> >> understanding
> >> is off but is this was you are suggesting, '-f file' is represented by
> >> an Option
> >> that holds a reference to an Argument.
> >
> > Not sure if I'm helping to clear things up but here goes.  I would  
> > regard "-f" as an option, and therefore when faced with "-f file" I  
> > see an option "-f" with an argument "file".  Thinking more though,  
> > this seems like a bit of a bikeshed.  Having an Option that references  
> > an Argument is probably the closest to my description above but the  
> > proposal takes the opposite approach where the Argument wraps a  
> > (Parent)Option.  This means that the Argument object concerns itself  
> > with processing the "file" section but in effect could be considered  
> > the complete "-f file".
> >
> >>
> >>> AnonymousArgument and UnsupportedMethodException.  Again it might be  
> >>> a
> >>> personal thing but I've always thought of UME as being a bit of a  
> >>> code
> >>> smell - to me it says "the object isn't really a subtype of the
> >>> specifying class but we've put it here anyway, so there".  I think
> >>> this strengthens the case against Argument implementing Option.
> >>
> >> The AnonymousArgument feature has not been designed, it has been
> >> *fitted* to the
> >> current implementation.  I think there are places where UME's are
> >> appropriate
> >> (partial implementations of specifications for example), but I too
> >> dislike the
> >> UMEs in AnonymousArgument.  I suspect I was trying to limit the number
> >> of public
> >> types used to 2 (Option and Argument), which I think is obvious from
> >> the impl.
> >
> > Yeah - thats all fair enough.  The "code smell" talk was definitely  
> > the OO purest in me, in reality UME is a useful compromising tool.
> >
> >>
> >>> CommandLineParser knows an awful lot.  I've commented before that the
> >>> internal handling of -D and -- should be optional but the knowledge  
> >>> of
> >>> how all the other options behave seems to be encoded in this class
> >>> too.  There's nothing inherently wrong with that but
> >>> it left me thinking it odd that the Option implementations didn't
> >>> control the behaviour themselves.  It also struck me that the same
> >>> would be true of any HelpFormatter built for the current model.
> >>
> >> I was working on simplifying CommandLineParser last night and I was
> >> thinking
> >> about the validation step (now that it is a separate call) and it
> >> struck me
> >> that the validation and a HelpFormatter would follow the same path
> >> through
> >> the Options instance and that there should be a means to plug-in the
> >> functionality you require, rather than having a separate help() method
> >> being defined on the Option as well.
> >
> > So the "print the usage" and "validate the command line" methods  
> > should use the same code path?  Hmm, I'll have to ponder that.
> >
> >>
> >> I do think the parsing is slighty different, but I need to think about
> >> it in
> >> a bit more detail.  It is possible that with your new proposal, it
> >> works out
> >> fine.
> >>
> >>> Without boring you with the route my thoughts took, here's the model  
> >>> I
> >>> came to with a bit of explanation afterwards.
> >>>
> >>> Class Diagram (Inheritance):
> >>>
> >>> Option <-----------+-- Options <---------------+-- ExclusiveOptions
> >>>   getDescription() |     parse(...)            |
> >>>   isRequired()     |                           +-- InclusiveOptions
> >>>   appendUsage(...) |
> >>>   validate(...)    +-- ParentOption <----------+-- DefaultOption
> >>>   process(...)     |     processParent(...)    |
> >>>   canProcess(...)  |     processChildren(...)  +-- CommandOption
> >>>   getPrefixes()    |
> >>>                    +-- Argument
> >>>                    |
> >>>                    +-- PropertyOption
> >>>                    |     getInstance()
> >>>                    |
> >>>                    +-- IgnoreOption
> >>>                          getInstance()
> >>
> >> Can you explain how Options inherits from Option?  I don't understand
> >> that piece.
> >
> > The proposed Option is a slightly higher level concept than the  
> > current Option.   In the first version of my diagram it was  
> > "CommandLineElement" but this suggested that Options should be called  
> > "CommandLineElements" and the names of all the other classes just  
> > seemed uglier and uglier.  So in the proposal an Option is considered  
> > a generic term for anything that could appear in the command line  
> > structure.  The useful part is that, just like awt's  
> > Component/Container relationship, an Options instance can be treated  
> > just like any other Option but has the facility of holding other  
> > Option instances.
> >
> >>
> >>> Class Diagram (Composition):
> >>>
> >>> Argument --------1 ParentOption --------1 Options --------* Option
> >>
> >> Options == childOptions here?
> >
> > Yes.  An argument "-f file" delegates the processing of "-f" to a  
> > ParentOption.  A ParentOption delegates the processing of any child  
> > options to an Options instance. And the Options class delegates  
> > further processing to one of its Option instances.
> >
> >>
> >>> The first thing to note is that I've separated out the Option
> >>> interface from the DefaultOption class.  The Option interface has  
> >>> lost
> >>> most of its structure enforcing role and gained behaviour specifying
> >>> instead.  Some new OptionBuilder would build DefaultOption instances
> >>> with all the longName / shortName and other properties of the current
> >>> OptionImpl class.  Similarly a CommandBuilder would allow
> >>> CommandOption instances to be built up with preferredName / aliases
> >>> properties.
> >>>
> >>> Another important point is that Argument is no longer directly  
> >>> related
> >>> to the DefaultOption.  Instead it is composed of either a
> >>> DefaultOption or CommandOption and concentrates purely on the details
> >>> of the argument.
> >>>
> >>> Options just becomes a generic object for storing a set of options,
> >>> the Exclusive / Inclusive just specify more restrictive behaviour as
> >>> they do presently.
> >>>
> >>> The idea of PropertyOption (-D) and IgnoreOption (--) just dropped  
> >>> out
> >>> of the structure and means that this standard behaviour can be  
> >>> treated
> >>> as any other option and if people have their own plan for a -D option
> >>> then they simply don't put a PropertyOption
> >>> instance in their Options.
> >>
> >> That makes sense.  I would rename IgnoreOption to ConsumeOption to
> >> signify that
> >> it actually does do something rather than simply ignores the values on
> >> the
> >> command line.
> >
> > +1  I'm not in the running for any class naming awards.
> >
> >>
> >>> After a little experimentation the sensible methods for Option to
> >>> specify seem to be the following:
> >>> getDescription() - used to allow a HelpFormatter to describe any  
> >>> given
> >>> Option.
> >>> appendUsage(...) - allow the option itself to append a usage string  
> >>> to
> >>> a StringBuffer
> >>
> >> I don't fully understand the reason for appendUsage, why would there
> >> not simply
> >> be a getUsage?
> >
> > Thats just my personal habit - I tend to have some sort of  
> > append(StringBuffer) method and then have toString() make use of it,  
> > getUsage() would probably be better than the toString() though.  The  
> > important point is that the Option instance itself becomes responsible  
> > for producing the usage text.
> >
> >>
> >>> validate(...) - validates a CommandLine's use of this Option
> >>> isRequired() - presumably used by validate() and appendUsage()
> >>> process(...) - takes a ListIterator of arguments and deals with
> >>> some/all of them.
> >>> canProcess(...) - checks that a call to process(...) will succeed.
> >>
> >> Is this necessary?  The current impl has two phases, one is to build  
> >> the
> >> CommandLine and the other is to validate the CommandLine against the
> >> Options.
> >
> > Currently the parser has a loop with an if statement:
> > for each argument
> >     if argument=="--" process --
> >     if argumetn "-D" processProperty
> >     if argument begins "-" processOption
> >
> >
> > But because all options become the same, the equivelent section (now  
> > within Options) becomes:
> >
> > for each argument
> >     for each option
> >         if option canProcess argument
> >             option.process
> >
> >>
> >>> getPrefixes() - returns the argument prefixes that could indicate  
> >>> this
> >>> Option can process a given argument.
> >>
> >> Can you explain this in more detail?
> >
> > After several attempts to start I'm tempted to say no!
> >
> > Right. Firstly, it may well be unimportant for now as it is really an  
> > implementation detail of my experimental code - there may be other  
> > stratergies for processing.
> >
> > The idea is that each option will return the set of string prefixes  
> > that this option can handle.  This unifies long and short option names  
> > {-?, -h, --help} along with command names and aliases {update, upd,  
> > up} into a common structure that should make lookups easier.  In the  
> > case of Opions, the set of prefixes is the union of the child options'  
> > prefixes.
> >
> > The canProcess method becomes a trivial case of "return  
> > getPrefixes().contains(arg);" and the Options implementation can use a  
> > prefix->option map to lookup the option to hand off processing to.  Of  
> > course both of these become more complicated as allowances are made  
> > for option bursting and arguments of the style "--arg=val1,val2".
> >
> > I've attached my experimental code in the hope that it'll help you  
> > understand what I mean.  I have options, commands, bursting, option  
> > groups and arguments parsing in isolation but haven't had the chance  
> > to check that combinations work.
> >
> >>
> >>> One of the nice things about this structure is that when somebody
> >>> wants to extend the system to cope with windows style "/?" options,  
> >>> or
> >>> case insensitive commands, they should only need to add a single
> >>> Option implementation and any Parser and Formatter will automatically
> >>> cope.
> >>
> >> Weird!  I had just began looking into this last night.  I removed the
> >> references
> >> to "-" and replaced it with a reference to a static (PREFIX).
> >
> > Yeah that'd work too!
> >>
> >>> I've not yet figured out whether a separate AnonymousArgument is
> >>> needed or if an Argument could exist without a ParentOption but I'm
> >>> sure that the UnsupportedMethodException methods would be gone
> >>> completely whichever route was taken.
> >>
> >> Based on the approach that Option no longer enforces the structure, it
> >> will
> >> follow that there will be no NMEs (depending on what getPrefixes  
> >> does).
> >
> > I'd suggest Collections.EMPTY_SET if getPrefixes() doesn't apply.
> >
> >>
> >>> So, thoughts? I'm happy to answer questions and help with
> >>> implementation as time permits but I'll be on holiday from Friday for
> >>> 10 days so will be offline for a while.
> >>
> >> Well I think I've enough thoughts in there for you ;)
> >
> > Hope all that helps,
> >
> > Rob
> >
> >>
> >> Cheers for the great input,
> >> -John K
> >>
> >>>
> >>> Rob
> >>>
> >>>
> >>> ----- Original Message -----
> >>> From: "John Keyes" <jb...@mac.com>
> >>> To: "Jakarta Commons Developers List"  
> >>> <co...@jakarta.apache.org>
> >>> Sent: Thursday, June 12, 2003 10:18 AM
> >>> Subject: Re: [CLI] Support for CVS style command line
> >>>
> >>>
> >>>>> The "setDisplayCommandAlias(boolean)" is purely hypothetical at the
> >>>>> moment, it illustrates
> >>>>> the level of control I was planning on offering but is beyond the
> >>>>> implementation so far.
> >>>>> I haven't tackled Commands and aliases at all but I guess should  
> >>>>> put
> >>>>> my code
> >>>>> where my mouth is.  I'll keep you posted on progress.
> >>>> Keep bouncing the ideas around anyway.  If you don't get around to
> >>>> implementing it
> >>>> at least the knowledge will be archived.
> >>>>
> >>>> Thanks,
> >>>> -John K
> >>>>
> >>>>
> >>>> -------------------------------------------------------------------- 
> >>>> -
> >>>> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> >>>> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> >>> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >>>
> >>>
> >> - - - - - - - - - - - - - - - - - - - - - - -
> >> Jakarta Commons CLI
> >> http://jakarta.apache.org/commons/cli
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> >> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >>
> >>
> >>
> > <clirob.zip>----------------------------------------------------------- 
> > ----------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> - - - - - - - - - - - - - - - - - - - - - - -
> Jakarta Commons CLI
> http://jakarta.apache.org/commons/cli
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [CLI] Do we have the correct model? (was Re: [CLI] Support for CVS style command line)

Posted by Rob Oxspring <ro...@imapmail.org>.
John,

I see there is a CLI_ROB branch taken from the trunk, presumably this will be the sandbox for the propsal?  Do you want me to post
updates and patches or do you want to get someone to grant commons commit privs to roxspring? - I have basic impls for
OptionBuilder, ArgumentBuilder and CommandLineParser and updated Argument at the moment with more to follow as time allows.  I've
also got thoughts about how to handle switches too but I'll mail about that separately.

Rob

----- Original Message ----- 
From: "Rob Oxspring" <ro...@imapmail.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Tuesday, July 01, 2003 1:46 PM
Subject: Re: [CLI] Do we have the correct model? (was Re: [CLI] Support for CVS style command line)


> Sounds like a good plan to me.
>
> Rob
>
> ----- Original Message ----- 
> From: "John Keyes" <jb...@mac.com>
> To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
> Sent: Sunday, June 29, 2003 11:10 PM
> Subject: Re: [CLI] Do we have the correct model? (was Re: [CLI] Support for CVS style command line)
>
>
> > Rob,
> >
> > I've been looking at your code and I like the structure.  I'm willing
> > to add
> > this to a new branch (so we can synchronize changes) and we can work on
> > it
> > for the next couple of weeks and see how we think things are
> > progressing.
> >
> > I think the first thing we should do is add the tests from the cli_1_x.
> > This will allow us to get the API in place.  By this I mean adding the
> > XXXBuilder classes and the CommandLineParser class.
> >
> > Let me know what you think and I'll get the ball rolling,
> > -John K
> >


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org