did you mean?

Signed-off-by: Kenneth Reitz <me@kennethreitz.org>
This commit is contained in:
2017-09-25 13:01:26 -04:00
parent 5c365ce7c6
commit 23ec2a0c16
2 changed files with 59 additions and 1 deletions
+2 -1
View File
@@ -30,6 +30,7 @@ from pipreqs import pipreqs
from blindspin import spinner
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from pip.req.req_file import parse_requirements
from click_didyoumean import DYMCommandCollection
from .project import Project
from .utils import (
@@ -2311,7 +2312,7 @@ cli.add_command(check)
cli.add_command(shell)
cli.add_command(run)
cli = DYMCommandCollection(sources=[cli])
if __name__ == '__main__':
cli()
+57
View File
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
"""
Extension for the python ``click`` module to provide
a group with a git-like *did-you-mean* feature.
"""
import click
import difflib
__version__ = "0.0.3"
class DYMMixin(object): # pylint: disable=too-few-public-methods
"""
Mixin class for click MultiCommand inherited classes
to provide git-like *did-you-mean* functionality when
a certain command is not registered.
"""
def __init__(self, *args, **kwargs):
self.max_suggestions = kwargs.pop("max_suggestions", 3)
self.cutoff = kwargs.pop("cutoff", 0.5)
super(DYMMixin, self).__init__(*args, **kwargs)
def resolve_command(self, ctx, args):
"""
Overrides clicks ``resolve_command`` method
and appends *Did you mean ...* suggestions
to the raised exception message.
"""
try:
return super(DYMMixin, self).resolve_command(ctx, args)
except click.exceptions.UsageError as error:
error_msg = str(error)
original_cmd_name = click.utils.make_str(args[0])
matches = difflib.get_close_matches(original_cmd_name,
self.list_commands(ctx), self.max_suggestions, self.cutoff)
if matches:
error_msg += '\n\nDid you mean one of these?\n %s' % '\n '.join(matches) # pylint: disable=line-too-long
raise click.exceptions.UsageError(error_msg, error.ctx)
class DYMGroup(DYMMixin, click.Group): # pylint: disable=too-many-public-methods
"""
click Group to provide git-like
*did-you-mean* functionality when a certain
command is not found in the group.
"""
class DYMCommandCollection(DYMMixin, click.CommandCollection): # pylint: disable=too-many-public-methods
"""
click CommandCollection to provide git-like
*did-you-mean* functionality when a certain
command is not found in the group.
"""