rvesse / airline

Java annotation-based framework for parsing Git like command line structures with deep extensibility
https://rvesse.github.io/airline/
Apache License 2.0
128 stars 20 forks source link

@Version usage on top-level Cli? #57

Closed stephenh closed 6 years ago

stephenh commented 7 years ago

Hi,

I'd like to use the @Version annotation, but it seems to assume it's on a command object?

E.g. I have a Cli setup like:

@Cli(
  name = "mirror",
  description = "two-way, real-time sync of files across machines",
  commands = { MirrorClientCommand.class, MirrorServerCommand.class },
  defaultCommand = Help.class)
@Version(sources = { "/META-INF/MANIFEST.MF" }, suppressOnError = false)
public class Mirror {

  public static void main(String[] args) throws Exception {
    com.github.rvesse.airline.Cli<Runnable> cli = new com.github.rvesse.airline.Cli<>(Mirror.class);
    cli.parse(args).run();
  }

I am admittedly source a MF sources (see my other ticket), but I was expecting this to blow up, and then I'd poke around at gradle to make a properties file instead.

But instead it looks like the @Version annotation here isn't getting found at all.

I was thinking maybe I should make a subclass of the airline Help.class, and add my @Version there? ...well, no, that didn't work.

Basically what I'd like is for when users run:

That they see the version information.

Right now the output is just:

usage: mirror <command> [ <args> ]

Commands are:
    client   two-way real-time sync
    server   starts a server for the remote client to connect to

See 'mirror help <command>' for more information on a specific command.

Is what I'm looking for already doable? Or something that's easy to support?

rvesse commented 7 years ago

What you are trying to do won't just work at the moment though it is definitely something I would like to do in the future. Annotations like @Version currently only work when applied directly to @Command classes though they may be applied to any class in the inheritance hierarchy.

Ideally we should also allow them on @Cli annotated classes with any instances in the @Command hierarchy able to override these.

All @Version does currently is add an extra section into the command specific help hence why you don't see any difference in output even when you extend Help and add the annotation. The behaviour of the Help command when the user does not specify command is to give the CLI help which does not include any extra annotation driven sections like @Version provides.

The best way to do this currently would be to create a Version command in a similar vein to Help which could then inspect the @Version annotation and generate appropriate output. As for a -v option you would need to add that as an option yourself. You could choose to do something similar to HelpOption for this.

I will probably aim to have something built in in the future but I can't give you a time frame on that.

stephenh commented 7 years ago

Hi Rob,

Thanks for the response. That makes sense...

HelpOption looks interesting, although I think it has the same wrinkle like @Version, where it'd have to be on each command.

I think a VersionCommand is probably what I'll go with, and maybe even have the command name be "-v", and have it hidden, so that mirror -v works, but then it doesn't show up in the list of regular commands. Or maybe I'll just call it version, to be more consistent with the other commands.

Having these on the top-level @Cli in the long run makes sense...it does seem kind of tricky, in that invocations like mirror -v and mirror -h would be kind of one-off/top-level commands that are parsed/handled separately/short-circuit the regular mirror command <args> approach.

rvesse commented 7 years ago

Agreed, this probably also relates to #53 which covers special handling for options like -h which currently require users to jump through some extra hoops

rvesse commented 7 years ago

HelpOption looks interesting, although I think it has the same wrinkle like @Version, where it'd have to be on each command.

Yes although any and all option definitions within a class hierarchy will be discovered. So personally I usually define a abstract class with all my common options and there have all my other commands extend from that.

rvesse commented 6 years ago

Using help section annotations on @Cli classes are now supported in the latest SNAPSHOT builds (2.5.1-SNAPSHOT)

Still need to incorporate use of help sections in CLI help

rvesse commented 6 years ago

Help sections added at the @Cli level are now incorporated in the global help output in the latest snapshots

rvesse commented 6 years ago

Here's example output with latest SNAPSHOT:

usage: test <command> [ <args> ]

Commands are:
    Args1   args1 description

See 'test help <command>' for more information on a specific command.

VERSION
            Component: Airline Test
            Version: 1.2.3
            Build: 12345abcde