Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What to do for multiple commands #518

Closed
NagendraHegde opened this issue Oct 15, 2018 · 12 comments
Closed

What to do for multiple commands #518

NagendraHegde opened this issue Oct 15, 2018 · 12 comments

Comments

@NagendraHegde
Copy link

Hi Team,

Below is the situation I am facing:

I want to build a cli tool with picocli. I want to bundle it in a fat jar and give it to the users so that they can use it as a cli tool.

The tool is going to have multiple commands. Below is the format:

java commandone -a somevalue

java commandtwo -b someothervalue

For these, i can write classes for each individual commands with the help of @command annotation.
e.g:
@command(name="commandcone")
public class CommandOne implements Runnable { ... }

But the problem is, all the example given in the wiki demand to have public static void main() in the class and manually call CommandLine.run( ... ) in order to get the commands executed.

In the case of a tool having multiple commands (not subcommands), what do I do? I can not write main method to each class that i create for a command, right?

Do i manually write the routing for different commands? or is there a mechanism available already in picocli and I am unable to find it properly?

Please help. (btw other features are cool and you guys rock :) )

@remkop
Copy link
Owner

remkop commented Oct 15, 2018

Hi @NagendraHegde , please take a look at this example:
https://github.com/remkop/picocli/blob/master/picocli-examples/src/main/java/picocli/examples/subcommands/ParentCommandDemo.java

It demonstrates how to code a top-level command with a single subcommand.
You can add more subcommands by adding them in the @Command(subcommands = {Aaa.class, Bbb.class, Ccc.class, ...}) list.

It is a good idea to make all your commands implement Runnable or Callable (either one is fine), then in your main method you can simply say:

CommandLine.run(new RunnableTopCommand(), args);

// or, if the top-level command implements Callable:
// CommandLine.call(new CallableTopCommand(), args);

Picocli will execute the most specific subcommand that the user specified. So, for example, if you have a command hierarchy like this:

top
  |
  +- sub
  |    |
  |    +- subsub
  |    
  +- sub2 
       |
       +- sub2sub

Then, when the user invokes top --option sub subsub --otheroption,
picocli will call run (or call) on the subsub subcommand (the most specific subcommand that the user specified.)

@remkop
Copy link
Owner

remkop commented Oct 16, 2018

@NagendraHegde Did this answer your question?

@remkop
Copy link
Owner

remkop commented Oct 22, 2018

@NagendraHegde Were you able to make progress or do you have follow-up questions?

@remkop
Copy link
Owner

remkop commented Nov 1, 2018

@NagendraHegde Can this ticket be closed?

@remkop
Copy link
Owner

remkop commented Nov 1, 2018

In the case of a tool having multiple commands (not subcommands), what do I do? I can not write main method to each class that i create for a command, right?

Since you are talking about top-level commands (not subcommands), every top-level command will need a separate class with its own main method to run it.

@remkop
Copy link
Owner

remkop commented Nov 9, 2018

If your application has multiple top-level commands, each of these will need its own main method so it can be called from the commandline like this:

java -cp myjar.jar com.package.CommandOneClass -a somevalue
java -cp myjar.jar com.package.CommandTwoClass -b someothervalue

Your jar can only have one Main-Class in its manifest, and that will be the command when users invoke the jar as an application, like this:

java -jar myjar.jar -x somevalue

If you have multiple top-level commands, what people often do is provide multiple script files (shell script or batch scripts) that the end user can invoke. For example, for Windows:

# commandone.bat
java -cp myjar.jar com.package.CommandOneClass %*

This allows end users to call the command with its script name.
Build tools like gradle offer plugins that can generate these scripts for you.

@remkop
Copy link
Owner

remkop commented Nov 10, 2018

Closing this ticket. Feel free to reopen if you want further clarification

@remkop remkop closed this as completed Nov 10, 2018
@sebastienvermeille
Copy link

I have the same problem and I find the last comment more as a workaround than a real solution.

This jar will receive args[] so it has all what it needs to have in order to interprete parameters. I don't see why we should require some bash or batch scripts here.

Isn't there a better solution which could work with picocli without having to use a script ?

@remkop
Copy link
Owner

remkop commented Mar 8, 2019

@sebastienvermeille, would you mind creating a new ticket to explain your use case?

@remkop
Copy link
Owner

remkop commented Mar 10, 2019

@sebastienvermeille The OP never replied after multiple comments so it’s hard to say whether I understood their problem. I’m happy to help but it would be good if you could explain in your own words what it is you’re trying to achieve.

@sebastienvermeille
Copy link

@remkop sure if can help somehow I will :)
I create one right now with the more details I can give

@remkop
Copy link
Owner

remkop commented Mar 11, 2019

@NagendraHegde I feel that I didn’t explain things very well in response to your question.

Please take a look at #641: perhaps my answer there is more clear and hopefully the discussion on that ticket is useful to you as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants