Skip to content

Positional before command? #125

@fakuivan

Description

@fakuivan

I'm trying to add a required positional before a group of commands but the parsing isn't working correctly. Here's an example:

#include "args/args.hxx"

int main(int argc, const char **argv) {
  args::ArgumentParser parser("Compress and decompress leveldb DB");
  args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});
  args::CompletionFlag completion(parser, {"completion"});
  args::Positional<std::string> db_file(parser, "input", "Input database file",
                                        args::Options::Required);
  args::Group commands(parser, "commands");
  args::Command compress(commands, "compress",
                         "Enables compression on a database");
  args::Command decompress(commands, "decompress",
                           "Remove compression on a database");
  try {
    parser.ParseCLI(argc, argv);
  } catch (const args::Completion &e) {
    std::cout << e.what();
    return 0;
  } catch (const args::Help &) {
    std::cout << parser;
    return 0;
  } catch (const args::ParseError &e) {
    std::cerr << e.what() << std::endl;
    std::cerr << parser;
    return 1;
  }
  std::cout << "Input database is: " << args::get(db_file) << std::endl;
  if (compress) {
    std::cout << "Compressing database" << std::endl;
  }
  if (decompress) {
    std::cout << "Decompressing database" << std::endl;
  }
  return 0;
}

It should work like this:

$ ./main input-file compress
Unknown command: input-file
  ./main COMMAND {OPTIONS} input

    Compress and decompress leveldb DB

  OPTIONS:

      -h, --help                        Display this help menu
      input                             Input database file
      commands
        compress                          Enables compression on a database
        decompress                        Remove compression on a database
      "--" can be used to terminate flag options and force all following
      arguments to be treated as positional options

Not like this, but the command is recognized

$ ./main compress input-file
Passed in argument, but no positional arguments were ready to receive it: input-file
  ./main compress

    Enables compression on a database

  OPTIONS:

And finally only with the command, the input field is still being requested.

$ ./main compress
terminate called after throwing an instance of 'args::RequiredError'
  what():  Option 'input' is required
Aborted (core dumped)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions