Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Print similar commands on the unknown command error (#5725)
* Print similar commands on the unknown command error

* Move back the python2 warning

* Update output

* Add a dot to the message

* Add a test for the helpful unknown error message
  • Loading branch information
Minimonium authored and lasote committed Sep 11, 2019
1 parent 6b5fa03 commit e6e631e
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
31 changes: 30 additions & 1 deletion conans/client/command.py
Expand Up @@ -6,6 +6,7 @@
import argparse
import six
from argparse import ArgumentError
from difflib import get_close_matches

from conans import __version__ as client_version
from conans.client.cmd.uploader import UPLOAD_POLICY_FORCE, \
Expand Down Expand Up @@ -1840,6 +1841,25 @@ def _commands(self):
result[method_name] = method
return result

def _print_similar(self, command):
""" looks for a similar commands and prints them if found
"""
matches = get_close_matches(
word=command, possibilities=self._commands().keys(), n=5, cutoff=0.75)

if len(matches) == 0:
return

if len(matches) > 1:
self._out.writeln("The most similar commands are")
else:
self._out.writeln("The most similar command is")

for match in matches:
self._out.writeln(" %s" % match)

self._out.writeln("")

def _warn_python2(self):
if six.PY2:
self._out.writeln("")
Expand All @@ -1863,10 +1883,19 @@ def run(self, *args):
if command in ["-v", "--version"]:
self._out.success("Conan version %s" % client_version)
return False

self._warn_python2()
self._show_help()

if command in ["-h", "--help"]:
self._show_help()
return False

self._out.writeln(
"'%s' is not a Conan command. See 'conan --help'." % command)
self._out.writeln("")

self._print_similar(command)

raise ConanException("Unknown command %s" % str(exc))
except IndexError: # No parameters
self._show_help()
Expand Down
47 changes: 47 additions & 0 deletions conans/test/functional/command/help_test.py
@@ -1,5 +1,6 @@
import sys
import unittest
import textwrap

from six import StringIO

Expand All @@ -20,6 +21,52 @@ def help_test(self):
client.run("some_unknown_command123", assert_error=True)
self.assertIn("ERROR: Unknown command 'some_unknown_command123'", client.out)

def unknown_command_test(self):
client = TestClient()

client.run("some_unknown_command123", assert_error=True)
expected_output = textwrap.dedent(
"""\
'some_unknown_command123' is not a Conan command. See 'conan --help'.
ERROR: Unknown command 'some_unknown_command123'
""")
self.assertIn(
expected_output, client.out)

# Check for a single suggestion
client.run("instal", assert_error=True)

expected_output = textwrap.dedent(
"""\
'instal' is not a Conan command. See 'conan --help'.
The most similar command is
install
ERROR: Unknown command 'instal'
""")
self.assertIn(
expected_output, client.out)

# Check for multiple suggestions
client.run("remoe", assert_error=True)
self.assertIn(
"", client.out)

expected_output = textwrap.dedent(
"""\
'remoe' is not a Conan command. See 'conan --help'.
The most similar commands are
remove
remote
ERROR: Unknown command 'remoe'
""")
self.assertIn(
expected_output, client.out)

def help_cmd_test(self):
client = TestClient()
try:
Expand Down

0 comments on commit e6e631e

Please sign in to comment.