diff options
| author | Robert Schumacher <roschuma@microsoft.com> | 2017-07-26 13:54:28 -0700 |
|---|---|---|
| committer | Robert Schumacher <roschuma@microsoft.com> | 2017-07-26 14:28:19 -0700 |
| commit | 60296cf16189d4cb048482a1c4476a41d9b18918 (patch) | |
| tree | c8d978a794a028cfe58f61c8a584e07562e66f96 | |
| parent | 661f5f9346a6759747c19c36b625c7679317fb11 (diff) | |
| download | vcpkg-60296cf16189d4cb048482a1c4476a41d9b18918.tar.gz vcpkg-60296cf16189d4cb048482a1c4476a41d9b18918.zip | |
[vcpkg] Add support for single-option arguments.
| -rw-r--r-- | toolsrc/include/VcpkgCmdArguments.h | 17 | ||||
| -rw-r--r-- | toolsrc/src/VcpkgCmdArguments.cpp | 69 | ||||
| -rw-r--r-- | toolsrc/src/tests_arguments.cpp | 23 |
3 files changed, 98 insertions, 11 deletions
diff --git a/toolsrc/include/VcpkgCmdArguments.h b/toolsrc/include/VcpkgCmdArguments.h index 316987100..0de5747b1 100644 --- a/toolsrc/include/VcpkgCmdArguments.h +++ b/toolsrc/include/VcpkgCmdArguments.h @@ -2,11 +2,18 @@ #include "vcpkg_optional.h" #include <memory> +#include <unordered_map> #include <unordered_set> #include <vector> namespace vcpkg { + struct ParsedArguments + { + std::unordered_set<std::string> switches; + std::unordered_map<std::string, std::string> settings; + }; + struct VcpkgCmdArguments { static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); @@ -21,7 +28,13 @@ namespace vcpkg std::string command; std::vector<std::string> command_arguments; std::unordered_set<std::string> check_and_get_optional_command_arguments( - const std::vector<std::string>& valid_options) const; + const std::vector<std::string>& valid_options) const + { + return std::move(check_and_get_optional_command_arguments(valid_options, {}).switches); + } + + 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; @@ -31,6 +44,6 @@ namespace vcpkg void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const; private: - std::unordered_set<std::string> optional_command_arguments; + std::unordered_map<std::string, Optional<std::string>> optional_command_arguments; }; } diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp index 62e0b114c..ebf4c5fc5 100644 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ b/toolsrc/src/VcpkgCmdArguments.cpp @@ -123,7 +123,15 @@ namespace vcpkg continue; } - args.optional_command_arguments.insert(arg); + auto eq_pos = arg.find('='); + if (eq_pos != std::string::npos) + { + args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); + } + else + { + args.optional_command_arguments.emplace(arg, nullopt); + } continue; } @@ -140,30 +148,73 @@ namespace vcpkg return args; } - std::unordered_set<std::string> VcpkgCmdArguments::check_and_get_optional_command_arguments( - const std::vector<std::string>& valid_options) const + ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments( + const std::vector<std::string>& valid_switches, const std::vector<std::string>& valid_settings) const { - std::unordered_set<std::string> output; + bool failed = false; + ParsedArguments output; + auto options_copy = this->optional_command_arguments; - for (const std::string& option : valid_options) + for (const std::string& option : valid_switches) { auto it = options_copy.find(option); if (it != options_copy.end()) { - output.insert(option); - options_copy.erase(it); + 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); + failed = true; + } + else + { + output.switches.insert(option); + options_copy.erase(it); + } + } + } + + for (const std::string& option : valid_settings) + { + auto it = options_copy.find(option); + 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); + failed = true; + } + else + { + output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO)); + options_copy.erase(it); + } } } if (!options_copy.empty()) { System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command); - for (const std::string& option : options_copy) + for (auto&& option : options_copy) + { + System::println(" %s", option.first); + } + System::println("\nValid options are:", this->command); + for (auto&& option : valid_switches) { - System::println(option); + System::println(" %s", option); } + for (auto&& option : valid_settings) + { + System::println(" %s=...", option); + } + 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; } diff --git a/toolsrc/src/tests_arguments.cpp b/toolsrc/src/tests_arguments.cpp index 624fbb910..14b3c3d4f 100644 --- a/toolsrc/src/tests_arguments.cpp +++ b/toolsrc/src/tests_arguments.cpp @@ -31,5 +31,28 @@ namespace UnitTest1 Assert::IsTrue(v.sendmetrics && v.sendmetrics.get());
Assert::IsTrue(v.printmetrics && *v.printmetrics.get());
}
+
+ TEST_METHOD(create_from_arg_sequence_valued_options)
+ {
+ 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"});
+ 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());
+ Assert::AreEqual("command", v.command.c_str());
+ }
+
+ TEST_METHOD(create_from_arg_sequence_valued_options2)
+ {
+ 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"});
+ 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());
+ Assert::IsTrue(opts.settings.find("--c") == opts.settings.end());
+ Assert::AreEqual(size_t{0}, v.command_arguments.size());
+ }
};
}
\ No newline at end of file |
