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

[Question] How to allow flags in a multiple arguments option (or how to name the remaining() in the help) #795

Open
jmarrec opened this issue Oct 28, 2022 · 3 comments

Comments

@jmarrec
Copy link

jmarrec commented Oct 28, 2022

I'm trying to have a subcommand that takes a file, and some extra args, and those extra args are passed down to that file for later processing. (I embed ruby & python, so I want a way to execute that ruby/python file with arguments).

What I'm looking after:

Usage: Products/os-cli11 execute_ruby_script [OPTIONS] path [arguments...]

Positionals:
  path TEXT:FILE REQUIRED     Path to ruby file
  arguments args              Arguments to pass to the ruby file

The issue is that if I pass execute_ruby_script myfile.rb arg1 arg2 it works fine, but execute_ruby_script myfile.rb -x arg2 doesn't: The following argument was not expected: -x

How can I both:

  • Allow passing extra args that might be flags, AND
  • Explicitly say so in the help message?

Thanks a lot for the great lib!

Original code

Original code, also available here: https://godbolt.org/z/vasGMPrrs

Click to Expand Original code
#include <CLI/CLI.hpp>
#include <fmt/format.h>
#include <fmt/std.h>     // Formatting std::filesystem::path
#include <fmt/ranges.h>  // Formatting std::vector

#include <filesystem>
namespace fs = std::filesystem;


int main(int argc, char* argv[]) {
  CLI::App app{"My CLI"};
  app.require_subcommand(1);

  auto* execute_ruby_scriptCommand = app.add_subcommand("execute_ruby_script", "Executes a ruby file");
  fs::path rubyScriptPath;
  execute_ruby_scriptCommand->add_option("path", rubyScriptPath, "Path to ruby file")->required(true)->check(CLI::ExistingFile);
  std::vector<std::string> executeRubyScriptCommandArgs;
  execute_ruby_scriptCommand->add_option("arguments", executeRubyScriptCommandArgs, "Arguments to pass to the ruby file")
     ->required(false)
     ->option_text("args");
  execute_ruby_scriptCommand->callback([&] {
    fmt::print("rubyScriptPath={}\n", rubyScriptPath);
    fmt::print("executeRubyScriptCommandArgs=[{}]\n", executeRubyScriptCommandArgs);
    for (const auto& arg : execute_ruby_scriptCommand->remaining()) {
      fmt::print("Remaining arg: {}\n", arg);
    }
  });

  CLI11_PARSE(app, argc, argv);

}
$ oscli11 execute_ruby_script myfile.rb -x arg2
The following argument was not expected: -x
Run with --help for more information.

Remaining args: it works to forward, but the help doesn't mention it

https://godbolt.org/z/c13db5WvY

It works:

$ oscli11 execute_ruby_script myfile.rb -x arg2
rubyScriptPath="myfile.rb"
remaining=["-x", "arg2"]

But the help doesn't mention it:

$ oscli11 execute_ruby_script --help
Executes a ruby file
Usage: build/oscli11 execute_ruby_script [OPTIONS] path

Positionals:
  path TEXT REQUIRED          Path to ruby file

Options:
  -h,--help                   Print this help message and exit
Click to expand remaining args version
int main(int argc, char* argv[]) {
  CLI::App app{"My CLI"};
  app.require_subcommand(1);

  auto* execute_ruby_scriptCommand = app.add_subcommand("execute_ruby_script", "Executes a ruby file");
  fs::path rubyScriptPath;
  execute_ruby_scriptCommand->add_option("path", rubyScriptPath, "Path to ruby file")->required(true); // ->check(CLI::ExistingFile);
  execute_ruby_scriptCommand->allow_extras(true);
  execute_ruby_scriptCommand->callback([&] {
    fmt::print("rubyScriptPath={}\n", rubyScriptPath);
    fmt::print("remaining=[{}]\n", execute_ruby_scriptCommand->remaining());
  });

  CLI11_PARSE(app, argc, argv);
}
@jmarrec
Copy link
Author

jmarrec commented Oct 28, 2022

I just realized that with the original version I can add a double dash in between the file and the args and it works.

$ execute_ruby_script myfile.rb -- -x arg2 -o arg4
rubyScriptPath="myfile.rb"
executeRubyScriptCommandArgs=["-x", "arg2", "-o", "arg4"]
remaining=["--"]

Is there to way to add that double dash into the help message (or even better, REQUIRE it)? That would solve my problem.

@phlptp
Copy link
Collaborator

phlptp commented Oct 28, 2022

You can use the footer to add a user specified note.
after #786 gets merged there will be a usage field that can also be user specified.

A couple other notes. One option might be to use positionals_at_end()
then assuming the *.rb get placed in a positional argument. Everything after that would be considered a positional argument and could be placed in a positional vector.

@jmarrec
Copy link
Author

jmarrec commented Oct 31, 2022

Thanks for the tips @phlptp.

Would a feature of adding a mandatory separator --, for eg between two positionals, be of interest to the CLI11 project? app.add_separator() and it would include it in the help message + check for it?

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

2 participants