jcommander icon indicating copy to clipboard operation
jcommander copied to clipboard

Using commands feels a bit awkward at the moment

Open huxi opened this issue 14 years ago • 6 comments

Using commands isn't as easy as the rest of JCommander.

I have code that looks like this:

    CommandLineArgs cl=new CommandLineArgs();
    JCommander commander = new JCommander(cl);
    Cat cat = new Cat();
    commander.addCommand(Cat.NAME, cat);
    Tail tail = new Tail();
    commander.addCommand(Tail.NAME, tail);
    Index index = new Index();
    commander.addCommand(Index.NAME, index);

The thing that's bugging me is that I had to define a public static final NAME field in each of my command instead of annotating the class, simply calling

    addCommand(command)

The same is the case for using the command:

    String command = commander.getParsedCommand();
    if(Tail.NAME.equals(command)) {
        [...]
    }

So there are two places where I still need to juggle with plain strings. Instead, I'd like to have something like

    Object commandObject = commander.getParsedCommandObject();

This would be really useful if all registered command objects would implement the same interface, e.g. Runnable. In that case, I could simply cast the returned commandObject and call run() (after checking against null, obviously).

This functionality could even be wrapped into the getParsedCommandObject() method like this:

    Runnable commandObject = commander.getParsedCommandObject<Runnable.class>();

huxi avatar Jan 21 '11 14:01 huxi

I agree that commands are kinda uneasy to use. I do like the commandName and commandAliases in @Parameters annotation.

I was also trying to get commands to work with enums. Here's some (maybe weird) code: Commands@aeea04. It'd be nice if I could set @Parameters (and not just @Parameter) to each enum element, so I could specify the command description.

The above as it is, results to this:

$ java -jar dist/test.jar --help
Usage: app.Fic [options] [command] [command options]
  Options:
    -d, --debug    display debug messages
                   Default: false
  [...]
  Commands:
    compress     compress and decompress commands
    decompress   compress and decompress commands

$ java -jar dist/test.jar --help compress
compress and decompress commands
Usage: compress [options]
  Options:
  * -i, --input    the input file
    -o, --output   the output file

c00kiemon5ter avatar Jun 25 '11 02:06 c00kiemon5ter

I think using enums for commands is a brilliant idea. Adding annotations to enums does not seem very clean though, but I think it should be easy to extend addCommand(String, Object) interface to support addCommand(Enum<?>, Object) and then have a Enum<?> getParsedCommandEnum().

You have inspired my for another good idea: How about a addCommand(Object) method, that would automatically create command name from the class name. So for example:

class Commit{
  //parameter definitions here
}

//... main ...
// work out command name from class name => "commit"
jc.addCommand(new Commit());

if("commit".equals(jc.getParsedCommand()){
  //go
}

or even

if(Commit.class == jc.getParsedCommandClass()){
  //go
}

When using the later, you can avoid declaring extra enums or string constants, and at the same time keep your code refactoring-proof.

rodionmoiseev avatar Jun 26 '11 07:06 rodionmoiseev

@cbeust an old one but some nice thoughts about Commands in it.

What do you say?

jeremysolarz avatar Jan 31 '17 12:01 jeremysolarz

Yes, I agree, lot of good ideas here. I'll go over it and think about how to improve the design of commands, let's keep this open.

cbeust avatar Jan 31 '17 17:01 cbeust

In the last project I used JCommander in (not very recently), I used Enums to wrap all my command classes. Each Enum had two fields: a String to hold the command name and a Class<?> to hold the corresponding class type of the command. This approach helped me work around the problem @huxi described with an utility like getEnum from Apache Commons.

acostalima avatar Feb 22 '17 19:02 acostalima

As @cbeust thinks we had good ideas here, wouldn't it be cool if someone of us would open a PR? 8-)

mkarg avatar Jul 03 '19 05:07 mkarg