aboutsummaryrefslogtreecommitdiff
path: root/toolsrc
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-11-02 15:20:42 -0700
committerRobert Schumacher <roschuma@microsoft.com>2017-11-02 15:20:42 -0700
commit6a91d1ece10ce0aeda89c44611d5335a07b8e40d (patch)
treeedeb7817fcfa3790ad68b785a3a19034b456b252 /toolsrc
parent38136a2d05435dc1ef4d9604b1336509a6d667f8 (diff)
downloadvcpkg-6a91d1ece10ce0aeda89c44611d5335a07b8e40d.tar.gz
vcpkg-6a91d1ece10ce0aeda89c44611d5335a07b8e40d.zip
[vcpkg] Refactor argument parsing to use common code paths.
Diffstat (limited to 'toolsrc')
-rw-r--r--toolsrc/include/vcpkg/base/span.h12
-rw-r--r--toolsrc/include/vcpkg/base/util.h2
-rw-r--r--toolsrc/include/vcpkg/build.h8
-rw-r--r--toolsrc/include/vcpkg/commands.h7
-rw-r--r--toolsrc/include/vcpkg/vcpkgcmdarguments.h65
-rw-r--r--toolsrc/src/tests.arguments.cpp11
-rw-r--r--toolsrc/src/vcpkg/build.cpp29
-rw-r--r--toolsrc/src/vcpkg/commands.autocomplete.cpp10
-rw-r--r--toolsrc/src/vcpkg/commands.buildexternal.cpp20
-rw-r--r--toolsrc/src/vcpkg/commands.cache.cpp16
-rw-r--r--toolsrc/src/vcpkg/commands.ci.cpp20
-rw-r--r--toolsrc/src/vcpkg/commands.contact.cpp12
-rw-r--r--toolsrc/src/vcpkg/commands.cpp2
-rw-r--r--toolsrc/src/vcpkg/commands.create.cpp15
-rw-r--r--toolsrc/src/vcpkg/commands.dependinfo.cpp12
-rw-r--r--toolsrc/src/vcpkg/commands.edit.cpp18
-rw-r--r--toolsrc/src/vcpkg/commands.env.cpp12
-rw-r--r--toolsrc/src/vcpkg/commands.hash.cpp15
-rw-r--r--toolsrc/src/vcpkg/commands.import.cpp14
-rw-r--r--toolsrc/src/vcpkg/commands.integrate.cpp13
-rw-r--r--toolsrc/src/vcpkg/commands.list.cpp20
-rw-r--r--toolsrc/src/vcpkg/commands.owns.cpp13
-rw-r--r--toolsrc/src/vcpkg/commands.portsdiff.cpp15
-rw-r--r--toolsrc/src/vcpkg/commands.search.cpp22
-rw-r--r--toolsrc/src/vcpkg/commands.version.cpp11
-rw-r--r--toolsrc/src/vcpkg/export.cpp80
-rw-r--r--toolsrc/src/vcpkg/help.cpp11
-rw-r--r--toolsrc/src/vcpkg/install.cpp26
-rw-r--r--toolsrc/src/vcpkg/remove.cpp42
-rw-r--r--toolsrc/src/vcpkg/update.cpp11
-rw-r--r--toolsrc/src/vcpkg/vcpkgcmdarguments.cpp147
31 files changed, 424 insertions, 287 deletions
diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h
index 6be546351..158f1ac74 100644
--- a/toolsrc/include/vcpkg/base/span.h
+++ b/toolsrc/include/vcpkg/base/span.h
@@ -57,4 +57,16 @@ namespace vcpkg
{
return {v.data(), v.size()};
}
+
+ template<class T>
+ constexpr T* begin(Span<T> sp)
+ {
+ return sp.begin();
+ }
+
+ template<class T>
+ constexpr T* end(Span<T> sp)
+ {
+ return sp.end();
+ }
} \ No newline at end of file
diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h
index e67d38ad8..155b16cf7 100644
--- a/toolsrc/include/vcpkg/base/util.h
+++ b/toolsrc/include/vcpkg/base/util.h
@@ -30,7 +30,7 @@ namespace vcpkg::Util
}
template<class Cont, class Func>
- using FmapOut = decltype(std::declval<Func>()(*begin(std::declval<Cont>())));
+ using FmapOut = decltype(std::declval<Func&>()(*begin(std::declval<Cont&>())));
template<class Cont, class Func, class Out = FmapOut<Cont, Func>>
std::vector<Out> fmap(Cont&& xs, Func&& f)
diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h
index 94d9fddf5..824f3ccaf 100644
--- a/toolsrc/include/vcpkg/build.h
+++ b/toolsrc/include/vcpkg/build.h
@@ -18,10 +18,10 @@ namespace vcpkg::Build
{
namespace Command
{
- void perform_and_exit(const FullPackageSpec& full_spec,
- const fs::path& port_dir,
- const ParsedArguments& options,
- const VcpkgPaths& paths);
+ void perform_and_exit_ex(const FullPackageSpec& full_spec,
+ const fs::path& port_dir,
+ const ParsedArguments& options,
+ const VcpkgPaths& paths);
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}
diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h
index d9ebad2c4..74fd80c03 100644
--- a/toolsrc/include/vcpkg/commands.h
+++ b/toolsrc/include/vcpkg/commands.h
@@ -23,16 +23,19 @@ namespace vcpkg::Commands
namespace CI
{
+ extern const CommandStructure COMMAND_STRUCTURE;
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}
namespace Env
{
+ extern const CommandStructure COMMAND_STRUCTURE;
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}
namespace Create
{
+ extern const CommandStructure COMMAND_STRUCTURE;
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
}
@@ -49,16 +52,19 @@ namespace vcpkg::Commands
namespace Search
{
+ extern const CommandStructure COMMAND_STRUCTURE;
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
}
namespace List
{
+ extern const CommandStructure COMMAND_STRUCTURE;
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
}
namespace Owns
{
+ extern const CommandStructure COMMAND_STRUCTURE;
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
}
@@ -99,6 +105,7 @@ namespace vcpkg::Commands
namespace Contact
{
+ extern const CommandStructure COMMAND_STRUCTURE;
const std::string& email();
void perform_and_exit(const VcpkgCmdArguments& args);
}
diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h
index e59979ad1..a832caf04 100644
--- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h
+++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h
@@ -17,13 +17,47 @@ namespace vcpkg
std::unordered_map<std::string, std::string> settings;
};
- struct VcpkgCmdArguments
+ struct VcpkgPaths;
+
+ struct CommandSwitch
+ {
+ std::string name;
+ CStringView short_help_text;
+ };
+
+ struct CommandSetting
{
+ std::string name;
+ CStringView short_help_text;
+ };
+
+ struct CommandOptionsStructure
+ {
+ Span<const CommandSwitch> switches;
+ Span<const CommandSetting> settings;
+ };
+
+ struct CommandStructure
+ {
+ std::string example_text;
+
+ size_t minimum_arity;
+ size_t maximum_arity;
+
+ CommandOptionsStructure options;
+
+ std::vector<std::string> (*valid_arguments)(const VcpkgPaths& paths);
+ };
+
#if defined(_WIN32)
- static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv);
+ using CommandLineCharType = wchar_t;
#else
- static VcpkgCmdArguments create_from_command_line(const int argc, const char* const* const argv);
+ using CommandLineCharType = char;
#endif
+
+ struct VcpkgCmdArguments
+ {
+ static VcpkgCmdArguments create_from_command_line(const int argc, const CommandLineCharType* const* const argv);
static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end);
std::unique_ptr<std::string> vcpkg_root_dir;
@@ -35,32 +69,9 @@ namespace vcpkg
std::string command;
std::vector<std::string> command_arguments;
- ParsedArguments check_and_get_optional_command_arguments(const std::vector<std::string>& valid_switches,
- const std::vector<std::string>& valid_settings) const;
-
- void check_max_arg_count(const size_t expected_arg_count) const;
- void check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const;
- void check_min_arg_count(const size_t expected_arg_count) const;
- void check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const;
- void check_exact_arg_count(const size_t expected_arg_count) const;
- void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const;
+ ParsedArguments parse_arguments(const CommandStructure& command_structure) const;
private:
std::unordered_map<std::string, Optional<std::string>> optional_command_arguments;
};
-
- struct VcpkgPaths;
-
- struct CommandStructure
- {
- CStringView example_text;
-
- size_t minimum_arity;
- size_t maximum_arity;
-
- Span<const std::string> switches;
- Span<const std::string> settings;
-
- std::vector<std::string> (*valid_arguments)(const VcpkgPaths& paths);
- };
}
diff --git a/toolsrc/src/tests.arguments.cpp b/toolsrc/src/tests.arguments.cpp
index 25bf0f085..0f082222d 100644
--- a/toolsrc/src/tests.arguments.cpp
+++ b/toolsrc/src/tests.arguments.cpp
@@ -34,9 +34,12 @@ namespace UnitTest1
TEST_METHOD(create_from_arg_sequence_valued_options)
{
+ std::array<CommandSetting, 1> settings = { {{"--a", ""}} };
+ CommandStructure cmdstruct = { "", 0, SIZE_MAX, {{}, settings }, nullptr };
+
std::vector<std::string> t = {"--a=b", "command", "argument"};
auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
- auto opts = v.check_and_get_optional_command_arguments({}, {"--a"});
+ auto opts = v.parse_arguments(cmdstruct);
Assert::AreEqual("b", opts.settings["--a"].c_str());
Assert::AreEqual(size_t{1}, v.command_arguments.size());
Assert::AreEqual("argument", v.command_arguments[0].c_str());
@@ -45,9 +48,13 @@ namespace UnitTest1
TEST_METHOD(create_from_arg_sequence_valued_options2)
{
+ std::array<CommandSwitch, 2> switches = { {{"--a", ""}, {"--c", ""}} };
+ std::array<CommandSetting, 2> settings = { { {"--b", ""}, {"--d", ""}} };
+ CommandStructure cmdstruct = {"", 0, SIZE_MAX, {switches, settings}, nullptr};
+
std::vector<std::string> t = {"--a", "--b=c"};
auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size());
- auto opts = v.check_and_get_optional_command_arguments({"--a", "--c"}, {"--b", "--d"});
+ auto opts = v.parse_arguments(cmdstruct);
Assert::AreEqual("c", opts.settings["--b"].c_str());
Assert::IsTrue(opts.settings.find("--d") == opts.settings.end());
Assert::IsTrue(opts.switches.find("--a") != opts.switches.end());
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
index c59b6f7d1..8b4654aa8 100644
--- a/toolsrc/src/vcpkg/build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -28,10 +28,10 @@ namespace vcpkg::Build::Command
static const std::string OPTION_CHECKS_ONLY = "--checks-only";
- void perform_and_exit(const FullPackageSpec& full_spec,
- const fs::path& port_dir,
- const ParsedArguments& options,
- const VcpkgPaths& paths)
+ void perform_and_exit_ex(const FullPackageSpec& full_spec,
+ const fs::path& port_dir,
+ const ParsedArguments& options,
+ const VcpkgPaths& paths)
{
const PackageSpec& spec = full_spec.package_spec;
if (Util::Sets::contains(options.switches, OPTION_CHECKS_ONLY))
@@ -97,21 +97,32 @@ namespace vcpkg::Build::Command
Checks::exit_success(VCPKG_LINE_INFO);
}
+ static const std::array<CommandSwitch, 1> BUILD_SWITCHES = {{
+ {OPTION_CHECKS_ONLY, "Only run checks, do not rebuild package"},
+ }};
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("build zlib:x64-windows"),
+ 1,
+ 1,
+ {BUILD_SWITCHES, {}},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string EXAMPLE = Help::create_example_string("build zlib:x64-windows");
// Build only takes a single package and all dependencies must already be installed
- args.check_exact_arg_count(1, EXAMPLE);
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
const std::string command_argument = args.command_arguments.at(0);
- const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE);
+ const FullPackageSpec spec =
+ Input::check_and_get_full_package_spec(command_argument, default_triplet, COMMAND_STRUCTURE.example_text);
Input::check_triplet(spec.package_spec.triplet(), paths);
if (!spec.features.empty() && !GlobalState::feature_packages)
{
Checks::exit_with_message(
VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag.");
}
- const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}, {});
- perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths);
+ perform_and_exit_ex(spec, paths.port_dir(spec.package_spec), options, paths);
}
}
diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp
index 410bfcd0d..0df7ec5eb 100644
--- a/toolsrc/src/vcpkg/commands.autocomplete.cpp
+++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp
@@ -121,7 +121,6 @@ namespace vcpkg::Commands::Autocomplete
static constexpr CommandEntry COMMANDS[] = {
CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE},
- CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE},
CommandEntry{"edit", R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE},
CommandEntry{"remove", R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE},
CommandEntry{"integrate", R"###(^integrate(\s+)(\S*)$)###", Integrate::COMMAND_STRUCTURE},
@@ -137,11 +136,16 @@ namespace vcpkg::Commands::Autocomplete
const bool is_option = Strings::case_insensitive_ascii_starts_with(prefix, "-");
if (is_option)
{
- results = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; });
+ results =
+ Util::fmap(command.structure.options.switches, [](const CommandSwitch& s) { return s.name; });
+
+ auto settings = Util::fmap(command.structure.options.settings, [](auto&& s) { return s.name; });
+ results.insert(results.end(), settings.begin(), settings.end());
}
else
{
- results = command.structure.valid_arguments(paths);
+ if (command.structure.valid_arguments != nullptr)
+ results = command.structure.valid_arguments(paths);
}
Util::unstable_keep_if(results, [&](const std::string& s) {
diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp
index 2cc7aabde..82d03db48 100644
--- a/toolsrc/src/vcpkg/commands.buildexternal.cpp
+++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp
@@ -7,17 +7,23 @@
namespace vcpkg::Commands::BuildExternal
{
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"),
+ 2,
+ 2,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string EXAMPLE =
- Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)");
- args.check_exact_arg_count(2, EXAMPLE);
- const FullPackageSpec spec =
- Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE);
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
+
+ const FullPackageSpec spec = Input::check_and_get_full_package_spec(
+ args.command_arguments.at(0), default_triplet, COMMAND_STRUCTURE.example_text);
Input::check_triplet(spec.package_spec.triplet(), paths);
- const ParsedArguments options = args.check_and_get_optional_command_arguments({}, {});
const fs::path port_dir = args.command_arguments.at(1);
- Build::Command::perform_and_exit(spec, port_dir, options, paths);
+ Build::Command::perform_and_exit_ex(spec, port_dir, options, paths);
}
}
diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp
index 64a3169b1..6fd123b7c 100644
--- a/toolsrc/src/vcpkg/commands.cache.cpp
+++ b/toolsrc/src/vcpkg/commands.cache.cpp
@@ -26,13 +26,19 @@ namespace vcpkg::Commands::Cache
return output;
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Strings::format(
+ "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s",
+ Help::create_example_string("cache png")),
+ 0,
+ 1,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Strings::format(
- "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s",
- Help::create_example_string("cache png"));
- args.check_max_arg_count(1, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
const std::vector<BinaryParagraph> binary_paragraphs = read_all_binary_paragraphs(paths);
if (binary_paragraphs.empty())
diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp
index d012ff6dc..dce294004 100644
--- a/toolsrc/src/vcpkg/commands.ci.cpp
+++ b/toolsrc/src/vcpkg/commands.ci.cpp
@@ -58,13 +58,23 @@ namespace vcpkg::Commands::CI
Install::InstallSummary summary;
};
+ static const std::string OPTION_EXCLUDE = "--exclude";
+
+ static const std::array<CommandSetting, 1> CI_SETTINGS = {{
+ {OPTION_EXCLUDE, "Comma separated list of ports to skip"},
+ }};
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("ci x64-windows"),
+ 0,
+ SIZE_MAX,
+ {{}, CI_SETTINGS},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string OPTION_EXCLUDE = "--exclude";
-
- static const std::string EXAMPLE = Help::create_example_string("ci x64-windows");
-
- const ParsedArguments options = args.check_and_get_optional_command_arguments({}, {OPTION_EXCLUDE});
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
const std::vector<std::string> exclusions = Strings::split(options.settings.at(OPTION_EXCLUDE), ",");
const std::set<std::string> exclusions_set(exclusions.cbegin(), exclusions.cend());
diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp
index 5694c1fa6..5d62faeea 100644
--- a/toolsrc/src/vcpkg/commands.contact.cpp
+++ b/toolsrc/src/vcpkg/commands.contact.cpp
@@ -2,6 +2,7 @@
#include <vcpkg/base/system.h>
#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
namespace vcpkg::Commands::Contact
{
@@ -11,10 +12,17 @@ namespace vcpkg::Commands::Contact
return S_EMAIL;
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("contact"),
+ 0,
+ 0,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args)
{
- args.check_exact_arg_count(0);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
System::println("Send an email to %s with any feedback.", email());
Checks::exit_success(VCPKG_LINE_INFO);
diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp
index 9d969ea28..15b10c7ea 100644
--- a/toolsrc/src/vcpkg/commands.cpp
+++ b/toolsrc/src/vcpkg/commands.cpp
@@ -13,7 +13,7 @@ namespace vcpkg::Commands
Span<const PackageNameAndFunction<CommandTypeA>> get_available_commands_type_a()
{
static std::vector<PackageNameAndFunction<CommandTypeA>> t = {
- {"install", &Install::perform_and_exit},
+ PackageNameAndFunction<CommandTypeA>{"install", &Install::perform_and_exit},
{"ci", &CI::perform_and_exit},
{"remove", &Remove::perform_and_exit},
{"build", &Build::Command::perform_and_exit},
diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp
index f1acacd14..c7183d257 100644
--- a/toolsrc/src/vcpkg/commands.create.cpp
+++ b/toolsrc/src/vcpkg/commands.create.cpp
@@ -8,13 +8,18 @@
namespace vcpkg::Commands::Create
{
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string(
+ R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"),
+ 2,
+ 3,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Help::create_example_string(
- R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###");
- args.check_max_arg_count(3, EXAMPLE);
- args.check_min_arg_count(2, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
const std::string port_name = args.command_arguments.at(0);
const std::string url = args.command_arguments.at(1);
diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp
index e5554f7e2..bb300d96e 100644
--- a/toolsrc/src/vcpkg/commands.dependinfo.cpp
+++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp
@@ -9,11 +9,17 @@
namespace vcpkg::Commands::DependInfo
{
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string(R"###(depend-info [pat])###"),
+ 0,
+ 1,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Help::create_example_string(R"###(depend-info [pat])###");
- args.check_max_arg_count(1, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
std::vector<std::unique_ptr<SourceControlFile>> source_control_files =
Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp
index bf618e256..e40e394fb 100644
--- a/toolsrc/src/vcpkg/commands.edit.cpp
+++ b/toolsrc/src/vcpkg/commands.edit.cpp
@@ -34,11 +34,6 @@ namespace vcpkg::Commands::Edit
static const std::string OPTION_BUILDTREES = "--buildtrees";
- static const std::array<std::string, 1> SWITCHES = {
- OPTION_BUILDTREES,
- };
- static const std::array<std::string, 0> SETTINGS;
-
static std::vector<std::string> valid_arguments(const VcpkgPaths& paths)
{
auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports);
@@ -47,12 +42,15 @@ namespace vcpkg::Commands::Edit
[](auto&& pgh) -> std::string { return pgh->core_paragraph->name; });
}
+ static const std::array<CommandSwitch, 1> EDIT_SWITCHES = {{
+ {OPTION_BUILDTREES, "Open editor into the port-specific buildtree subfolder"},
+ }};
+
const CommandStructure COMMAND_STRUCTURE = {
- "edit zlib",
+ Help::create_example_string("edit zlib"),
1,
1,
- SWITCHES,
- SETTINGS,
+ {EDIT_SWITCHES, {}},
&valid_arguments,
};
@@ -63,9 +61,7 @@ namespace vcpkg::Commands::Edit
auto& fs = paths.get_filesystem();
- static const std::string EXAMPLE = Help::create_example_string("edit zlib");
- args.check_exact_arg_count(1, EXAMPLE);
- const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}, {});
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
const std::string port_name = args.command_arguments.at(0);
const fs::path portpath = paths.ports / port_name;
diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp
index c0d26dac2..98b5aced9 100644
--- a/toolsrc/src/vcpkg/commands.env.cpp
+++ b/toolsrc/src/vcpkg/commands.env.cpp
@@ -7,11 +7,17 @@
namespace vcpkg::Commands::Env
{
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("env --triplet x64-windows"),
+ 0,
+ 0,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string EXAMPLE = Help::create_example_string(R"(env --triplet x64-windows)");
- args.check_exact_arg_count(0, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet);
const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path);
diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp
index 51f6b9ad0..a5940ea1e 100644
--- a/toolsrc/src/vcpkg/commands.hash.cpp
+++ b/toolsrc/src/vcpkg/commands.hash.cpp
@@ -28,13 +28,18 @@ namespace vcpkg::Commands::Hash
System::println(hash);
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Strings::format("The argument should be a file path\n%s",
+ Help::create_example_string("hash boost_1_62_0.tar.bz2")),
+ 1,
+ 2,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args)
{
- static const std::string EXAMPLE = Strings::format("The argument should be a file path\n%s",
- Help::create_example_string("hash boost_1_62_0.tar.bz2"));
- args.check_min_arg_count(1, EXAMPLE);
- args.check_max_arg_count(2, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
if (args.command_arguments.size() == 1)
{
diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp
index 5e74b6d94..24394207b 100644
--- a/toolsrc/src/vcpkg/commands.import.cpp
+++ b/toolsrc/src/vcpkg/commands.import.cpp
@@ -92,12 +92,18 @@ namespace vcpkg::Commands::Import
fs.write_contents(control_file_path, Strings::serialize(control_file_data));
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string(
+ R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"),
+ 3,
+ 3,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Help::create_example_string(
- R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)");
- args.check_exact_arg_count(3, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
const fs::path control_file_path(args.command_arguments[0]);
const fs::path include_directory(args.command_arguments[1]);
diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp
index 604bd2c6e..31b9ec722 100644
--- a/toolsrc/src/vcpkg/commands.integrate.cpp
+++ b/toolsrc/src/vcpkg/commands.integrate.cpp
@@ -333,10 +333,6 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
static const std::string PROJECT = "project";
}
- static const std::array<std::string, 0> INSTALL_SWITCHES;
-
- static const std::array<std::string, 0> INSTALL_SETTINGS;
-
static std::vector<std::string> valid_arguments(const VcpkgPaths&)
{
return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT};
@@ -348,18 +344,13 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
INTEGRATE_COMMAND_HELPSTRING),
1,
1,
- INSTALL_SWITCHES,
- INSTALL_SETTINGS,
+ {},
&valid_arguments,
};
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Strings::format("Commands:\n"
- "%s",
- INTEGRATE_COMMAND_HELPSTRING);
- args.check_exact_arg_count(1, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
#if defined(_WIN32)
if (args.command_arguments[0] == Subcommand::INSTALL)
diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp
index 145d4c931..1f2387843 100644
--- a/toolsrc/src/vcpkg/commands.list.cpp
+++ b/toolsrc/src/vcpkg/commands.list.cpp
@@ -24,13 +24,23 @@ namespace vcpkg::Commands::List
}
}
+ static const std::array<CommandSwitch, 1> LIST_SWITCHES = {{
+ {OPTION_FULLDESC, "Do not truncate long text"},
+ }};
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ Strings::format(
+ "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s",
+ Help::create_example_string("list png")),
+ 0,
+ 1,
+ {LIST_SWITCHES, {}},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Strings::format(
- "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s",
- Help::create_example_string("list png"));
- args.check_max_arg_count(1, EXAMPLE);
- const ParsedArguments options = args.check_and_get_optional_command_arguments({OPTION_FULLDESC}, {});
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
const StatusParagraphs status_paragraphs = database_load_check(paths);
std::vector<StatusParagraph*> installed_packages = get_installed_ports(status_paragraphs);
diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp
index b2db966e1..52249187b 100644
--- a/toolsrc/src/vcpkg/commands.owns.cpp
+++ b/toolsrc/src/vcpkg/commands.owns.cpp
@@ -23,13 +23,18 @@ namespace vcpkg::Commands::Owns
}
}
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Strings::format("The argument should be a pattern to search for. %s",
+ Help::create_example_string("owns zlib.dll")),
+ 1,
+ 1,
+ {},
+ nullptr,
+ };
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s",
- Help::create_example_string("owns zlib.dll"));
- args.check_exact_arg_count(1, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
const StatusParagraphs status_db = database_load_check(paths);
search_file(paths, args.command_arguments[0], status_db);
diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp
index 5008f3e8a..0277c8bdb 100644
--- a/toolsrc/src/vcpkg/commands.portsdiff.cpp
+++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp
@@ -114,13 +114,18 @@ namespace vcpkg::Commands::PortsDiff
VCPKG_LINE_INFO, output.output == VALID_COMMIT_OUTPUT, "Invalid commit id %s", git_commit_id);
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Strings::format("The argument should be a branch/tag/hash to checkout.\n%s",
+ Help::create_example_string("portsdiff mybranchname")),
+ 1,
+ 2,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Strings::format("The argument should be a branch/tag/hash to checkout.\n%s",
- Help::create_example_string("portsdiff mybranchname"));
- args.check_min_arg_count(1, EXAMPLE);
- args.check_max_arg_count(2, EXAMPLE);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
const fs::path& git_exe = paths.get_git_exe();
diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp
index ad3046e6d..01291ddfb 100644
--- a/toolsrc/src/vcpkg/commands.search.cpp
+++ b/toolsrc/src/vcpkg/commands.search.cpp
@@ -79,14 +79,24 @@ namespace vcpkg::Commands::Search
}
}
+ static std::array<CommandSwitch, 2> SEARCH_SWITCHES = {{
+ {OPTION_GRAPH, "Open editor into the port-specific buildtree subfolder"},
+ {OPTION_FULLDESC, "Do not truncate long text"},
+ }};
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ Strings::format(
+ "The argument should be a substring to search for, or no argument to display all libraries.\n%s",
+ Help::create_example_string("search png")),
+ 0,
+ 1,
+ {SEARCH_SWITCHES, {}},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string EXAMPLE = Strings::format(
- "The argument should be a substring to search for, or no argument to display all libraries.\n%s",
- Help::create_example_string("search png"));
- args.check_max_arg_count(1, EXAMPLE);
- const ParsedArguments options =
- args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}, {});
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
const bool full_description = Util::Sets::contains(options.switches, OPTION_FULLDESC);
auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp
index e8756a77d..3f44cf1a2 100644
--- a/toolsrc/src/vcpkg/commands.version.cpp
+++ b/toolsrc/src/vcpkg/commands.version.cpp
@@ -2,6 +2,7 @@
#include <vcpkg/base/system.h>
#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
#include <vcpkg/metrics.h>
#define STRINGIFY(...) #__VA_ARGS__
@@ -61,11 +62,17 @@ namespace vcpkg::Commands::Version
}
}
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("version"),
+ 0,
+ 0,
+ {},
+ nullptr,
+ };
void perform_and_exit(const VcpkgCmdArguments& args)
{
- args.check_exact_arg_count(0);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
System::println("Vcpkg package management program version %s\n"
"\n"
diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp
index eb4f5db3c..bbeecefed 100644
--- a/toolsrc/src/vcpkg/export.cpp
+++ b/toolsrc/src/vcpkg/export.cpp
@@ -257,51 +257,57 @@ namespace vcpkg::Export
std::vector<PackageSpec> specs;
};
+ static const std::string OPTION_DRY_RUN = "--dry-run";
+ static const std::string OPTION_RAW = "--raw";
+ static const std::string OPTION_NUGET = "--nuget";
+ static const std::string OPTION_IFW = "--ifw";
+ static const std::string OPTION_ZIP = "--zip";
+ static const std::string OPTION_SEVEN_ZIP = "--7zip";
+ static const std::string OPTION_NUGET_ID = "--nuget-id";
+ static const std::string OPTION_NUGET_VERSION = "--nuget-version";
+ static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url";
+ static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path";
+ static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path";
+ static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path";
+ static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path";
+
+ static const std::array<CommandSwitch, 6> EXPORT_SWITCHES = {{
+ {OPTION_DRY_RUN, "Do not actually export"},
+ {OPTION_RAW, "Export to an uncompressed directory"},
+ {OPTION_NUGET, "Export a NuGet package"},
+ {OPTION_IFW, "Export to an IFW-based installer"},
+ {OPTION_ZIP, "Export to a zip file"},
+ {OPTION_SEVEN_ZIP, "Export to a 7zip (.7z) file"},
+ }};
+ static const std::array<CommandSetting, 7> EXPORT_SETTINGS = {{
+ {OPTION_NUGET_ID, "Specify the id for the exported NuGet package"},
+ {OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"},
+ {OPTION_IFW_REPOSITORY_URL, ""},
+ {OPTION_IFW_PACKAGES_DIR_PATH, ""},
+ {OPTION_IFW_REPOSITORY_DIR_PATH, ""},
+ {OPTION_IFW_CONFIG_FILE_PATH, ""},
+ {OPTION_IFW_INSTALLER_FILE_PATH, ""},
+ }};
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("export zlib zlib:x64-windows boost --nuget"),
+ 0,
+ SIZE_MAX,
+ {EXPORT_SWITCHES, EXPORT_SETTINGS},
+ nullptr,
+ };
+
static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args,
const Triplet& default_triplet)
{
ExportArguments ret;
- static const std::string OPTION_DRY_RUN = "--dry-run";
- static const std::string OPTION_RAW = "--raw";
- static const std::string OPTION_NUGET = "--nuget";
- static const std::string OPTION_IFW = "--ifw";
- static const std::string OPTION_ZIP = "--zip";
- static const std::string OPTION_SEVEN_ZIP = "--7zip";
- static const std::string OPTION_NUGET_ID = "--nuget-id";
- static const std::string OPTION_NUGET_VERSION = "--nuget-version";
- static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url";
- static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path";
- static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path";
- static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path";
- static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path";
+ const auto options = args.parse_arguments(COMMAND_STRUCTURE);
// input sanitization
- static const std::string EXAMPLE = Help::create_example_string("export zlib zlib:x64-windows boost --nuget");
- args.check_min_arg_count(1, EXAMPLE);
-
ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE);
+ return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text);
});
-
- const auto options = args.check_and_get_optional_command_arguments(
- {
- OPTION_DRY_RUN,
- OPTION_RAW,
- OPTION_NUGET,
- OPTION_IFW,
- OPTION_ZIP,
- OPTION_SEVEN_ZIP,
- },
- {
- OPTION_NUGET_ID,
- OPTION_NUGET_VERSION,
- OPTION_IFW_REPOSITORY_URL,
- OPTION_IFW_PACKAGES_DIR_PATH,
- OPTION_IFW_REPOSITORY_DIR_PATH,
- OPTION_IFW_CONFIG_FILE_PATH,
- OPTION_IFW_INSTALLER_FILE_PATH,
- });
ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend();
ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend();
ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend();
@@ -313,7 +319,7 @@ namespace vcpkg::Export
{
System::println(System::Color::error,
"Must provide at least one export type: --raw --nuget --ifw --zip --7zip");
- System::print(EXAMPLE);
+ System::print(COMMAND_STRUCTURE.example_text);
Checks::exit_fail(VCPKG_LINE_INFO);
}
diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp
index 8783833f2..5d4cf99a4 100644
--- a/toolsrc/src/vcpkg/help.cpp
+++ b/toolsrc/src/vcpkg/help.cpp
@@ -91,10 +91,17 @@ namespace vcpkg::Help
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.check_max_arg_count(1);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
if (args.command_arguments.empty())
{
diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp
index b1f722d59..20ffd3164 100644
--- a/toolsrc/src/vcpkg/install.cpp
+++ b/toolsrc/src/vcpkg/install.cpp
@@ -535,13 +535,13 @@ namespace vcpkg::Install
static const std::string OPTION_RECURSE = "--recurse";
static const std::string OPTION_KEEP_GOING = "--keep-going";
- static const std::array<std::string, 5> INSTALL_SWITCHES = {
- OPTION_DRY_RUN,
- OPTION_USE_HEAD_VERSION,
- OPTION_NO_DOWNLOADS,
- OPTION_RECURSE,
- OPTION_KEEP_GOING,
- };
+ static const std::array<CommandSwitch, 5> INSTALL_SWITCHES = {{
+ {OPTION_DRY_RUN, "Do not actually build or install"},
+ {OPTION_USE_HEAD_VERSION, "Install the libraries on the command line using the latest upstream sources"},
+ {OPTION_NO_DOWNLOADS, "Do not download new sources"},
+ {OPTION_RECURSE, "Allow removal of packages as part of installation"},
+ {OPTION_KEEP_GOING, "Continue installing packages on failure"},
+ }};
static const std::array<std::string, 0> INSTALL_SETTINGS;
std::vector<std::string> get_all_port_names(const VcpkgPaths& paths)
@@ -553,22 +553,20 @@ namespace vcpkg::Install
}
const CommandStructure COMMAND_STRUCTURE = {
- "install zlib zlib:x64-windows curl boost",
+ Help::create_example_string("install zlib zlib:x64-windows curl boost"),
1,
SIZE_MAX,
- INSTALL_SWITCHES,
- INSTALL_SETTINGS,
+ {INSTALL_SWITCHES, {}},
&get_all_port_names,
};
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
// input sanitization
- static const std::string EXAMPLE = Help::create_example_string("install zlib zlib:x64-windows curl boost");
- args.check_min_arg_count(1, EXAMPLE);
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE);
+ return Input::check_and_get_full_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text);
});
for (auto&& spec : specs)
@@ -581,8 +579,6 @@ namespace vcpkg::Install
}
}
- const ParsedArguments options = args.check_and_get_optional_command_arguments(
- {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}, {});
const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN);
const bool use_head_version = Util::Sets::contains(options.switches, (OPTION_USE_HEAD_VERSION));
const bool no_downloads = Util::Sets::contains(options.switches, (OPTION_NO_DOWNLOADS));
diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp
index 156f23003..7f40fb16e 100644
--- a/toolsrc/src/vcpkg/remove.cpp
+++ b/toolsrc/src/vcpkg/remove.cpp
@@ -169,14 +169,13 @@ namespace vcpkg::Remove
static const std::string OPTION_DRY_RUN = "--dry-run";
static const std::string OPTION_OUTDATED = "--outdated";
- static const std::array<std::string, 5> SWITCHES = {
- OPTION_PURGE,
- OPTION_NO_PURGE,
- OPTION_RECURSE,
- OPTION_DRY_RUN,
- OPTION_OUTDATED,
- };
- static const std::array<std::string, 0> SETTINGS;
+ static const std::array<CommandSwitch, 5> SWITCHES = {{
+ {OPTION_PURGE, "Remove the cached copy of the package (default)"},
+ {OPTION_NO_PURGE, "Do not remove the cached copy of the package"},
+ {OPTION_RECURSE, "Allow removal of packages not explicitly specified on the command line"},
+ {OPTION_DRY_RUN, "Print the packages to be removed, but do not remove them"},
+ {OPTION_OUTDATED, "Select all packages with versions that do not match the portfiles"},
+ }};
static std::vector<std::string> valid_arguments(const VcpkgPaths& paths)
{
@@ -187,25 +186,26 @@ namespace vcpkg::Remove
}
const CommandStructure COMMAND_STRUCTURE = {
- "remove zlib zlib:x64-windows curl boost",
- 1,
+ Help::create_example_string("remove zlib zlib:x64-windows curl boost"),
+ 0,
SIZE_MAX,
- SWITCHES,
- SETTINGS,
+ {SWITCHES, {}},
&valid_arguments,
};
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost");
- const ParsedArguments options = args.check_and_get_optional_command_arguments(
- {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}, {});
+ const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
StatusParagraphs status_db = database_load_check(paths);
std::vector<PackageSpec> specs;
if (Util::Sets::contains(options.switches, OPTION_OUTDATED))
{
- args.check_exact_arg_count(0, EXAMPLE);
+ if (args.command_arguments.size() != 0)
+ {
+ System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'");
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
specs = Util::fmap(Update::find_outdated_packages(paths, status_db),
[](auto&& outdated) { return outdated.spec; });
@@ -217,9 +217,13 @@ namespace vcpkg::Remove
}
else
{
- args.check_min_arg_count(1, EXAMPLE);
+ if (args.command_arguments.size() < 1)
+ {
+ System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'");
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE);
+ return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text);
});
for (auto&& spec : specs)
@@ -231,7 +235,7 @@ namespace vcpkg::Remove
if (purge_was_passed && no_purge_was_passed)
{
System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge.");
- System::print(EXAMPLE);
+ System::print(COMMAND_STRUCTURE.example_text);
Checks::exit_fail(VCPKG_LINE_INFO);
}
const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed);
diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp
index 7d565251e..61a3f89c5 100644
--- a/toolsrc/src/vcpkg/update.cpp
+++ b/toolsrc/src/vcpkg/update.cpp
@@ -38,10 +38,17 @@ namespace vcpkg::Update
return output;
}
+ const CommandStructure COMMAND_STRUCTURE = {
+ Help::create_example_string("update"),
+ 0,
+ 0,
+ {},
+ nullptr,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- args.check_exact_arg_count(0);
- args.check_and_get_optional_command_arguments({}, {});
+ args.parse_arguments(COMMAND_STRUCTURE);
System::println("Using local portfile versions. To update the local portfiles, use `git pull`.");
const StatusParagraphs status_db = database_load_check(paths);
diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
index 209f6a3f2..35cdbc12e 100644
--- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
+++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
@@ -45,11 +45,8 @@ namespace vcpkg
option_field = new_setting;
}
-#if defined(_WIN32)
- VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv)
-#else
- VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const char* const* const argv)
-#endif
+ VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc,
+ const CommandLineCharType* const* const argv)
{
std::vector<std::string> v;
for (int i = 1; i < argc; ++i)
@@ -158,46 +155,83 @@ namespace vcpkg
return args;
}
- ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments(
- const std::vector<std::string>& valid_switches, const std::vector<std::string>& valid_settings) const
+ ParsedArguments VcpkgCmdArguments::parse_arguments(const CommandStructure& command_structure) const
{
bool failed = false;
ParsedArguments output;
+ const size_t actual_arg_count = command_arguments.size();
+
+ if (command_structure.minimum_arity == command_structure.maximum_arity)
+ {
+ if (actual_arg_count != command_structure.minimum_arity)
+ {
+ System::println(System::Color::error,
+ "Error: '%s' requires %u arguments, but %u were provided.",
+ this->command,
+ command_structure.minimum_arity,
+ actual_arg_count);
+ failed = true;
+ }
+ }
+ else
+ {
+ if (actual_arg_count < command_structure.minimum_arity)
+ {
+ System::println(System::Color::error,
+ "Error: '%s' requires at least %u arguments, but %u were provided",
+ this->command,
+ command_structure.minimum_arity,
+ actual_arg_count);
+ failed = true;
+ }
+ if (actual_arg_count > command_structure.maximum_arity)
+ {
+ System::println(System::Color::error,
+ "Error: '%s' requires at most %u arguments, but %u were provided",
+ this->command,
+ command_structure.maximum_arity,
+ actual_arg_count);
+ failed = true;
+ }
+ }
+
auto options_copy = this->optional_command_arguments;
- for (const std::string& option : valid_switches)
+ for (auto&& option : command_structure.options.switches)
{
- const auto it = options_copy.find(option);
+ const auto it = options_copy.find(option.name);
if (it != options_copy.end())
{
if (it->second.has_value())
{
// Having a string value indicates it was passed like '--a=xyz'
- System::println(System::Color::error, "The option '%s' does not accept an argument.", option);
+ System::println(
+ System::Color::error, "Error: The option '%s' does not accept an argument.", option.name);
failed = true;
}
else
{
- output.switches.insert(option);
+ output.switches.insert(option.name);
options_copy.erase(it);
}
}
}
- for (const std::string& option : valid_settings)
+ for (auto&& option : command_structure.options.settings)
{
- const auto it = options_copy.find(option);
+ const auto it = options_copy.find(option.name);
if (it != options_copy.end())
{
if (!it->second.has_value())
{
// Not having a string value indicates it was passed like '--a'
- System::println(System::Color::error, "The option '%s' must be passed an argument.", option);
+ System::println(
+ System::Color::error, "Error: The option '%s' must be passed an argument.", option.name);
failed = true;
}
else
{
- output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO));
+ output.settings.emplace(option.name, it->second.value_or_exit(VCPKG_LINE_INFO));
options_copy.erase(it);
}
}
@@ -210,83 +244,32 @@ namespace vcpkg
{
System::println(" %s", option.first);
}
- System::println("\nValid options are:", this->command);
- for (auto&& option : valid_switches)
+ System::println();
+ failed = true;
+ }
+
+ if (failed)
+ {
+ if (!command_structure.example_text.empty())
{
- System::println(" %s", option);
+ System::println("%s", command_structure.example_text);
}
- for (auto&& option : valid_settings)
+
+ System::println("Options:", this->command);
+ for (auto&& option : command_structure.options.switches)
{
- System::println(" %s=...", option);
+ System::println(" %-40s %s", option.name, option.short_help_text);
+ }
+ for (auto&& option : command_structure.options.settings)
+ {
+ 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);
}
- if (failed) Checks::exit_fail(VCPKG_LINE_INFO);
return output;
}
-
- void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const
- {
- return check_max_arg_count(expected_arg_count, "");
- }
-
- void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const
- {
- return check_min_arg_count(expected_arg_count, "");
- }
-
- void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const
- {
- return check_exact_arg_count(expected_arg_count, "");
- }
-
- void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const
- {
- const size_t actual_arg_count = command_arguments.size();
- if (actual_arg_count > expected_arg_count)
- {
- System::println(System::Color::error,
- "Error: `%s` requires at most %u arguments, but %u were provided",
- this->command,
- expected_arg_count,
- actual_arg_count);
- System::print(example_text);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const
- {
- const size_t actual_arg_count = command_arguments.size();
- if (actual_arg_count < expected_arg_count)
- {
- System::println(System::Color::error,
- "Error: `%s` requires at least %u arguments, but %u were provided",
- this->command,
- expected_arg_count,
- actual_arg_count);
- System::print(example_text);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
-
- void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count,
- const std::string& example_text) const
- {
- const size_t actual_arg_count = command_arguments.size();
- if (actual_arg_count != expected_arg_count)
- {
- System::println(System::Color::error,
- "Error: `%s` requires %u arguments, but %u were provided",
- this->command,
- expected_arg_count,
- actual_arg_count);
- System::print(example_text);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
}