1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-01-31 10:11:14 +00:00

#298 Suggest more than one result in *_no_command rules

This commit is contained in:
nvbn 2015-07-29 16:09:26 +03:00
parent 4bc1cc7849
commit d6e80b7835
17 changed files with 53 additions and 56 deletions

View File

@ -22,7 +22,7 @@ def test_match(brew_unknown_cmd):
def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2): def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2):
assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd), 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), assert get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2),
None) == 'brew install' None) == ['brew install', 'brew uninstall', 'brew list']

View File

@ -122,8 +122,8 @@ def test_not_match(script, stderr):
@pytest.mark.usefixtures('docker_help') @pytest.mark.usefixtures('docker_help')
@pytest.mark.parametrize('wrong, fixed', [ @pytest.mark.parametrize('wrong, fixed', [
('pes', 'ps'), ('pes', ['ps', 'push', 'pause']),
('tags', 'tag')]) ('tags', ['tag', 'stats', 'images'])])
def test_get_new_command(wrong, fixed): def test_get_new_command(wrong, fixed):
command = Command('docker {}'.format(wrong), stderr=stderr(wrong)) 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]

View File

@ -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, def test_get_new_command(git_not_command, git_not_command_one_of_this,
git_not_command_closest): git_not_command_closest):
assert get_new_command(Command('git brnch', stderr=git_not_command), None) \ 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), 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), assert get_new_command(Command('git tags', stderr=git_not_command_closest),
None) == 'git tag' None) == ['git tag', 'git stage']

View File

@ -25,4 +25,4 @@ def test_get_new_command(mocker):
mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[ mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[
'serve', 'build', 'default']) 'serve', 'build', 'default'])
command = Command('gulp srve', stdout('srve')) command = Command('gulp srve', stdout('srve'))
assert get_new_command(command, None) == 'gulp serve' assert get_new_command(command, None) == ['gulp serve', 'gulp default']

View File

@ -27,8 +27,8 @@ def test_not_match(script, stderr):
@pytest.mark.parametrize('cmd, result', [ @pytest.mark.parametrize('cmd, result', [
('log', 'heroku logs'), ('log', ['heroku logs', 'heroku pg']),
('pge', 'heroku pg')]) ('pge', ['heroku pg', 'heroku logs'])])
def test_get_new_command(cmd, result): def test_get_new_command(cmd, result):
command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)) command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd))
assert get_new_command(command, None) == result assert get_new_command(command, None) == result

View File

@ -9,6 +9,7 @@ def is_not_task():
Did you mean this? Did you mean this?
repl repl
jar
''' '''
@ -19,4 +20,4 @@ def test_match(is_not_task):
def test_get_new_command(is_not_task): def test_get_new_command(is_not_task):
assert get_new_command(Mock(script='lein rpl --help', stderr=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']

View File

@ -22,8 +22,8 @@ def test_get_new_command():
assert get_new_command( assert get_new_command(
Command(stderr='vom: not found', Command(stderr='vom: not found',
script='vom file.py'), script='vom file.py'),
None) == 'vim file.py' None) == ['vim file.py']
assert get_new_command( assert get_new_command(
Command(stderr='fucck: not found', Command(stderr='fucck: not found',
script='fucck'), script='fucck'),
Command) == 'fsck' Command) == ['fsck']

View File

@ -61,30 +61,30 @@ def test_not_match(command):
assert not match(command, None) assert not match(command, None)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_commands', [
(Command('tsuru log', stderr=( (Command('tsuru log', stderr=(
'tsuru: "log" is not a tsuru command. See "tsuru help".\n' 'tsuru: "log" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n' '\nDid you mean?\n'
'\tapp-log\n' '\tapp-log\n'
'\tlogin\n' '\tlogin\n'
'\tlogout\n' '\tlogout\n'
)), 'tsuru login'), )), ['tsuru login', 'tsuru logout', 'tsuru app-log']),
(Command('tsuru app-l', stderr=( (Command('tsuru app-l', stderr=(
'tsuru: "app-l" is not a tsuru command. See "tsuru help".\n' 'tsuru: "app-l" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n' '\nDid you mean?\n'
'\tapp-list\n' '\tapp-list\n'
'\tapp-log\n' '\tapp-log\n'
)), 'tsuru app-log'), )), ['tsuru app-log', 'tsuru app-list']),
(Command('tsuru user-list', stderr=( (Command('tsuru user-list', stderr=(
'tsuru: "user-list" is not a tsuru command. See "tsuru help".\n' 'tsuru: "user-list" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n' '\nDid you mean?\n'
'\tteam-user-list\n' '\tteam-user-list\n'
)), 'tsuru team-user-list'), )), ['tsuru team-user-list']),
(Command('tsuru targetlist', stderr=( (Command('tsuru targetlist', stderr=(
'tsuru: "targetlist" is not a tsuru command. See "tsuru help".\n' 'tsuru: "targetlist" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n' '\nDid you mean?\n'
'\ttarget-list\n' '\ttarget-list\n'
)), 'tsuru target-list'), )), ['tsuru target-list']),
]) ])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_commands):
assert get_new_command(command, None) == new_command assert get_new_command(command, None) == new_commands

