diff --git a/book/chapters/config.md b/book/chapters/config.md index d062c659..30ca48ef 100644 --- a/book/chapters/config.md +++ b/book/chapters/config.md @@ -87,6 +87,10 @@ app.allow_config_extras(CLI::config_extras_mode::ignore_all); will completely ignore any mismatches, extras, or other issues with the config file +Config file extras are stored in the remaining output as two components. The +first is the name of the field including subcommands using dot notation the +second (or more) are the argument fields. + ### Getting the used configuration file name If it is needed to get the configuration file name used this can be obtained via diff --git a/include/CLI/impl/App_inl.hpp b/include/CLI/impl/App_inl.hpp index 01d74e6d..7d487442 100644 --- a/include/CLI/impl/App_inl.hpp +++ b/include/CLI/impl/App_inl.hpp @@ -1414,6 +1414,9 @@ CLI11_INLINE bool App::_parse_single_config(const ConfigItem &item, std::size_t if(get_allow_config_extras() == config_extras_mode::capture) // Should we worry about classifying the extras properly? missing_.emplace_back(detail::Classifier::NONE, item.fullname()); + for(const auto &input : item.inputs) { + missing_.emplace_back(detail::Classifier::NONE, input); + } return false; } diff --git a/tests/ConfigFileTest.cpp b/tests/ConfigFileTest.cpp index eb6af960..b043b110 100644 --- a/tests/ConfigFileTest.cpp +++ b/tests/ConfigFileTest.cpp @@ -509,10 +509,47 @@ TEST_CASE_METHOD(TApp, "IniGetRemainingOption", "[config]") { int two{0}; app.add_option("--two", two); REQUIRE_NOTHROW(run()); - std::vector ExpectedRemaining = {ExtraOption}; + std::vector ExpectedRemaining = {ExtraOption, "3"}; CHECK(ExpectedRemaining == app.remaining()); } +TEST_CASE_METHOD(TApp, "IniRemainingSub", "[config]") { + TempFile tmpini{"TestIniTmp.ini"}; + + app.set_config("--config", tmpini); + auto *map = app.add_subcommand("map"); + map->allow_config_extras(); + + { + std::ofstream out{tmpini}; + out << "[map]\n"; + out << "a = 1\n"; + out << "b=[1,2,3]\n"; + out << "c = 3" << std::endl; + } + + REQUIRE_NOTHROW(run()); + std::vector rem = map->remaining(); + REQUIRE(rem.size() == 8U); + CHECK(rem[0] == "map.a"); + CHECK(rem[2] == "map.b"); + CHECK(rem[6] == "map.c"); + CHECK(rem[5] == "3"); + + int a{0}; + int c{0}; + std::vector b; + map->add_option("-a", a); + map->add_option("-b", b); + map->add_option("-c", c); + + CHECK_NOTHROW(app.parse(app.remaining_for_passthrough())); + CHECK(a == 1); + CHECK(c == 3); + REQUIRE(b.size() == 3U); + CHECK(b[1] == 2); +} + TEST_CASE_METHOD(TApp, "IniGetNoRemaining", "[config]") { TempFile tmpini{"TestIniTmp.ini"};