Commit 9d41ddef83ed8695b69707bb65a47772a9e57407
Committed by
Henry Schreiner
1 parent
b7c031cc
Better mixing of positionals and unlimited options (#102)
Showing
3 changed files
with
29 additions
and
7 deletions
README.md
| ... | ... | @@ -211,7 +211,7 @@ Extra positional arguments will cause the program to exit, so at least one posit |
| 211 | 211 | If you set `.allow_extras()` on the main `App`, you will not get an error. You can access the missing options using `remaining` (if you have subcommands, `app.remaining(true)` will get all remaining options, subcommands included). |
| 212 | 212 | |
| 213 | 213 | You can access a vector of pointers to the parsed options in the original order using `parse_order()`. |
| 214 | -If `--` is present in the command line, | |
| 214 | +If `--` is present in the command line that does not end an unlimited option, then | |
| 215 | 215 | everything after that is positional only. |
| 216 | 216 | |
| 217 | 217 | ... | ... |
include/CLI/App.hpp
| ... | ... | @@ -1461,12 +1461,6 @@ class App { |
| 1461 | 1461 | // If any positionals remain, don't keep eating |
| 1462 | 1462 | if(_count_remaining_positionals() > 0) |
| 1463 | 1463 | break; |
| 1464 | - | |
| 1465 | - // If there are any unlimited positionals, those also take priority | |
| 1466 | - if(std::any_of(std::begin(options_), std::end(options_), [](const Option_p &opt) { | |
| 1467 | - return opt->get_positional() && opt->get_items_expected() < 0; | |
| 1468 | - })) | |
| 1469 | - break; | |
| 1470 | 1464 | } |
| 1471 | 1465 | op->add_result(args.back()); |
| 1472 | 1466 | parse_order_.push_back(op.get()); | ... | ... |
tests/AppTest.cpp
| ... | ... | @@ -543,8 +543,22 @@ TEST_F(TApp, RequiredOptsUnlimited) { |
| 543 | 543 | std::vector<std::string> remain; |
| 544 | 544 | app.add_option("positional", remain); |
| 545 | 545 | run(); |
| 546 | + EXPECT_EQ(strs, std::vector<std::string>({"one", "two"})); | |
| 547 | + EXPECT_EQ(remain, std::vector<std::string>()); | |
| 548 | + | |
| 549 | + app.reset(); | |
| 550 | + args = {"--str", "one", "--", "two"}; | |
| 551 | + | |
| 552 | + run(); | |
| 546 | 553 | EXPECT_EQ(strs, std::vector<std::string>({"one"})); |
| 547 | 554 | EXPECT_EQ(remain, std::vector<std::string>({"two"})); |
| 555 | + | |
| 556 | + app.reset(); | |
| 557 | + args = {"one", "--str", "two"}; | |
| 558 | + | |
| 559 | + run(); | |
| 560 | + EXPECT_EQ(strs, std::vector<std::string>({"two"})); | |
| 561 | + EXPECT_EQ(remain, std::vector<std::string>({"one"})); | |
| 548 | 562 | } |
| 549 | 563 | |
| 550 | 564 | TEST_F(TApp, RequiredOptsUnlimitedShort) { |
| ... | ... | @@ -577,8 +591,22 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) { |
| 577 | 591 | std::vector<std::string> remain; |
| 578 | 592 | app.add_option("positional", remain); |
| 579 | 593 | run(); |
| 594 | + EXPECT_EQ(strs, std::vector<std::string>({"one", "two"})); | |
| 595 | + EXPECT_EQ(remain, std::vector<std::string>()); | |
| 596 | + | |
| 597 | + app.reset(); | |
| 598 | + args = {"-s", "one", "--", "two"}; | |
| 599 | + | |
| 600 | + run(); | |
| 580 | 601 | EXPECT_EQ(strs, std::vector<std::string>({"one"})); |
| 581 | 602 | EXPECT_EQ(remain, std::vector<std::string>({"two"})); |
| 603 | + | |
| 604 | + app.reset(); | |
| 605 | + args = {"one", "-s", "two"}; | |
| 606 | + | |
| 607 | + run(); | |
| 608 | + EXPECT_EQ(strs, std::vector<std::string>({"two"})); | |
| 609 | + EXPECT_EQ(remain, std::vector<std::string>({"one"})); | |
| 582 | 610 | } |
| 583 | 611 | |
| 584 | 612 | TEST_F(TApp, OptsUnlimitedEnd) { | ... | ... |