diff --git a/README.md b/README.md index 15ab0f38..adec02e6 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ OPTIONS Export the help page information. Value must be one of [html, man, ctd, cwl]. --version-check (bool) - Whether to check for the newest app version. Default: true. + Whether to check for the newest app version. Default: true VERSION Last update: diff --git a/include/sharg/detail/format_base.hpp b/include/sharg/detail/format_base.hpp index 7355a83f..575b6cc0 100644 --- a/include/sharg/detail/format_base.hpp +++ b/include/sharg/detail/format_base.hpp @@ -12,7 +12,6 @@ */ #pragma once -#include #include #include @@ -238,7 +237,6 @@ class format_base message << detail::to_string(value); } - message << ". "; return message.str(); } }; @@ -287,11 +285,12 @@ class format_help_base : public format_base std::string info{config.description}; if (config.default_message.empty()) - info += ((config.required) ? std::string{" "} : get_default_message(value, value)); + info += ((config.required) ? std::string{} : get_default_message(value, value)); else info += get_default_message(value, config.default_message); - info += config.validator.get_help_page_message(); + if (auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty()) + info += ". " + validator_message; store_help_page_element( [this, id, info]() @@ -321,20 +320,41 @@ class format_help_base : public format_base template void add_positional_option(option_type & value, config const & config) { + // a list at the end may be empty and thus have a default value + auto positional_default_message = [&value]() -> std::string + { + if constexpr (detail::is_container_option) + { + return get_default_message(value, value); + } + else + { + (void)value; // Silence unused variable warning. + return {}; + } + }; + + auto positional_validator_message = [&config]() -> std::string + { + if (auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty()) + return ". " + validator_message; + else + return {}; + }; + positional_option_calls.push_back( - [this, &value, description = config.description, validator = config.validator]() + [this, + &value, + default_message = positional_default_message(), + validator_message = positional_validator_message(), + description = config.description]() { ++positional_option_count; derived_t().print_list_item(detail::to_string("\\fBARGUMENT-", positional_option_count, "\\fP ", option_type_and_list_info(value)), - description + - // a list at the end may be empty and thus have a default value - ((detail::is_container_option) - ? get_default_message(value, value) - : std::string{" "}) - + validator.get_help_page_message()); + description + default_message + validator_message); }); } @@ -402,7 +422,7 @@ class format_help_base : public format_base + detail::supported_exports + "."); if (version_check_dev_decision == update_notifications::on) derived_t().print_list_item("\\fB--version-check\\fP (bool)", - "Whether to check for the newest app version. Default: true."); + "Whether to check for the newest app version. Default: true"); if (!meta.examples.empty()) { diff --git a/include/sharg/detail/format_tdl.hpp b/include/sharg/detail/format_tdl.hpp index 537c2391..73ac2d57 100644 --- a/include/sharg/detail/format_tdl.hpp +++ b/include/sharg/detail/format_tdl.hpp @@ -170,8 +170,14 @@ class format_tdl : format_base void add_option(option_type & value, config const & config) { auto description = config.description; - description += (config.required ? std::string{" "} : detail::to_string(" Default: ", value, ". ")); - description += config.validator.get_help_page_message(); + + if (config.default_message.empty()) + description += ((config.required) ? std::string{} : get_default_message(value, value)); + else + description += get_default_message(value, config.default_message); + + if (auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty()) + description += ". " + validator_message; auto tags = std::set{}; if (config.required) @@ -263,19 +269,38 @@ class format_tdl : format_base template void add_positional_option(option_type & value, config const & config) { - std::string msg = config.validator.get_help_page_message(); + // a list at the end may be empty and thus have a default value + auto positional_default_message = [&value]() -> std::string + { + if constexpr (detail::is_container_option) + { + return get_default_message(value, value); + } + else + { + (void)value; // Silence unused variable warning. + return {}; + } + }; + + auto positional_validator_message = [&config]() -> std::string + { + if (auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty()) + return ". " + validator_message; + else + return {}; + }; positional_option_calls.push_back( - [this, &value, config, msg](std::string_view) + [this, + &value, + config, + default_message = positional_default_message(), + validator_message = positional_validator_message()](std::string_view) { auto id = "positional_" + std::to_string(positional_option_count); ++positional_option_count; - auto description = - config.description + - // a list at the end may be empty and thus have a default value - ((detail::is_container_option) ? detail::to_string(" Default: ", value, ". ") - : std::string{" "}) - + msg; + auto description = config.description + default_message + validator_message; parameters.push_back(tdl::Node{ .name = id, diff --git a/test/snippet/readme_sneak_peek.out b/test/snippet/readme_sneak_peek.out index c00731ff..8c684226 100644 --- a/test/snippet/readme_sneak_peek.out +++ b/test/snippet/readme_sneak_peek.out @@ -20,7 +20,7 @@ OPTIONS Export the help page information. Value must be one of [html, man, ctd, cwl]. --version-check (bool) - Whether to check for the newest app version. Default: true. + Whether to check for the newest app version. Default: true VERSION Last update: diff --git a/test/unit/detail/format_ctd_test.cpp b/test/unit/detail/format_ctd_test.cpp index 1c5a111a..965b64a1 100644 --- a/test/unit/detail/format_ctd_test.cpp +++ b/test/unit/detail/format_ctd_test.cpp @@ -48,13 +48,13 @@ struct format_ctd_test : public ::testing::Test "\n" R"del( )del" "\n" - R"del( )del" + R"del( )del" "\n" - R"del( )del" + R"del( )del" "\n" - R"del( )del" + R"del( )del" "\n" - R"del( )del" + R"del( )del" "\n" R"del( )del" "\n" diff --git a/test/unit/detail/format_cwl_test.cpp b/test/unit/detail/format_cwl_test.cpp index 3cf6dee0..373e03a6 100644 --- a/test/unit/detail/format_cwl_test.cpp +++ b/test/unit/detail/format_cwl_test.cpp @@ -85,12 +85,12 @@ TEST(format_cwl_test, full_information) "doc: \"description\\ndescription2\\n\"\n" "inputs:\n" " int:\n" - " doc: \"this is a int option. Default: 5. \"\n" + " doc: \"this is a int option. Default: 5\"\n" " type: long?\n" " inputBinding:\n" " prefix: --int\n" " jint:\n" - " doc: \"this is a required int option. \"\n" + " doc: this is a required int option.\n" " type: long\n" " inputBinding:\n" " prefix: --jint\n" @@ -203,22 +203,22 @@ TEST(format_cwl_test, subparser) "doc: \"\"\n" "inputs:\n" " int:\n" - " doc: \"this is a int option. Default: 5. \"\n" + " doc: \"this is a int option. Default: 5\"\n" " type: long?\n" " inputBinding:\n" " prefix: --int\n" " jint:\n" - " doc: \"this is a required int option. \"\n" + " doc: this is a required int option.\n" " type: long\n" " inputBinding:\n" " prefix: --jint\n" " percent:\n" - " doc: \"this is a required float option. \"\n" + " doc: this is a required float option.\n" " type: double\n" " inputBinding:\n" " prefix: --percent\n" " string:\n" - " doc: \"this is a string option (advanced). Default: . \"\n" + " doc: \"this is a string option (advanced). Default: \\\"\\\"\"\n" " type: string?\n" " inputBinding:\n" " prefix: --string\n" diff --git a/test/unit/detail/format_help_test.cpp b/test/unit/detail/format_help_test.cpp index 2c5cb9ff..35c07d59 100644 --- a/test/unit/detail/format_help_test.cpp +++ b/test/unit/detail/format_help_test.cpp @@ -39,7 +39,7 @@ std::string const basic_options_str = " Common options\n" "[html, man].\n" #endif " --version-check (bool)\n" - " Whether to check for the newest app version. Default: true.\n"; + " Whether to check for the newest app version. Default: true\n"; std::string const basic_version_str = "VERSION\n" " Last update:\n" @@ -132,18 +132,18 @@ TEST(help_page_printing, quote_strings) "===========\n\n" "POSITIONAL ARGUMENTS\n" " ARGUMENT-1 (List of std::string)\n" - " Default: [\"Some\", \"other\", \"string\"].\n\n" + " Default: [\"Some\", \"other\", \"string\"]\n\n" "OPTIONS\n" " -a, --string1 (std::string)\n" - " Default: \"\".\n" + " Default: \"\"\n" " -b, --string2 (std::string)\n" - " Default: \"Some string\".\n" + " Default: \"Some string\"\n" " -c, --string3 (std::string)\n" - " Default: \"Quoted\".\n" + " Default: \"Quoted\"\n" " -d, --string4 (List of std::string)\n" - " Default: [\"Some\", \"other\", \"string\"].\n" + " Default: [\"Some\", \"other\", \"string\"]\n" " -e, --string5 (List of std::string)\n" - " Default: None.\n\n" + " Default: None\n\n" + basic_options_str + "\n" + basic_version_str; EXPECT_EQ(std_cout, expected); } @@ -171,18 +171,18 @@ TEST(help_page_printing, quote_paths) "===========\n\n" "POSITIONAL ARGUMENTS\n" " ARGUMENT-1 (List of std::filesystem::path)\n" - " Default: [\"/some\", \"/other\", \"/path\"].\n\n" + " Default: [\"/some\", \"/other\", \"/path\"]\n\n" "OPTIONS\n" " -a, --path1 (std::filesystem::path)\n" - " Default: \"\".\n" + " Default: \"\"\n" " -b, --path2 (std::filesystem::path)\n" - " Default: \"/some/path\".\n" + " Default: \"/some/path\"\n" " -c, --path3 (std::filesystem::path)\n" - " Default: \"/usr/bin/\".\n" + " Default: \"/usr/bin/\"\n" " -d, --path4 (List of std::filesystem::path)\n" - " Default: [\"/some\", \"/other\", \"/path\"].\n" + " Default: [\"/some\", \"/other\", \"/path\"]\n" " -e, --path5 (List of std::filesystem::path)\n" - " Default: None.\n\n" + " Default: None\n\n" + basic_options_str + "\n" + basic_version_str; EXPECT_EQ(std_cout, expected); } @@ -452,7 +452,7 @@ TEST(help_page_printing, advanced_options) "\n" " advanced subsection\n" " -j, --jnt (unsigned 8 bit integer)\n" - " this is a int option. Default: 2.\n" + " this is a int option. Default: 2\n" " -f, --flag\n" " this is a flag.\n" " -s, --some\n" @@ -532,10 +532,10 @@ TEST(help_page_printing, full_information) " ARGUMENT-1 (signed 8 bit integer)\n" " this is not a list.\n" " ARGUMENT-2 (List of std::string)\n" - " this is a positional option. Default: [].\n" + " this is a positional option. Default: []\n" "\nOPTIONS\n" " -i, --int (signed 32 bit integer)\n" - " this is a int option. Default: A number.\n" + " this is a int option. Default: A number\n" " -e, --enum (foo)\n" " this is an enum option. Default: one. Value must be one of [three,\n" " two, one].\n" @@ -662,7 +662,7 @@ TEST(parse_test, subcommand_parser) " subcommand key word is passed on to the corresponding sub-parser.\n" "\nOPTIONS\n" " -f, --foo (signed 32 bit integer)\n" - " foo bar. Default: 0.\n" + " foo bar. Default: 0\n" "\n" + basic_options_str + "\n" + basic_version_str; diff --git a/test/unit/detail/format_html_test.cpp b/test/unit/detail/format_html_test.cpp index 8c83d1a0..2b2d7e24 100644 --- a/test/unit/detail/format_html_test.cpp +++ b/test/unit/detail/format_html_test.cpp @@ -49,7 +49,7 @@ TEST(html_format, empty_information) "[html, man].\n" #endif "
--version-check (bool)
\n" - "
Whether to check for the newest app version. Default: true.
\n" + "
Whether to check for the newest app version. Default: true
\n" "\n" "

Version

\n" "

\n" @@ -143,16 +143,16 @@ TEST(html_format, full_information_information) "

Positional Arguments

\n" "
\n" "
ARGUMENT-1 (signed 8 bit integer)
\n" - "
this is a positional option.
\n" + "
this is a positional option.
\n" "
ARGUMENT-2 (List of std::string)
\n" - "
this is a positional option. Default: [].
\n" + "
this is a positional option. Default: []
\n" "
\n" "

Options

\n" "
\n" "
-i, --int (signed 32 bit integer)
\n" - "
this is a int option. Default: A number.
\n" + "
this is a int option. Default: A number
\n" "
-j, --jint (signed 32 bit integer)
\n" - "
this is a required int option.
\n" + "
this is a required int option.
\n" "
-f, --flag
\n" "
this is a flag.
\n" "
-k, --kflag
\n" @@ -176,7 +176,7 @@ TEST(html_format, full_information_information) "[html, man].\n" #endif "
--version-check (bool)
\n" - "
Whether to check for the newest app version. Default: true.
\n" + "
Whether to check for the newest app version. Default: true
\n" "
\n" "

Examples

\n" "

\n" diff --git a/test/unit/detail/format_man_test.cpp b/test/unit/detail/format_man_test.cpp index d2468771..5e2f467e 100644 --- a/test/unit/detail/format_man_test.cpp +++ b/test/unit/detail/format_man_test.cpp @@ -47,13 +47,13 @@ struct format_man_test : public ::testing::Test "\n" R"(\fBARGUMENT-1\fP (\fIsigned 8 bit integer\fP))" "\n" - R"(this is a positional option. )" + R"(this is a positional option.)" "\n" R"(.TP)" "\n" R"(\fBARGUMENT-2\fP (\fIList\fP of \fIstd::string\fP))" "\n" - R"(this is a positional option. Default: []. )" + R"(this is a positional option. Default: [])" "\n" R"(.SH OPTIONS)" "\n" @@ -61,13 +61,13 @@ struct format_man_test : public ::testing::Test "\n" R"(\fB-i\fP, \fB--int\fP (\fIsigned 32 bit integer\fP))" "\n" - R"(this is a int option. Default: A number. )" + R"(this is a int option. Default: A number)" "\n" R"(.TP)" "\n" R"(\fB-j\fP, \fB--jint\fP (\fIsigned 32 bit integer\fP))" "\n" - R"(this is a required int option. )" + R"(this is a required int option.)" "\n" R"(.SH FLAGS)" "\n" @@ -128,7 +128,7 @@ struct format_man_test : public ::testing::Test "\n" R"(\fB--version-check\fP (bool))" "\n" - R"(Whether to check for the newest app version. Default: true.)" + R"(Whether to check for the newest app version. Default: true)" "\n" R"(.SH EXAMPLES)" "\n" @@ -246,7 +246,7 @@ TEST_F(format_man_test, empty_information) "\n" R"(\fB--version-check\fP (bool))" "\n" - R"(Whether to check for the newest app version. Default: true.)" + R"(Whether to check for the newest app version. Default: true)" "\n" R"(.SH VERSION)" "\n" diff --git a/test/unit/detail/seqan3_test.cpp b/test/unit/detail/seqan3_test.cpp index 6999f8ff..abe6d39b 100644 --- a/test/unit/detail/seqan3_test.cpp +++ b/test/unit/detail/seqan3_test.cpp @@ -26,7 +26,7 @@ std::string const basic_options_str = " Common options\n" "[html, man].\n" #endif " --version-check (bool)\n" - " Whether to check for the newest app version. Default: true.\n"; + " Whether to check for the newest app version. Default: true\n"; std::string const basic_version_str = "VERSION\n" " Last update:\n" diff --git a/test/unit/parser/format_parse_validators_test.cpp b/test/unit/parser/format_parse_validators_test.cpp index 6d717a03..637bd385 100644 --- a/test/unit/parser/format_parse_validators_test.cpp +++ b/test/unit/parser/format_parse_validators_test.cpp @@ -171,8 +171,8 @@ TEST(validator_test, input_file) "\n" "POSITIONAL ARGUMENTS\n" " ARGUMENT-1 (std::filesystem::path)\n" - " desc The input file must exist and read permissions must be granted.\n" - " Valid file extensions are: [fa, sam, fasta, fasta.txt].\n" + " desc. The input file must exist and read permissions must be\n" + " granted. Valid file extensions are: [fa, sam, fasta, fasta.txt].\n" "\nOPTIONS\n\n"} + basic_options_str + "\n" + basic_version_str; EXPECT_EQ(my_stdout, expected); @@ -323,7 +323,7 @@ TEST(validator_test, output_file) "\n" "POSITIONAL ARGUMENTS\n" " ARGUMENT-1 (std::filesystem::path)\n" - " desc The output file must not exist already and write permissions\n" + " desc. The output file must not exist already and write permissions\n" " must be granted. Valid file extensions are: [fa, sam, fasta,\n" " fasta.txt].\n" "\nOPTIONS\n\n"} @@ -352,7 +352,7 @@ TEST(validator_test, output_file) "\n" "POSITIONAL ARGUMENTS\n" " ARGUMENT-1 (std::filesystem::path)\n" - " desc Write permissions must be granted. Valid file extensions are:\n" + " desc. Write permissions must be granted. Valid file extensions are:\n" " [fa, sam, fasta, fasta.txt].\n" "\nOPTIONS\n\n"} + basic_options_str + "\n" + basic_version_str; @@ -443,7 +443,7 @@ TEST(validator_test, input_directory) "\n" "POSITIONAL ARGUMENTS\n" " ARGUMENT-1 (std::filesystem::path)\n" - " desc An existing, readable path for the input directory.\n" + " desc. An existing, readable path for the input directory.\n" "\nOPTIONS\n\n"} + basic_options_str + "\n" + basic_version_str; @@ -505,7 +505,7 @@ TEST(validator_test, output_directory) "\n" "POSITIONAL ARGUMENTS\n" " ARGUMENT-1 (std::filesystem::path)\n" - " desc A valid path for the output directory.\n" + " desc. A valid path for the output directory.\n" "\nOPTIONS\n\n"} + basic_options_str + "\n" + basic_version_str;