View File

@ -1,7 +1,7 @@
import os import os
import re import re
import subprocess import subprocess
from thefuck.utils import get_closest, replace_argument from thefuck.utils import get_closest, replace_command
BREW_CMD_PATH = '/Library/Homebrew/cmd' BREW_CMD_PATH = '/Library/Homebrew/cmd'
TAP_PATH = '/Library/Taps' TAP_PATH = '/Library/Taps'
@ -77,10 +77,6 @@ if brew_path_prefix:
pass pass
def _get_similar_command(command):
return get_closest(command, brew_commands)
def match(command, settings): def match(command, settings):
is_proper_command = ('brew' in command.script and is_proper_command = ('brew' in command.script and
'Unknown command' in command.stderr) 'Unknown command' in command.stderr)
@ -89,7 +85,7 @@ def match(command, settings):
if is_proper_command: if is_proper_command:
broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)',
command.stderr)[0] 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 return has_possible_commands
@ -97,6 +93,4 @@ def match(command, settings):
def get_new_command(command, settings): def get_new_command(command, settings):
broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)',
command.stderr)[0] command.stderr)[0]
new_cmd = _get_similar_command(broken_cmd) return replace_command(command, broken_cmd, brew_commands)
return replace_argument(command.script, broken_cmd, new_cmd)

View File

@ -1,7 +1,7 @@
from itertools import dropwhile, takewhile, islice from itertools import dropwhile, takewhile, islice
import re import re
import subprocess 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 @sudo_support
@ -23,5 +23,4 @@ def get_docker_commands():
def get_new_command(command, settings): def get_new_command(command, settings):
wrong_command = re.findall( wrong_command = re.findall(
r"docker: '(\w+)' is not a docker command.", command.stderr)[0] r"docker: '(\w+)' is not a docker command.", command.stderr)[0]
fixed_command = get_closest(wrong_command, get_docker_commands()) return replace_command(command, wrong_command, get_docker_commands())
return replace_argument(command.script, wrong_command, fixed_command)

View File

@ -1,6 +1,6 @@
import re import re
from thefuck.utils import (get_closest, git_support, replace_argument, from thefuck.utils import (git_support,
get_all_matched_commands) get_all_matched_commands, replace_command)
@git_support @git_support
@ -13,7 +13,5 @@ def match(command, settings):
def get_new_command(command, settings): def get_new_command(command, settings):
broken_cmd = re.findall(r"git: '([^']*)' is not a git command", broken_cmd = re.findall(r"git: '([^']*)' is not a git command",
command.stderr)[0] command.stderr)[0]
new_cmd = get_closest(broken_cmd, matched = get_all_matched_commands(command.stderr)
get_all_matched_commands(command.stderr)) return replace_command(command, broken_cmd, matched)
return replace_argument(command.script, broken_cmd, new_cmd)

