RE: [cli] commons cli version 2.0?
Thanks for that, I've added a new test (based on yours) and fixed existing ones. It turns out that GroupImpl was only validating options that are present and skipping those that were missing. I've fixed this in cvs but no binary is available yet. ok thanks, I've updated my local checkout now and picked it up. I've being playing with it some more and have some more minor points.. 1) On the Builder classes the reset() method has a void return type This means that you can't reuse the same builder within one large expression for multiple options (eg because the PreferredName is set to the first value used)? eg. Code like this is currently blocked DefaultOptionBuilder dob = ... Group wizardArgs = gBuilder .withOption( oBuilder .reset() .withLongName(opt1) .withLongName(altopt1) .create() ).withOption( oBuilder .reset() .withLongName(opt1) .withLongName(altopt1) .create() ).create(); 2) Some error messages could be more specific eg in DefaultOption.validate === RCS file: /home/cvspublic/jakarta-commons/cli/src/java/org/apache/commons/cli2/opt ion/DefaultOption.java,v retrieving revision 1.3 diff -r1.3 DefaultOption.java 187c187 throw new OptionException(this); --- throw new OptionException(this, cli.error.missing.required, preferredName); 3) (As noted before) in the svn/cvs-style usage there is no easy way to determine which command has been invoked - a (hacky?) workaround is to do something like String command = null; for(Iterator i = line.getOptions().iterator(); i.hasNext(); ) { Option o = (Option) i.next(); if(!o.getPreferredName().startsWith(-)) { if(command!=null) { throw new RuntimeException(You can only specify one command); // this is never thrown as the top-level Group has a maximum of 1 } else { command = o.getPreferredName(); } } } I'm not sure what a nice API for this would be though - maybe something to look at only the top level options passed (and not their children) CommandLine line = ... ... line.getTopLevelOptions(); ?? 4) (As noted before) For non-group option implementations nesting exceptions might be a way of allowing detailed information about where the parse error occurred eg in the validate method in Command you could have public void validate(WriteableCommandLine commandLine) throws OptionException { if (isRequired() !commandLine.hasOption(this)) { throw new OptionException(this); } try { super.validate(commandLine); } catch(OptionException oe) { OptionException mine = new OptionException(this); // or maybe the message should be altered to Command +preferredName+ +oe.getMessage()); mine.initCause(oe); throw mine; } } which would mean the HelpFormatter would need to iterate to the end of the chain of exceptions to find the true message (or as in the comment above parent options could prefix additional information about what is going on). Its probably better to have the HelpFormatter construct this detailed message as an option if this idea has any milage in it Also, if you do need/want some extra coding/docs time then I might be able to get permission to allocate some time to lending a hand? thanks, Andrew - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: [cli] commons cli version 2.0?
hi, thanks very much for the information :) I've downloaded the sources and have been playing with the CLI2 api - specifically the commands section, and have some (possibly confused) feedback.. I'm interested in developing a tool which has a command line like tool tool options command command options and which would have use cases like 1 tool Type 'tool help' for usage 2 tool help usage: tool tool options subcommand command is one of a descr-a b descr-b c descr-c d descr-d 3 tool a usage: tool tool options a a options a options -f, --foo -b, --bar and so on (if you have used subversion then pretty much identical to that). The model I've tried to use for this is: Group (commands) (Minimum=Maximum=1) | |__ Command (command1) | | | |__ Group | | | |__ Option (f, foo) | | | |__ Option (b, bar) | | | |__ Option (h, help)-- command help | |__ Command (command2) | |__ Command (command3) | |__ Command (help) -- overall help but have found the following questions/potential issues 1) There is only one OptionException to cover all problems - is the idea to use the Option available to infer any additional detail you need? This seems strange compared to CLI1.0 where there were specific exception subclasses? 2) When giving a Command a list of Options required parameter is not respected? For example - above it seems to make no difference if foo or bar are required or not? You can use the Group's setMinimum, setMaximum methods but this can't mimic the behaviour needed for the majority of cases 3) The default behaviour when displaying the usage of the whole command line lists the commands one by one eg Usage: command1 -f|-b|-h command2 command3 help which is correct but possibly something people writing tools of this form will all need to change. Anyhow, the overall framework looks great although I've not yet understood a number of things I think. thanks, Andrew -Original Message- From: Rob Oxspring [mailto:[EMAIL PROTECTED] Sent: 24 September 2004 12:15 To: Andrew Ferguson; Jakarta Commons Users List Subject: Re: [cli] commons cli version 2.0? Hi, (cc to commons-user since this may be useful to others) CLI2 is about ready, just waiting for one last bugfix (ready to commit) and a little documentation. Unfortunately I'm snowed under with the day job at the moment so am not sure when I'll get it finshed. I guess the new feature list goes something like: * switches (+d|-d) * commands (a la cvs update) * options without short forms * multiple aliases per option * optional -D processing (java properties) * optional -- processing (consume remaining arguments) * fine grained control over what's displayed * accepts defaults from Properties * accepts defaults from Preferences * flexible api Hiding options from the help formatted isn't supported out of the box but the api should allow you to acheive that result by wrapping either the hidden options themselves or the top level Group; the important thing is to filter the results of helpLines() to exclude the hidden options. I'll concentrate on the latter approach and assume all other methods are delegated directly to the wrapped group: (untested code, expect typos) HiddenOptionsGroup implements Group { private Set hiddenOptions = new HashSet(); public void hideOption(Option hidden){ hiddenOptions.add(hidden); } public List helpLines(){ List lines = wrapped.helpLines(); for(Iterator i=lines.iterator();i.hasNext();){ HelpLine line = (HelpLine)i.next(); if(hiddenOptions.contains(line.getOption())){ i.remove(); } } return lines; } // delegate remaining methods } // then use it as follows Option secret = ... Group options = ... HiddenOptionsGroup hog = new HiddenOptionsGroup(options); hog.hideOption(secret) HelpFormatter help = new HelpFormatter(); help.setOptions(hog); help.printHelp(); Built in support for hidden options may appear in later versions if there is demand for it. Hope that helps, Rob Andrew Ferguson wrote: hi, i was just wondering if you have any details about when CLI2.0 might be available? (and what new features would be available) I'm currently using CLI1.0 but am under pressure from other team members because it doesn't support options like 1) hidden options that aren't displayed by the help formatter 2
RE: [cli] commons cli version 2.0?
hi, My early versions of the CLI2 model included several exceptions covering the various situations but we merged them all into one feeling that people were unlikely to be interested in the differences. I assume you want to know, for a given exception, whether to give tool level help or command level help? yes I'm not sure how best to achieve this off hand and am not even sure that more specific exception classes would help. ok, I'll try to think about this more - my initial thought was something like a MissingCommandException would allow me to catch this and help solve my particular issue, but in general you might want to know where in the command-line tree the command was (as its not necessarily at the top level?) and that might be over-doing things? When you say make no difference do you mean in the displayed help or in the processing? I'm pretty sure it should validate as you expect: first validating each of the options and then validating the number of them against the minimum/maximum. I'll try and have a look over the weekend but if you could send me an example (test case would be ideal) that demonstrates the problem the it'll be easier to resolve. oops, sorry - what I meant was that I can have a Group containing two options, one of which is required and one of which isn't. When it comes to processing that Group the only constraints that seem to be honoured are the setMinimum and setMaximum. So for example if you had a Group with required options r1,r2,r3 and not required options n1,n2,n3 then you can't use the number of present options alone as the validation predicate as eg. requiring a minimum of three options would allow n1,n2,n3 I've attached a test-case RequiredWithinGroupTest.java that hopefully demonstrates this (it works on my machine:) but if your answer is that this is the intended behaviour then I guess its not an error - but is there an alternate way to achieve the following? umbrella-tool --umbrella-tool-option1 command --required1 --required2 --required3 --nonrequired1 --nonrequired3 --nonrequired3 I'm not really sure what to do about this, I think its safe to say that the defaults can never suit every use. I assume you've discovered and played with DisplaySettings to customise fullUsageSettings in HelpFormatter? I did wonder about automatically switching options to shorter forms until they all fit on a single line, which might result closer to what you're after. That would have to wait for a later release though, I think. ok, I had been thinking that if the Command class was primarily intended for cvs/svn style applications then the default behaviour should maybe be skewed towards this by specially recognizing a top-level group of Commands? but the current HelpFormatter is more than adequate for achieving the same thing in the client code also, as you point out svn does not do this (and having just checked cvs* doesn't either..) thanks, Andrew * it just has a --help-commands option to display the command list - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: [cli] commons cli version 2.0? (attachment inlined)
sorry the attachment seems to have failed - here is the plain text: package org.apache.commons.cli2.application; import java.io.*; import javax.swing.*; import junit.framework.TestCase; import org.apache.commons.cli2.*; import org.apache.commons.cli2.Group; import org.apache.commons.cli2.builder.ArgumentBuilder; import org.apache.commons.cli2.builder.CommandBuilder; import org.apache.commons.cli2.builder.DefaultOptionBuilder; import org.apache.commons.cli2.builder.GroupBuilder; import org.apache.commons.cli2.commandline.*; import org.apache.commons.cli2.option.*; import org.apache.commons.cli2.option.ArgumentTest; import org.apache.commons.cli2.util.*; public class RequiredWithinGroupTest extends TestCase { public void testRequiredIsHonoured() { Group commands = buildCLI(); Parser parser = new Parser(); parser.setGroup(commands); CommandLine line = null; String [] arg = {command1}; /* * We expect command1 to say that the --foo option is required * */ try { line = parser.parse(arg); fail(/required/ Option within Group was allowed to be absent); } catch (OptionException oe) { /* Expected failure */ } } static Group buildCLI() { GroupBuilder gBuilder = new GroupBuilder(); CommandBuilder cBuilder = new CommandBuilder(); DefaultOptionBuilder oBuilder = new DefaultOptionBuilder(); /* This is the top level of commands */ Group commands = gBuilder .withMinimum(1) .withMaximum(1) .withName(command name) .withOption(createCommand1()) .withOption( cBuilder .withName(command2) .withName(c2) .withDescription(command2 does ...) .create() ) .withOption( cBuilder .withName(help) .withDescription(Display the list of commands) .create() ) .withOption( cBuilder .withName(command3) .withName(c3) .withDescription(command3 does ...) .create() ).create(); return commands; } /* * Options common to a particular subset of commands */ static GroupBuilder createCommonGroupBuilder() { GroupBuilder gBuilder = new GroupBuilder(); DefaultOptionBuilder oBuilder = new DefaultOptionBuilder(); ArgumentBuilder aBuilder = new ArgumentBuilder(); Option product = oBuilder .withShortName(f) .withLongName(fuu) .withRequired(true) .withDescription(fuu is the option that does ...) .create(); Option variant = oBuilder .withShortName(b) .withLongName(bah) .withRequired(false) .withDescription(bah is the option that does ...) .create(); return gBuilder .withOption(product) .withOption(variant); } static Command createCommand1() { CommandBuilder cBuilder = new CommandBuilder(); DefaultOptionBuilder oBuilder = new DefaultOptionBuilder(); GroupBuilder gBuilder = createCommonGroupBuilder(); Group c1Args = gBuilder .withOption( oBuilder .withLongName(non-recursive) .withRequired(false) .withDescription(turn off recursion) .create() ).withOption(
RE: C# implementation of Jakarta-Commons
this is also my plan - am hoping that ikvm and the ClassPath project mature enough to let me run my current java application on the .NET CLR without changes. I also like quite a lot of the changes they made from java for C# - it seems they have made a few more concessions to C++ programmers, and made a larger language as a result. I think delegates are meant to cover the functionality you'd normally need inner classes for, and inner classes seem to be one of the parts of java that have some very unpleasant corners so am interested in this, also the absense of checked exceptions seems like a change that could have a big impact (not sure which way..) If the .NET CLR takes off in a big, and multi-platform, way (which afaik it hasn't yet) then I guess porting existing java applications might make sense. For projects like Nunit where there is an assumption that the CLR is your main interest then a reimp seems appropriate. My programs at the moment are on the other side - assuming that the JVM is of main interest - but if ikvm and classpath allow them to run direct on .NET then this is great news :) (distributing a JVM is a real pain) my initial impressions suggest that the Java class libraries are both more extensive, and better designed and organised than those in C# I'm only vaguely aware of whats in the BCL, but this is still a surprising statement.. a lot of the changes in C# seem to be motived from experience of using Java and looking at what could be done better. The j2se library has a fair number of deprecated methods, and other time-earned scars that I'd assumed the BCL would have been able to avoid these while retaining the uptodate (and adding some new) functionality? the only thing that's really pleased me in the BCL is that you have methods for copying and manipulating files directly - contract jave where you have to either fiddle with streams, or use the slightly bizarrely named transferTo on a nio Channel. anyway, interesting times, interesting times.. :) -Original Message- From: Bart Read [mailto:[EMAIL PROTECTED] Sent: 04 August 2004 09:45 To: Jakarta Commons Users List Subject: RE: C# implementation of Jakarta-Commons Thanks, that's useful to know. I must admit that I'm sitting on the fence a bit regarding the merits of using cross-compilers. The approach taken by NUnit (= JUnit for .NET) was firstly a pretty much direct transliteration from Java to C#, however they have now re-implemented from scratch with C#. I think C# has enough different language features (properties, delegates, doesn't seem to support inner classes... let alone anonymous etc) to justify doing this. Incidentally, just to clarify, just because C# has these features doesn't necessarily mean I'm a big fan of all of them: I happen to like the simplicity of Java syntax. Also, my initial impressions suggest that the Java class libraries are both more extensive, and better designed and organised than those in C#. Regardless, I'll certainly take a look at ikvmc... certainly if it allows quick access to some of the collections functionality lacking in .NET then I'll be very happy. Many thanks, Bart - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: C# implementation of Jakarta-Commons
ikvm might be able to compile the jar directly for .NET? http://weblog.ikvm.net/ -Original Message- From: Bart Read [mailto:[EMAIL PROTECTED] Sent: 03 August 2004 11:22 To: [EMAIL PROTECTED] Subject: C# implementation of Jakarta-Commons Dear All, I've been a user of the Commons libraries for some time now on Java projects that I've been involved with. However, I've recently started working for a Microsoft shop who use C#, and have found that to begin with the .NET collections libraries are fairly woeful compared with those provided as standard with Java (e.g. where is Set or a comparable interface?). So I wondered if anybody was aware of a project to implement a C# version of the Commons, or something similar? A quick search of the web hasn't revealed anything so far. Many thanks, Bart Read - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: C# implementation of Jakarta-Commons
forgot to mention that ikvmc /can/ compile the commons-cli library, and some limited testing shows the generated .dll assembly runs directly on the CLR ! as ikvm/classpath projects mature this will probably be better than porting at the source level, since things will remain in synch presumably, any pure java jar which doesn't use too recent API (ie the Classpath open-source project supports all the used API) will compile ? -Original Message- From: Andrew Ferguson [mailto:[EMAIL PROTECTED] Sent: 03 August 2004 13:41 To: Jakarta Commons Users List Subject: RE: C# implementation of Jakarta-Commons ikvm might be able to compile the jar directly for .NET? http://weblog.ikvm.net/ -Original Message- From: Bart Read [mailto:[EMAIL PROTECTED] Sent: 03 August 2004 11:22 To: [EMAIL PROTECTED] Subject: C# implementation of Jakarta-Commons Dear All, I've been a user of the Commons libraries for some time now on Java projects that I've been involved with. However, I've recently started working for a Microsoft shop who use C#, and have found that to begin with the .NET collections libraries are fairly woeful compared with those provided as standard with Java (e.g. where is Set or a comparable interface?). So I wondered if anybody was aware of a project to implement a C# version of the Commons, or something similar? A quick search of the web hasn't revealed anything so far. Many thanks, Bart Read - 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]
RE: commons-cli processing options incorrectly?
this also seems to happen with the current cvs image - I'm not sure what the CLI 2.0 classes are though - is anyone still working on the pre-2.0 classes? -Original Message- From: Andrew Ferguson [mailto:[EMAIL PROTECTED] Sent: 15 July 2004 18:40 To: Jakarta Commons Users List Subject: commons-cli processing options incorrectly? hi, this could be me misunderstanding the posix standard but this link http://java.sun.com/docs/books/tutorial/essential/attributes/_posix.html says Options that do not require arguments can be grouped after a hyphen, so, for example, -lst is equivalent to -t -l -s. but the following code: import org.apache.commons.cli.*; import java.util.*; public class CLITest { public static void main(String[]arg) throws Exception { CommandLineParser parser = new PosixParser(); Options options = new Options(); Option p = new Option(p, pets, true, takes a list of up to 4 animals); p.setArgs(4); p.setRequired(true); Option v = new Option(v, vet, true, the name of a vet); v.setArgs(100); v.setRequired(true); options.addOption(p).addOption(v); CommandLine line = parser.parse(options, arg); System.out.println(p ? +line.hasOption(p)+ +Arrays.asList(line.getOptionValues(p))); System.out.println(v ? +line.hasOption(v)+ +Arrays.asList(line.getOptionValues(v))); } } produces these results y:\java\miscjava CLITest -p 1 2 3 -v 4 5 6 p ? true [1, 2, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 2 v 3 -v 4 5 6 p ? true [1, 2] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 v 2 3 -v 4 5 6 p ? true [1] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 V 2 3 -v 4 5 6 p ? true [1, V, 2, 3] v ? true [4, 5, 6] when I was expecting: (* marks different from above) y:\java\miscjava CLITest -p 1 2 3 -v 4 5 6 p ? true [1, 2, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 2 v 3 -v 4 5 6 * p ? true [1, 2, v, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 v 2 3 -v 4 5 6 * p ? true [1, v, 2, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 V 2 3 -v 4 5 6 p ? true [1, V, 2, 3] v ? true [4, 5, 6] I'm constantly misunderstanding how command lines are meant to be interpreted, but this seems wrong?? thanks, Andrew - 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]
commons-cli processing options incorrectly?
hi, this could be me misunderstanding the posix standard but this link http://java.sun.com/docs/books/tutorial/essential/attributes/_posix.html says Options that do not require arguments can be grouped after a hyphen, so, for example, -lst is equivalent to -t -l -s. but the following code: import org.apache.commons.cli.*; import java.util.*; public class CLITest { public static void main(String[]arg) throws Exception { CommandLineParser parser = new PosixParser(); Options options = new Options(); Option p = new Option(p, pets, true, takes a list of up to 4 animals); p.setArgs(4); p.setRequired(true); Option v = new Option(v, vet, true, the name of a vet); v.setArgs(100); v.setRequired(true); options.addOption(p).addOption(v); CommandLine line = parser.parse(options, arg); System.out.println(p ? +line.hasOption(p)+ +Arrays.asList(line.getOptionValues(p))); System.out.println(v ? +line.hasOption(v)+ +Arrays.asList(line.getOptionValues(v))); } } produces these results y:\java\miscjava CLITest -p 1 2 3 -v 4 5 6 p ? true [1, 2, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 2 v 3 -v 4 5 6 p ? true [1, 2] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 v 2 3 -v 4 5 6 p ? true [1] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 V 2 3 -v 4 5 6 p ? true [1, V, 2, 3] v ? true [4, 5, 6] when I was expecting: (* marks different from above) y:\java\miscjava CLITest -p 1 2 3 -v 4 5 6 p ? true [1, 2, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 2 v 3 -v 4 5 6 * p ? true [1, 2, v, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 v 2 3 -v 4 5 6 * p ? true [1, v, 2, 3] v ? true [4, 5, 6] y:\java\miscjava CLITest -p 1 V 2 3 -v 4 5 6 p ? true [1, V, 2, 3] v ? true [4, 5, 6] I'm constantly misunderstanding how command lines are meant to be interpreted, but this seems wrong?? thanks, Andrew - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]