From d6e80b78353701bba834ede58cc641fd21abe432 Mon Sep 17 00:00:00 2001 From: nvbn Date: Wed, 29 Jul 2015 16:09:26 +0300 Subject: [PATCH] #298 Suggest more than one result in *_no_command rules --- tests/rules/test_brew_unknown_command.py | 4 ++-- tests/rules/test_docker_not_command.py | 6 +++--- tests/rules/test_git_not_command.py | 6 +++--- tests/rules/test_gulp_not_task.py | 2 +- tests/rules/test_heroku_not_command.py | 4 ++-- tests/rules/test_lein_not_task.py | 3 ++- tests/rules/test_no_command.py | 4 ++-- tests/rules/test_tsuru_not_command.py | 14 +++++++------- thefuck/rules/brew_unknown_command.py | 12 +++--------- thefuck/rules/docker_not_command.py | 5 ++--- thefuck/rules/git_not_command.py | 10 ++++------ thefuck/rules/gulp_not_task.py | 5 ++--- thefuck/rules/heroku_not_command.py | 5 ++--- thefuck/rules/lein_not_task.py | 8 ++++---- thefuck/rules/no_command.py | 7 ++++--- thefuck/rules/tsuru_not_command.py | 7 +++---- thefuck/utils.py | 7 +++++++ 17 files changed, 53 insertions(+), 56 deletions(-) diff --git a/tests/rules/test_brew_unknown_command.py b/tests/rules/test_brew_unknown_command.py index d9a79c30..b33f7409 100644 --- a/tests/rules/test_brew_unknown_command.py +++ b/tests/rules/test_brew_unknown_command.py @@ -22,7 +22,7 @@ def test_match(brew_unknown_cmd): def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2): assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd), - None) == 'brew list' + None) == ['brew list', 'brew install', 'brew uninstall'] assert get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2), - None) == 'brew install' + None) == ['brew install', 'brew uninstall', 'brew list'] diff --git a/tests/rules/test_docker_not_command.py b/tests/rules/test_docker_not_command.py index 1e7b0061..5e9a7811 100644 --- a/tests/rules/test_docker_not_command.py +++ b/tests/rules/test_docker_not_command.py @@ -122,8 +122,8 @@ def test_not_match(script, stderr): @pytest.mark.usefixtures('docker_help') @pytest.mark.parametrize('wrong, fixed', [ - ('pes', 'ps'), - ('tags', 'tag')]) + ('pes', ['ps', 'push', 'pause']), + ('tags', ['tag', 'stats', 'images'])]) def test_get_new_command(wrong, fixed): command = Command('docker {}'.format(wrong), stderr=stderr(wrong)) - assert get_new_command(command, None) == 'docker {}'.format(fixed) + assert get_new_command(command, None) == ['docker {}'.format(x) for x in fixed] diff --git a/tests/rules/test_git_not_command.py b/tests/rules/test_git_not_command.py index 76f5817b..0bff9803 100644 --- a/tests/rules/test_git_not_command.py +++ b/tests/rules/test_git_not_command.py @@ -50,8 +50,8 @@ def test_match(git_not_command, git_command, git_not_command_one_of_this): def test_get_new_command(git_not_command, git_not_command_one_of_this, git_not_command_closest): assert get_new_command(Command('git brnch', stderr=git_not_command), None) \ - == 'git branch' + == ['git branch'] assert get_new_command(Command('git st', stderr=git_not_command_one_of_this), - None) == 'git status' + None) == ['git stats', 'git stash', 'git stage'] assert get_new_command(Command('git tags', stderr=git_not_command_closest), - None) == 'git tag' + None) == ['git tag', 'git stage'] diff --git a/tests/rules/test_gulp_not_task.py b/tests/rules/test_gulp_not_task.py index f5fa09b0..980e0f73 100644 --- a/tests/rules/test_gulp_not_task.py +++ b/tests/rules/test_gulp_not_task.py @@ -25,4 +25,4 @@ def test_get_new_command(mocker): mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[ 'serve', 'build', 'default']) command = Command('gulp srve', stdout('srve')) - assert get_new_command(command, None) == 'gulp serve' + assert get_new_command(command, None) == ['gulp serve', 'gulp default'] diff --git a/tests/rules/test_heroku_not_command.py b/tests/rules/test_heroku_not_command.py index acbda7ae..c1f5a761 100644 --- a/tests/rules/test_heroku_not_command.py +++ b/tests/rules/test_heroku_not_command.py @@ -27,8 +27,8 @@ def test_not_match(script, stderr): @pytest.mark.parametrize('cmd, result', [ - ('log', 'heroku logs'), - ('pge', 'heroku pg')]) + ('log', ['heroku logs', 'heroku pg']), + ('pge', ['heroku pg', 'heroku logs'])]) def test_get_new_command(cmd, result): command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)) assert get_new_command(command, None) == result diff --git a/tests/rules/test_lein_not_task.py b/tests/rules/test_lein_not_task.py index 35975b82..9eef9b44 100644 --- a/tests/rules/test_lein_not_task.py +++ b/tests/rules/test_lein_not_task.py @@ -9,6 +9,7 @@ def is_not_task(): Did you mean this? repl + jar ''' @@ -19,4 +20,4 @@ def test_match(is_not_task): def test_get_new_command(is_not_task): assert get_new_command(Mock(script='lein rpl --help', stderr=is_not_task), - None) == 'lein repl --help' + None) == ['lein repl --help', 'lein jar --help'] diff --git a/tests/rules/test_no_command.py b/tests/rules/test_no_command.py index 6159d76b..a44c1fd9 100644 --- a/tests/rules/test_no_command.py +++ b/tests/rules/test_no_command.py @@ -22,8 +22,8 @@ def test_get_new_command(): assert get_new_command( Command(stderr='vom: not found', script='vom file.py'), - None) == 'vim file.py' + None) == ['vim file.py'] assert get_new_command( Command(stderr='fucck: not found', script='fucck'), - Command) == 'fsck' + Command) == ['fsck'] diff --git a/tests/rules/test_tsuru_not_command.py b/tests/rules/test_tsuru_not_command.py index d8d8c99a..80baf7e4 100644 --- a/tests/rules/test_tsuru_not_command.py +++ b/tests/rules/test_tsuru_not_command.py @@ -61,30 +61,30 @@ def test_not_match(command): assert not match(command, None) -@pytest.mark.parametrize('command, new_command', [ +@pytest.mark.parametrize('command, new_commands', [ (Command('tsuru log', stderr=( 'tsuru: "log" is not a tsuru command. See "tsuru help".\n' '\nDid you mean?\n' '\tapp-log\n' '\tlogin\n' '\tlogout\n' - )), 'tsuru login'), + )), ['tsuru login', 'tsuru logout', 'tsuru app-log']), (Command('tsuru app-l', stderr=( 'tsuru: "app-l" is not a tsuru command. See "tsuru help".\n' '\nDid you mean?\n' '\tapp-list\n' '\tapp-log\n' - )), 'tsuru app-log'), + )), ['tsuru app-log', 'tsuru app-list']), (Command('tsuru user-list', stderr=( 'tsuru: "user-list" is not a tsuru command. See "tsuru help".\n' '\nDid you mean?\n' '\tteam-user-list\n' - )), 'tsuru team-user-list'), + )), ['tsuru team-user-list']), (Command('tsuru targetlist', stderr=( 'tsuru: "targetlist" is not a tsuru command. See "tsuru help".\n' '\nDid you mean?\n' '\ttarget-list\n' - )), 'tsuru target-list'), + )), ['tsuru target-list']), ]) -def test_get_new_command(command, new_command): - assert get_new_command(command, None) == new_command +def test_get_new_command(command, new_commands): + assert get_new_command(command, None) == new_commands diff --git a/thefuck/rules/brew_unknown_command.py b/thefuck/rules/brew_unknown_command.py index 0a2402f3..9b80f887 100644 --- a/thefuck/rules/brew_unknown_command.py +++ b/thefuck/rules/brew_unknown_command.py @@ -1,7 +1,7 @@ import os import re import subprocess -from thefuck.utils import get_closest, replace_argument +from thefuck.utils import get_closest, replace_command BREW_CMD_PATH = '/Library/Homebrew/cmd' TAP_PATH = '/Library/Taps' @@ -77,10 +77,6 @@ if brew_path_prefix: pass -def _get_similar_command(command): - return get_closest(command, brew_commands) - - def match(command, settings): is_proper_command = ('brew' in command.script and 'Unknown command' in command.stderr) @@ -89,7 +85,7 @@ def match(command, settings): if is_proper_command: broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', command.stderr)[0] - has_possible_commands = bool(_get_similar_command(broken_cmd)) + has_possible_commands = bool(get_closest(broken_cmd, brew_commands)) return has_possible_commands @@ -97,6 +93,4 @@ def match(command, settings): def get_new_command(command, settings): broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', command.stderr)[0] - new_cmd = _get_similar_command(broken_cmd) - - return replace_argument(command.script, broken_cmd, new_cmd) + return replace_command(command, broken_cmd, brew_commands) diff --git a/thefuck/rules/docker_not_command.py b/thefuck/rules/docker_not_command.py index 4b473bbf..d866ee27 100644 --- a/thefuck/rules/docker_not_command.py +++ b/thefuck/rules/docker_not_command.py @@ -1,7 +1,7 @@ from itertools import dropwhile, takewhile, islice import re import subprocess -from thefuck.utils import get_closest, sudo_support, replace_argument +from thefuck.utils import get_closest, sudo_support, replace_argument, replace_command @sudo_support @@ -23,5 +23,4 @@ def get_docker_commands(): def get_new_command(command, settings): wrong_command = re.findall( r"docker: '(\w+)' is not a docker command.", command.stderr)[0] - fixed_command = get_closest(wrong_command, get_docker_commands()) - return replace_argument(command.script, wrong_command, fixed_command) + return replace_command(command, wrong_command, get_docker_commands()) diff --git a/thefuck/rules/git_not_command.py b/thefuck/rules/git_not_command.py index 033e0095..65df0a97 100644 --- a/thefuck/rules/git_not_command.py +++ b/thefuck/rules/git_not_command.py @@ -1,6 +1,6 @@ import re -from thefuck.utils import (get_closest, git_support, replace_argument, - get_all_matched_commands) +from thefuck.utils import (git_support, + get_all_matched_commands, replace_command) @git_support @@ -13,7 +13,5 @@ def match(command, settings): def get_new_command(command, settings): broken_cmd = re.findall(r"git: '([^']*)' is not a git command", command.stderr)[0] - new_cmd = get_closest(broken_cmd, - get_all_matched_commands(command.stderr)) - return replace_argument(command.script, broken_cmd, new_cmd) - + matched = get_all_matched_commands(command.stderr) + return replace_command(command, broken_cmd, matched) diff --git a/thefuck/rules/gulp_not_task.py b/thefuck/rules/gulp_not_task.py index c7ecc99b..c1a548c1 100644 --- a/thefuck/rules/gulp_not_task.py +++ b/thefuck/rules/gulp_not_task.py @@ -1,6 +1,6 @@ import re import subprocess -from thefuck.utils import get_closest, replace_argument +from thefuck.utils import replace_command def match(command, script): @@ -18,5 +18,4 @@ def get_gulp_tasks(): def get_new_command(command, script): wrong_task = re.findall(r"Task '(\w+)' is not in your gulpfile", command.stdout)[0] - fixed_task = get_closest(wrong_task, get_gulp_tasks()) - return replace_argument(command.script, wrong_task, fixed_task) + return replace_command(command, wrong_task, get_gulp_tasks()) diff --git a/thefuck/rules/heroku_not_command.py b/thefuck/rules/heroku_not_command.py index 04600b31..87360bc8 100644 --- a/thefuck/rules/heroku_not_command.py +++ b/thefuck/rules/heroku_not_command.py @@ -1,5 +1,5 @@ import re -from thefuck.utils import get_closest, replace_argument +from thefuck.utils import replace_command def match(command, settings): @@ -16,5 +16,4 @@ def _get_suggests(stderr): def get_new_command(command, settings): wrong = re.findall(r'`(\w+)` is not a heroku command', command.stderr)[0] - correct = get_closest(wrong, _get_suggests(command.stderr)) - return replace_argument(command.script, wrong, correct) + return replace_command(command, wrong, _get_suggests(command.stderr)) diff --git a/thefuck/rules/lein_not_task.py b/thefuck/rules/lein_not_task.py index 6ecdd38b..34e46fe3 100644 --- a/thefuck/rules/lein_not_task.py +++ b/thefuck/rules/lein_not_task.py @@ -1,5 +1,6 @@ import re -from thefuck.utils import sudo_support, replace_argument +from thefuck.utils import sudo_support,\ + replace_command, get_all_matched_commands @sudo_support @@ -13,6 +14,5 @@ def match(command, settings): def get_new_command(command, settings): broken_cmd = re.findall(r"'([^']*)' is not a task", command.stderr)[0] - new_cmd = re.findall(r'Did you mean this\?\n\s*([^\n]*)', - command.stderr)[0] - return replace_argument(command.script, broken_cmd, new_cmd) + new_cmds = get_all_matched_commands(command.stderr, 'Did you mean this?') + return replace_command(command, broken_cmd, new_cmds) diff --git a/thefuck/rules/no_command.py b/thefuck/rules/no_command.py index f414ba3b..a8258ce0 100644 --- a/thefuck/rules/no_command.py +++ b/thefuck/rules/no_command.py @@ -1,5 +1,5 @@ from difflib import get_close_matches -from thefuck.utils import sudo_support, get_all_executables, get_closest +from thefuck.utils import sudo_support, get_all_executables @sudo_support @@ -12,8 +12,9 @@ def match(command, settings): @sudo_support def get_new_command(command, settings): old_command = command.script.split(' ')[0] - new_command = get_closest(old_command, get_all_executables()) - return ' '.join([new_command] + command.script.split(' ')[1:]) + new_cmds = get_close_matches(old_command, get_all_executables(), cutoff=0.1) + return [' '.join([new_command] + command.script.split(' ')[1:]) + for new_command in new_cmds] priority = 3000 diff --git a/thefuck/rules/tsuru_not_command.py b/thefuck/rules/tsuru_not_command.py index 29930a5a..1115a3ae 100644 --- a/thefuck/rules/tsuru_not_command.py +++ b/thefuck/rules/tsuru_not_command.py @@ -1,6 +1,6 @@ import re from thefuck.utils import (get_closest, replace_argument, - get_all_matched_commands) + get_all_matched_commands, replace_command) def match(command, settings): @@ -12,7 +12,6 @@ def match(command, settings): def get_new_command(command, settings): broken_cmd = re.findall(r'tsuru: "([^"]*)" is not a tsuru command', command.stderr)[0] - new_cmd = get_closest(broken_cmd, - get_all_matched_commands(command.stderr)) - return replace_argument(command.script, broken_cmd, new_cmd) + return replace_command(command, broken_cmd, + get_all_matched_commands(command.stderr)) diff --git a/thefuck/utils.py b/thefuck/utils.py index db579fe9..dde7c906 100644 --- a/thefuck/utils.py +++ b/thefuck/utils.py @@ -178,3 +178,10 @@ def get_all_matched_commands(stderr, separator='Did you mean'): should_yield = True elif should_yield and line: yield line.strip() + + +def replace_command(command, broken, matched): + """Helper for *_no_command rules.""" + new_cmds = get_close_matches(broken, matched, cutoff=0.1) + return [replace_argument(command.script, broken, new_cmd.strip()) + for new_cmd in new_cmds]