mirror of
https://github.com/cemu-project/vcpkg.git
synced 2025-02-24 03:27:12 +01:00
[vcpkg] Add support for single-option arguments.
This commit is contained in:
parent
661f5f9346
commit
60296cf161
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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(option);
|
||||
System::println(" %s", option.first);
|
||||
}
|
||||
System::println("\nValid options are:", this->command);
|
||||
for (auto&& option : valid_switches)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user