View File

@ -1,6 +1,6 @@
import re import re
import subprocess import subprocess
from thefuck.utils import get_closest, replace_argument from thefuck.utils import replace_command
def match(command, script): def match(command, script):
@ -18,5 +18,4 @@ def get_gulp_tasks():
def get_new_command(command, script): def get_new_command(command, script):
wrong_task = re.findall(r"Task '(\w+)' is not in your gulpfile", wrong_task = re.findall(r"Task '(\w+)' is not in your gulpfile",
command.stdout)[0] command.stdout)[0]
fixed_task = get_closest(wrong_task, get_gulp_tasks()) return replace_command(command, wrong_task, get_gulp_tasks())
return replace_argument(command.script, wrong_task, fixed_task)

View File

@ -1,5 +1,5 @@
import re import re
from thefuck.utils import get_closest, replace_argument from thefuck.utils import replace_command
def match(command, settings): def match(command, settings):
@ -16,5 +16,4 @@ def _get_suggests(stderr):
def get_new_command(command, settings): def get_new_command(command, settings):
wrong = re.findall(r'`(\w+)` is not a heroku command', command.stderr)[0] wrong = re.findall(r'`(\w+)` is not a heroku command', command.stderr)[0]
correct = get_closest(wrong, _get_suggests(command.stderr)) return replace_command(command, wrong, _get_suggests(command.stderr))
return replace_argument(command.script, wrong, correct)

View File

@ -1,5 +1,6 @@
import re import re
from thefuck.utils import sudo_support, replace_argument from thefuck.utils import sudo_support,\
replace_command, get_all_matched_commands
@sudo_support @sudo_support
@ -13,6 +14,5 @@ def match(command, settings):
def get_new_command(command, settings): def get_new_command(command, settings):
broken_cmd = re.findall(r"'([^']*)' is not a task", broken_cmd = re.findall(r"'([^']*)' is not a task",
command.stderr)[0] command.stderr)[0]
new_cmd = re.findall(r'Did you mean this\?\n\s*([^\n]*)', new_cmds = get_all_matched_commands(command.stderr, 'Did you mean this?')
command.stderr)[0] return replace_command(command, broken_cmd, new_cmds)
return replace_argument(command.script, broken_cmd, new_cmd)

View File

@ -1,5 +1,5 @@
from difflib import get_close_matches 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 @sudo_support
@ -12,8 +12,9 @@ def match(command, settings):
@sudo_support @sudo_support
def get_new_command(command, settings): def get_new_command(command, settings):
old_command = command.script.split(' ')[0] old_command = command.script.split(' ')[0]
new_command = get_closest(old_command, get_all_executables()) new_cmds = get_close_matches(old_command, get_all_executables(), cutoff=0.1)
return ' '.join([new_command] + command.script.split(' ')[1:]) return [' '.join([new_command] + command.script.split(' ')[1:])
for new_command in new_cmds]
priority = 3000 priority = 3000

View File

@ -1,6 +1,6 @@
import re import re
from thefuck.utils import (get_closest, replace_argument, from thefuck.utils import (get_closest, replace_argument,
get_all_matched_commands) get_all_matched_commands, replace_command)
def match(command, settings): def match(command, settings):
@ -12,7 +12,6 @@ def match(command, settings):
def get_new_command(command, settings): def get_new_command(command, settings):
broken_cmd = re.findall(r'tsuru: "([^"]*)" is not a tsuru command', broken_cmd = re.findall(r'tsuru: "([^"]*)" is not a tsuru command',
command.stderr)[0] command.stderr)[0]
new_cmd = get_closest(broken_cmd, return replace_command(command, broken_cmd,
get_all_matched_commands(command.stderr)) get_all_matched_commands(command.stderr))
return replace_argument(command.script, broken_cmd, new_cmd)

View File

@ -178,3 +178,10 @@ def get_all_matched_commands(stderr, separator='Did you mean'):
should_yield = True should_yield = True
elif should_yield and line: elif should_yield and line:
yield line.strip() 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]