Bug 1057694 - Command suggestions in mach. r=gps

This commit is contained in:
Ahmed Kachkach
2014-08-26 16:17:00 +02:00
parent 9c580324b2
commit ed94ab0fae
3 changed files with 24 additions and 8 deletions

View File

@@ -29,11 +29,12 @@ class NoCommandError(MachError):
class UnknownCommandError(MachError):
"""Raised when we attempted to execute an unknown command."""
def __init__(self, command, verb):
def __init__(self, command, verb, suggested_commands=None):
MachError.__init__(self)
self.command = command
self.verb = verb
self.suggested_commands = suggested_commands or []
class UnrecognizedArgumentError(MachError):
"""Raised when an unknown argument is passed to mach."""

View File

@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import argparse
import difflib
import sys
from operator import itemgetter
@@ -105,12 +106,21 @@ class CommandAction(argparse.Action):
else:
raise NoCommandError()
handler = self._mach_registrar.command_handlers.get(command)
# Command suggestion
if command not in self._mach_registrar.command_handlers:
# We first try to look for a valid command that is very similar to the given command.
suggested_commands = difflib.get_close_matches(command, self._mach_registrar.command_handlers.keys(), cutoff=0.8)
# If we find more than one matching command, or no command at all, we give command suggestions instead
# (with a lower matching threshold). All commands that start with the given command (for instance: 'mochitest-plain',
# 'mochitest-chrome', etc. for 'mochitest-') are also included.
if len(suggested_commands) != 1:
suggested_commands = set(difflib.get_close_matches(command, self._mach_registrar.command_handlers.keys(), cutoff=0.5))
suggested_commands |= {cmd for cmd in self._mach_registrar.command_handlers if cmd.startswith(command)}
raise UnknownCommandError(command, 'run', suggested_commands)
sys.stderr.write("We're assuming the '%s' command is '%s' and we're executing it for you.\n\n" % (command, suggested_commands[0]))
command = suggested_commands[0]
# FUTURE consider looking for commands with similar names and
# suggest or run them.
if not handler:
raise UnknownCommandError(command, 'run')
handler = self._mach_registrar.command_handlers.get(command)
# FUTURE
# If we wanted to conditionally enable commands based on whether

View File

@@ -78,10 +78,14 @@ Run |mach help| to show a list of commands.
UNKNOWN_COMMAND_ERROR = r'''
It looks like you are trying to %s an unknown mach command: %s
%s
Run |mach help| to show a list of commands.
'''.lstrip()
SUGGESTED_COMMANDS_MESSAGE = r'''
Did you want to %s any of these commands instead: %s?
'''
UNRECOGNIZED_ARGUMENT_ERROR = r'''
It looks like you passed an unrecognized argument into mach.
@@ -388,7 +392,8 @@ To see more help for a specific command, run:
print(NO_COMMAND_ERROR)
return 1
except UnknownCommandError as e:
print(UNKNOWN_COMMAND_ERROR % (e.verb, e.command))
suggestion_message = SUGGESTED_COMMANDS_MESSAGE % (e.verb, ', '.join(e.suggested_commands)) if e.suggested_commands else ''
print(UNKNOWN_COMMAND_ERROR % (e.verb, e.command, suggestion_message))
return 1
except UnrecognizedArgumentError as e:
print(UNRECOGNIZED_ARGUMENT_ERROR % (e.command,