Skip to content

Commit

Permalink
ceph.in: print all matched commands if arg missing
Browse files Browse the repository at this point in the history
so if only a single command matches, the "Invalid command:" error
message is
printed, otherwise, the top 10 matched candidate commands are printed.

Fixes: http://tracker.ceph.com/issues/22344
Signed-off-by: Kefu Chai <kchai@redhat.com>
  • Loading branch information
tchaikov committed Jan 2, 2018
1 parent 24bc418 commit d61df34
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 8 deletions.
30 changes: 22 additions & 8 deletions src/pybind/ceph_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ class ArgumentFormat(ArgumentError):
pass


class ArgumentMissing(ArgumentError):
"""
Argument value missing in a command
"""
pass


class ArgumentValid(ArgumentError):
"""
Argument value is otherwise invalid (doesn't match choices, for instance)
Expand Down Expand Up @@ -944,7 +951,7 @@ def validate(args, signature, flags=0, partial=False):
return d
# special-case the "0 expected 1" case
if desc.numseen == 0 and desc.n == 1:
raise ArgumentNumber(
raise ArgumentMissing(
'missing required parameter {0}'.format(desc)
)
raise ArgumentNumber(
Expand Down Expand Up @@ -1042,6 +1049,7 @@ def validate_command(sigdict, args, verbose=False):
print("bestcmds_sorted: ", file=sys.stderr)
pprint.PrettyPrinter(stream=sys.stderr).pprint(bestcmds_sorted)

e = None
# for everything in bestcmds, look for a true match
for cmdsig in bestcmds_sorted:
for cmd in cmdsig.values():
Expand All @@ -1054,6 +1062,10 @@ def validate_command(sigdict, args, verbose=False):
# ignore prefix mismatches; we just haven't found
# the right command yet
pass
except ArgumentMissing as e:
if len(bestcmds) == 1:
found = cmd
break
except ArgumentTooFew:
# It looked like this matched the beginning, but it
# didn't have enough args supplied. If we're out of
Expand All @@ -1066,22 +1078,24 @@ def validate_command(sigdict, args, verbose=False):
# Solid mismatch on an arg (type, range, etc.)
# Stop now, because we have the right command but
# some other input is invalid
print("Invalid command: ", e, file=sys.stderr)
print(concise_sig(sig), ': ', cmd['help'], file=sys.stderr)
return {}
if found:
found = cmd
break
if found or e:
break

if not found:
if found:
if not valid_dict:
print("Invalid command:", e, file=sys.stderr)
print(concise_sig(sig), ': ', cmd['help'], file=sys.stderr)
return valid_dict
else:
bestcmds = bestcmds[:10]
print('no valid command found; {0} closest matches:'.format(len(bestcmds)), file=sys.stderr)
for cmdsig in bestcmds:
for (cmdtag, cmd) in cmdsig.items():
print(concise_sig(cmd['sig']), file=sys.stderr)
return None

return valid_dict


def find_cmd_target(childargs):
"""
Expand Down
27 changes: 27 additions & 0 deletions src/test/pybind/test_ceph_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

import os
import re
import sys
import json
from StringIO import StringIO

def get_command_descriptions(what):
CEPH_BIN = os.environ['CEPH_BIN']
Expand Down Expand Up @@ -88,6 +90,20 @@ def check_no_arg(self, prefix, command):
command,
'toomany']))

def capture_output(self, args, stdout=None, stderr=None):
if stdout:
stdout = StringIO()
sys.stdout = stdout
if stderr:
stderr = StringIO()
sys.stderr = stderr
ret = validate_command(sigdict, args)
if stdout:
stdout = stdout.getvalue().strip()
if stderr:
stderr = stderr.getvalue().strip()
return ret, stdout, stderr


class TestBasic:

Expand Down Expand Up @@ -180,6 +196,17 @@ def test_debug(self):
assert_equal({}, validate_command(sigdict, ['pg', 'debug',
'invalid']))

def test_pg_missing_args_output(self):
ret, _, stderr = self.capture_output(['pg'], stderr=True)
assert_equal(None, ret)
assert_regexp_matches(stderr, re.compile('no valid command found.* closest matches'))

def test_pg_wrong_arg_output(self):
ret, _, stderr = self.capture_output(['pg', 'map', 'bad-pgid'],
stderr=True)
assert_equal({}, ret)
assert_in("Invalid command", stderr)


class TestAuth(TestArgparse):

Expand Down

0 comments on commit d61df34

Please sign in to comment.