Skip to content

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

Open
@jmarrec

Description

@jmarrec

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);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions