[vcpkg] Improve `vcpkg help` -- now has per-command help!
MODIFY
include/vcpkg/base/cstringview.h
include/vcpkg/base/cstringview.h
@@ -63,6 +63,8 @@ namespace vcpkg
inline bool operator!=(const std::string& l, const CStringView& r) { return l != r.c_str(); }
+ inline std::string operator+(std::string&& l, const CStringView& r) { return std::move(l) + r.c_str(); }
+
inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); }
static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*");

MODIFY
include/vcpkg/export.h
include/vcpkg/export.h
namespace vcpkg::Export
{
+ extern const CommandStructure COMMAND_STRUCTURE;
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths);

MODIFY
include/vcpkg/help.h
include/vcpkg/help.h
namespace vcpkg::Help
{
+ extern const CommandStructure COMMAND_STRUCTURE;
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
void help_topic_valid_triplet(const VcpkgPaths& paths);
void print_usage();
- void print_example(const std::string& command_and_arguments);
-
std::string create_example_string(const std::string& command_and_arguments);
}

MODIFY
include/vcpkg/vcpkgcmdarguments.h
include/vcpkg/vcpkgcmdarguments.h
@@ -49,6 +49,8 @@ namespace vcpkg
std::vector<std::string> (*valid_arguments)(const VcpkgPaths& paths);
};
+ void display_usage(const CommandStructure& command_structure);
+
#if defined(_WIN32)
using CommandLineCharType = wchar_t;
#else

MODIFY
src/vcpkg/export.cpp
src/vcpkg/export.cpp
#include <vcpkg/base/util.h>
#include <vcpkg/commands.h>
#include <vcpkg/dependencies.h>
+#include <vcpkg/export.h>
#include <vcpkg/export.ifw.h>
#include <vcpkg/help.h>
#include <vcpkg/input.h>
@@ -289,7 +290,7 @@ namespace vcpkg::Export
{OPTION_IFW_INSTALLER_FILE_PATH, ""},
}};
- const CommandStructure COMMAND_STRUCTURE = {
+ const CommandStructure vcpkg::Export::COMMAND_STRUCTURE = {
Help::create_example_string("export zlib zlib:x64-windows boost --nuget"),
0,
SIZE_MAX,

MODIFY
src/vcpkg/help.cpp
src/vcpkg/help.cpp
#include <vcpkg/base/system.h>
#include <vcpkg/commands.h>
+#include <vcpkg/export.h>
+#include <vcpkg/help.h>
+#include <vcpkg/install.h>
+#include <vcpkg/remove.h>
namespace vcpkg::Help
{
- void help_topics()
+ struct Topic
+ {
+ using topic_function = void (*)(const VcpkgPaths& paths);
+
+ constexpr Topic(CStringView n, topic_function fn) : name(n), print(fn) {}
+
+ CStringView name;
+ topic_function print;
+ };
+
+ template<const CommandStructure& S>
+ static void command_topic_fn(const VcpkgPaths&)
+ {
+ display_usage(S);
+ }
+
+ static void integrate_topic_fn(const VcpkgPaths&)
+ {
+ System::print("Commands:\n"
+ "%s",
+ Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING);
+ }
+
+ static void help_topics(const VcpkgPaths&);
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("help"),
+ 0,
+ 1,
+ {},
+ nullptr,
+ };
+
+ static constexpr std::array<Topic, 12> topics = {{
+ {"create", command_topic_fn<Commands::Create::COMMAND_STRUCTURE>},
+ {"edit", command_topic_fn<Commands::Edit::COMMAND_STRUCTURE>},
+ {"env", command_topic_fn<Commands::Env::COMMAND_STRUCTURE>},
+ {"export", command_topic_fn<Export::COMMAND_STRUCTURE>},
+ {"help", command_topic_fn<Help::COMMAND_STRUCTURE>},
+ {"install", command_topic_fn<Install::COMMAND_STRUCTURE>},
+ {"integrate", integrate_topic_fn},
+ {"list", command_topic_fn<Commands::List::COMMAND_STRUCTURE>},
+ {"owns", command_topic_fn<Commands::Owns::COMMAND_STRUCTURE>},
+ {"remove", command_topic_fn<Remove::COMMAND_STRUCTURE>},
+ {"search", command_topic_fn<Commands::Search::COMMAND_STRUCTURE>},
+ {"topics", help_topics},
+ }};
+
+ static void help_topics(const VcpkgPaths&)
{
System::println("Available help topics:\n"
" triplet\n"
- " integrate\n"
- " export");
+ " integrate"
+ "%s",
+ Strings::join("", topics, [](const Topic& topic) { return std::string("\n ") + topic.name; }));
}
void help_topic_valid_triplet(const VcpkgPaths& paths)
@@ -22,21 +75,6 @@ namespace vcpkg::Help
}
}
- void help_topic_export()
- {
- System::println("Summary:\n"
- " vcpkg export [options] <pkgs>...\n"
- "\n"
- "Options:\n"
- " --7zip Export to a 7zip (.7z) file\n"
- " --dry-run Do not actually export\n"
- " --nuget Export a NuGet package\n"
- " --nuget-id=<id> Specify the id for the exported NuGet package\n"
- " --nuget-version=<ver> Specify the version for the exported NuGet package\n"
- " --raw Export to an uncompressed directory\n"
- " --zip Export to a zip file");
- }
-
void print_usage()
{
System::println(
@@ -86,19 +124,6 @@ namespace vcpkg::Help
return cs;
}
- void print_example(const std::string& command_and_arguments)
- {
- System::println(create_example_string(command_and_arguments));
- }
-
- const CommandStructure COMMAND_STRUCTURE = {
- Help::create_example_string("help"),
- 0,
- 1,
- {},
- nullptr,
- };
-
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
args.parse_arguments(COMMAND_STRUCTURE);
@@ -112,27 +137,18 @@ namespace vcpkg::Help
if (topic == "triplet" || topic == "triplets" || topic == "triple")
{
help_topic_valid_triplet(paths);
+ Checks::exit_success(VCPKG_LINE_INFO);
}
- else if (topic == "export")
- {
- help_topic_export();
- }
- else if (topic == "integrate")
- {
- System::print("Commands:\n"
- "%s",
- Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING);
- }
- else if (topic == "topics")
+
+ auto it_topic = Util::find_if(topics, [&](const Topic& t) { return t.name == topic; });
+ if (it_topic != topics.end())
{
- help_topics();
+ it_topic->print(paths);
+ Checks::exit_success(VCPKG_LINE_INFO);
}
- else
- {
+
System::println(System::Color::error, "Error: unknown topic %s", topic);
- help_topics();
+ help_topics(paths);
Checks::exit_fail(VCPKG_LINE_INFO);
}
- Checks::exit_success(VCPKG_LINE_INFO);
- }
}

MODIFY
src/vcpkg/vcpkgcmdarguments.cpp
src/vcpkg/vcpkgcmdarguments.cpp
@@ -249,13 +249,22 @@ namespace vcpkg
}
if (failed)
+ {
+ display_usage(command_structure);
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ return output;
+ }
+
+ void display_usage(const CommandStructure& command_structure)
{
if (!command_structure.example_text.empty())
{
System::println("%s", command_structure.example_text);
}
- System::println("Options:", this->command);
+ System::println("Options:");
for (auto&& option : command_structure.options.switches)
{
System::println(" %-40s %s", option.name, option.short_help_text);
@@ -264,12 +273,9 @@ namespace vcpkg
{
System::println(" %-40s %s", (option.name + "=..."), option.short_help_text);
}
- System::println(" --triplet <t>");
- System::println(" --vcpkg-root <path>");
-
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- return output;
+ System::println(" %-40s %s", "--triplet <t>", "Set the default triplet for unqualified packages");
+ System::println(" %-40s %s",
+ "--vcpkg-root <path>",
+ "Specify the vcpkg directory to use instead of current directory or tool directory");
}
}

[vcpkg] Improve `vcpkg help` -- now has per-command help!