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

Do not propagate root options into subcommands #614

Open
ivan-aksamentov opened this issue Jul 14, 2021 · 2 comments
Open

Do not propagate root options into subcommands #614

ivan-aksamentov opened this issue Jul 14, 2021 · 2 comments

Comments

@ivan-aksamentov
Copy link

This is an inverse of #437 and #450

I had the exact opposite situation:

I have an existing application, which accepts flags and options and has no subcommands. Now I want to add subcommands, each with completely different options and not shared with the root options. I also don't want to break the interface for existing users.

The problem is then that I need to keep all the root options and they will propagate to all subcommands. Which is wrong in my case.

This behavior is really hard to change in my application. Basically I need to create another subcommand (let's call it "run"), move all the old root options there, and then to emulate the old behavior to reroute the calls without subcommands to the "run" subcommand. I used callblacks and ended up looking very hairy and I am not sure I handled all the edge cases corerectly (like --help needed to be excluded).

I'd like a configuration option in CLI11 to be able to tell whether I want root options to be propagated into subcommands or not. Perhaps this should be an option for each .add_subcommand() so that it can be decided individually per subcommand.

cc @phlptp

@phlptp
Copy link
Collaborator

phlptp commented Jul 14, 2021

The way I would and have handled a situation like this is to create the subcommand separately and not through the add_subcommand method.

auto subc=std::make_shared<CLI::App>("description", "sub_command_name");

Then it won't inherit the main app default. But can still be added later via

App.add_subcommand(subc);

the subcommand name will be the subcommand used in the main app. If you leave the name blank it will ack like an option group.

@zeroxia
Copy link

zeroxia commented Jul 20, 2021

The way I would and have handled a situation like this is to create the subcommand separately and not through the add_subcommand method.

auto subc=std::make_shared<CLI::App>("description", "sub_command_name");

Then it won't inherit the main app default. But can still be added later via

App.add_subcommand(subc);

the subcommand name will be the subcommand used in the main app. If you leave the name blank it will ack like an option group.

I have a similar requirement:

I have global options like "-i", "-o" for input/output to fall through, because many subcommands will need an input and output, they don't need to define it repeatedly.

But I have one special subcommand (say "test"), I think it's like a prefix command, that should keep all options to itself, even "-h", "-i", "-o" should NOT be processed by the root CLI::App instance.

Using either the prefix subcommand, or this separate shared_ptr<CLI::App>, as long as I add the special command to the root CLI::App, once I run "./program test -h", CLI11::App will capture this and dump the help screen.

Initially I tried to enable prefix_command() both on the parent and sub commands, but still I can't get any from the remaining() function.
Using the suggestion from yours, I found I can get the arguments by calling remaining(), only problem is once I specify test -h, CLI::App will dump a help screen, and the callback of my test subcommand won't be called. I actually need to have everything after test argument on the command line. How to get this done? Thanks.

UPDATE:

It turns out I can use set_help_flag() without argument to disable the default help flag to the test subcommand, then it can get everything. Thanks.

Another minor issue I'm not sure how to do it.

In the test subcommand, I actually want to call another library's applyCommandLine() API, which expects argc and argv like those for main(). So I can call subc->remaining() to get those arguments after the test subcommand name on command line, but is there any API to get the program name? So I can construct another "command line", effectively with only the "test" word removed from the original command line.

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

No branches or pull requests

3 participants