From cc840de22c6359f40768b339f16b97a6a343b064 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 11 Oct 2019 15:27:16 -0700 Subject: [PATCH] rgw-admin: cmdline, dump expected commands on error Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_admin.cc | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index dc88e7c41dbd6..2933552b1de7a 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -412,6 +412,7 @@ public: private: struct Node { map next; + set expected; /* separate un-normalized list */ std::any opt; }; @@ -440,6 +441,13 @@ private: } } + bool gen_next_expected(Node *node, vector *expected, bool ret) { + for (auto& next_cmd : node->expected) { + expected->push_back(next_cmd); + } + return ret; + } + Node root; public: @@ -469,6 +477,9 @@ public: for (auto& word : words) { auto norm = normalize_alias(word); auto parent = node; + + node->expected.insert(word); + node = &node->next[norm]; if (norm == "[*]") { /* optional param at the end */ @@ -485,7 +496,8 @@ public: bool find_command(Container& args, std::any *opt_cmd, vector *extra_args, - string *error) { + string *error, + vector *expected) { auto node = &cmd_root; std::optional found_opt; @@ -496,8 +508,8 @@ public: if (iter == node->next.end()) { iter = node->next.find("*"); if (iter == node->next.end()) { - *error = string("unrecognized arg ") + arg; - return false; + *error = string("ERROR: Unrecognized argument: '") + arg + "'"; + return gen_next_expected(node, expected, false); } extra_args->push_back(arg); if (!found_opt) { @@ -510,8 +522,8 @@ public: *opt_cmd = found_opt.value_or(node->opt); if (!opt_cmd->has_value()) { - *error ="no command"; - return false; + *error ="ERROR: Unknown command"; + return gen_next_expected(node, expected, false); } return true; @@ -3028,11 +3040,21 @@ int main(int argc, const char **argv) } else { std::vector extra_args; + std::vector expected; std::any _opt_cmd; - if (!cmd.find_command(args, &_opt_cmd, &extra_args, &err)) { - cerr << err << std::endl; + if (!cmd.find_command(args, &_opt_cmd, &extra_args, &err, &expected)) { + if (!expected.empty()) { + cerr << err << std::endl; + cerr << "Expected one of the following:" << std::endl; + for (auto& exp : expected) { + if (exp == "*" || exp == "[*]") { + continue; + } + cerr << " " << exp << std::endl; + } + } exit(1); } -- 2.39.5