diff --git a/README.md b/README.md index 5a453a21..8a6c8c1a 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `systemctl` – correctly orders parameters of confusing `systemctl`; * `test.py` – runs `py.test` instead of `test.py`; * `tsuru_login` – runs `tsuru login` if not authenticated or session expired; +* `tsuru_not_command` – fixes wrong tsuru commands like `tsuru shell`; * `tmux` – fixes `tmux` commands; * `whois` – fixes `whois` command. diff --git a/tests/rules/test_tsuru_not_command.py b/tests/rules/test_tsuru_not_command.py new file mode 100644 index 00000000..d8d8c99a --- /dev/null +++ b/tests/rules/test_tsuru_not_command.py @@ -0,0 +1,90 @@ +import pytest + +from tests.utils import Command +from thefuck.rules.tsuru_not_command import match, get_new_command + + +@pytest.mark.parametrize('command', [ + Command('tsuru log', stderr=( + 'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n' + '\nDid you mean?\n' + '\tapp-log\n' + '\tlogin\n' + '\tlogout\n' + )), + Command('tsuru app-l', stderr=( + 'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n' + '\nDid you mean?\n' + '\tapp-list\n' + '\tapp-log\n' + )), + Command('tsuru user-list', stderr=( + 'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n' + '\nDid you mean?\n' + '\tteam-user-list\n' + )), + Command('tsuru targetlist', stderr=( + 'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n' + '\nDid you mean?\n' + '\ttarget-list\n' + )), +]) +def test_match(command): + assert match(command, None) + + +@pytest.mark.parametrize('command', [ + Command('tsuru tchururu', stderr=( + 'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n' + '\nDid you mean?\n' + )), + Command('tsuru version', stderr='tsuru version 0.16.0.'), + Command('tsuru help', stderr=( + 'tsuru version 0.16.0.\n' + '\nUsage: tsuru command [args]\n' + )), + Command('tsuru platform-list', stderr=( + '- java\n' + '- logstashgiro\n' + '- newnode\n' + '- nodejs\n' + '- php\n' + '- python\n' + '- python3\n' + '- ruby\n' + '- ruby20\n' + '- static\n' + )), + Command('tsuru env-get', stderr='Error: App thefuck not found.'), +]) +def test_not_match(command): + assert not match(command, None) + + +@pytest.mark.parametrize('command, new_command', [ + (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'), + (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'), + (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'), + (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'), +]) +def test_get_new_command(command, new_command): + assert get_new_command(command, None) == new_command diff --git a/tests/test_utils.py b/tests/test_utils.py index ec8605de..e47db872 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,7 +1,8 @@ import pytest from mock import Mock from thefuck.utils import git_support, sudo_support, wrap_settings,\ - memoize, get_closest, get_all_executables, replace_argument + memoize, get_closest, get_all_executables, replace_argument, \ + get_all_matched_commands from thefuck.types import Settings from tests.utils import Command @@ -99,3 +100,32 @@ def test_get_all_callables(): (('git brnch', 'brnch', 'branch'), 'git branch')]) def test_replace_argument(args, result): assert replace_argument(*args) == result + + +@pytest.mark.parametrize('stderr, result', [ + (("git: 'cone' is not a git command. See 'git --help'.\n" + '\n' + 'Did you mean one of these?\n' + '\tclone'), ['clone']), + (("git: 're' is not a git command. See 'git --help'.\n" + '\n' + 'Did you mean one of these?\n' + '\trebase\n' + '\treset\n' + '\tgrep\n' + '\trm'), ['rebase', 'reset', 'grep', 'rm']), + (('tsuru: "target" is not a tsuru command. See "tsuru help".\n' + '\n' + 'Did you mean one of these?\n' + '\tservice-add\n' + '\tservice-bind\n' + '\tservice-doc\n' + '\tservice-info\n' + '\tservice-list\n' + '\tservice-remove\n' + '\tservice-status\n' + '\tservice-unbind'), ['service-add', 'service-bind', 'service-doc', + 'service-info', 'service-list', 'service-remove', + 'service-status', 'service-unbind'])]) +def test_get_all_matched_commands(stderr, result): + assert list(get_all_matched_commands(stderr)) == result diff --git a/thefuck/rules/git_not_command.py b/thefuck/rules/git_not_command.py index 0eb5fbf9..033e0095 100644 --- a/thefuck/rules/git_not_command.py +++ b/thefuck/rules/git_not_command.py @@ -1,5 +1,6 @@ import re -from thefuck.utils import get_closest, git_support, replace_argument +from thefuck.utils import (get_closest, git_support, replace_argument, + get_all_matched_commands) @git_support @@ -8,20 +9,11 @@ def match(command, settings): and 'Did you mean' in command.stderr) -def _get_all_git_matched_commands(stderr): - should_yield = False - for line in stderr.split('\n'): - if 'Did you mean' in line: - should_yield = True - elif should_yield and line: - yield line.strip() - - @git_support 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_git_matched_commands(command.stderr)) + get_all_matched_commands(command.stderr)) return replace_argument(command.script, broken_cmd, new_cmd) diff --git a/thefuck/rules/tsuru_not_command.py b/thefuck/rules/tsuru_not_command.py new file mode 100644 index 00000000..29930a5a --- /dev/null +++ b/thefuck/rules/tsuru_not_command.py @@ -0,0 +1,18 @@ +import re +from thefuck.utils import (get_closest, replace_argument, + get_all_matched_commands) + + +def match(command, settings): + return (command.script.startswith('tsuru ') + and ' is not a tsuru command. See "tsuru help".' in command.stderr + and '\nDid you mean?\n\t' in command.stderr) + + +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) + diff --git a/thefuck/utils.py b/thefuck/utils.py index 8bd6dc75..639fa4d8 100644 --- a/thefuck/utils.py +++ b/thefuck/utils.py @@ -159,3 +159,12 @@ def replace_argument(script, from_, to): else: return script.replace( u' {} '.format(from_), u' {} '.format(to), 1) + + +def get_all_matched_commands(stderr, separator='Did you mean'): + should_yield = False + for line in stderr.split('\n'): + if separator in line: + should_yield = True + elif should_yield and line: + yield line.strip()