From 4ef1fec8348328429c11830c8789fb7376916f00 Mon Sep 17 00:00:00 2001 From: Shaun Verch Date: Wed, 5 Feb 2014 15:05:39 -0500 Subject: SERVER-12589 Exclude empty sections in help output --- src/mongo/util/options_parser/option_section.cpp | 50 ++++++++++++++++++++-- src/mongo/util/options_parser/option_section.h | 6 ++- .../util/options_parser/options_parser_test.cpp | 18 ++++++++ 3 files changed, 69 insertions(+), 5 deletions(-) (limited to 'src/mongo/util/options_parser') diff --git a/src/mongo/util/options_parser/option_section.cpp b/src/mongo/util/options_parser/option_section.cpp index 886478f25af..2addd8d5d77 100644 --- a/src/mongo/util/options_parser/option_section.cpp +++ b/src/mongo/util/options_parser/option_section.cpp @@ -356,7 +356,8 @@ namespace optionenvironment { Status OptionSection::getBoostOptions(po::options_description* boostOptions, bool visibleOnly, bool includeDefaults, - OptionSources sources) const { + OptionSources sources, + bool getEmptySections) const { std::list::const_iterator oditerator; for (oditerator = _options.begin(); oditerator != _options.end(); oditerator++) { @@ -396,8 +397,19 @@ namespace optionenvironment { po::options_description subGroup = ositerator->_name.empty() ? po::options_description() : po::options_description(ositerator->_name.c_str()); - Status ret = ositerator->getBoostOptions(&subGroup, visibleOnly, includeDefaults, - sources); + + // Do not add empty sections to our option_description unless we specifically requested. + int numOptions; + Status ret = ositerator->countOptions(&numOptions, visibleOnly, sources); + if (!ret.isOK()) { + return ret; + } + if (numOptions == 0 && getEmptySections == false) { + continue; + } + + ret = ositerator->getBoostOptions(&subGroup, visibleOnly, includeDefaults, + sources, getEmptySections); if (!ret.isOK()) { return ret; } @@ -557,6 +569,32 @@ namespace optionenvironment { return Status::OK(); } + Status OptionSection::countOptions(int* numOptions, + bool visibleOnly, + OptionSources sources) const { + + *numOptions = 0; + + std::list::const_iterator oditerator; + for (oditerator = _options.begin(); oditerator != _options.end(); oditerator++) { + // Only count this option if it matches the sources we specified and the option is + // either visible or we are requesting hidden options + if ((!visibleOnly || (oditerator->_isVisible)) && + (oditerator->_sources & sources)) { + (*numOptions)++; + } + } + + std::list::const_iterator ositerator; + for (ositerator = _subSections.begin(); ositerator != _subSections.end(); ositerator++) { + int numSubOptions = 0; + ositerator->countOptions(&numSubOptions, visibleOnly, sources); + *numOptions += numSubOptions; + } + + return Status::OK(); + } + Status OptionSection::getConstraints( std::vector >* constraints) const { @@ -619,7 +657,11 @@ namespace optionenvironment { po::options_description boostOptions = _name.empty() ? po::options_description() : po::options_description(_name.c_str()); - Status ret = getBoostOptions(&boostOptions, true, true, SourceAllLegacy); + Status ret = getBoostOptions(&boostOptions, + true, /* visibleOnly */ + true, /* includeDefaults */ + SourceAllLegacy, + false); /* getEmptySections */ if (!ret.isOK()) { StringBuilder sb; sb << "Error constructing help string: " << ret.toString(); diff --git a/src/mongo/util/options_parser/option_section.h b/src/mongo/util/options_parser/option_section.h index 0da5fba3a90..0f457e99637 100644 --- a/src/mongo/util/options_parser/option_section.h +++ b/src/mongo/util/options_parser/option_section.h @@ -109,7 +109,8 @@ namespace optionenvironment { Status getBoostOptions(po::options_description* boostOptions, bool visibleOnly = false, bool includeDefaults = false, - OptionSources = SourceAll) const; + OptionSources = SourceAll, + bool getEmptySections = true) const; Status getBoostPositionalOptions( po::positional_options_description* boostPositionalOptions) const; @@ -118,6 +119,9 @@ namespace optionenvironment { // found has been registered and has the correct type Status getAllOptions(std::vector* options) const; + // Count the number of options in this section and all subsections + Status countOptions(int* numOptions, bool visibleOnly, OptionSources sources) const; + /** * Populates the given map with all the default values for any options in this option * section and all sub sections. diff --git a/src/mongo/util/options_parser/options_parser_test.cpp b/src/mongo/util/options_parser/options_parser_test.cpp index aa73d36fb3c..7a90663f218 100644 --- a/src/mongo/util/options_parser/options_parser_test.cpp +++ b/src/mongo/util/options_parser/options_parser_test.cpp @@ -3830,4 +3830,22 @@ namespace { ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment)); } + TEST(OptionCount, Basic) { + OptionsParserTester parser; + moe::Environment environment; + + moe::OptionSection testOpts; + testOpts.addOptionChaining("basic", "basic", moe::String, "Basic Option"); + testOpts.addOptionChaining("hidden", "hidden", moe::String, "Hidden Option").hidden(); + + moe::OptionSection subSection("Section Name"); + subSection.addOptionChaining("port", "port", moe::Int, "Port") + .setSources(moe::SourceYAMLConfig); + testOpts.addSection(subSection); + + int numOptions; + ASSERT_OK(testOpts.countOptions(&numOptions, true /*visibleOnly*/, moe::SourceCommandLine)); + ASSERT_EQUALS(numOptions, 1); + } + } // unnamed namespace -- cgit v1.2.1