mirror of
https://github.com/nvbn/thefuck.git
synced 2025-03-20 01:28:56 +00:00
#N/A: Reunify rules into one and define it for multiple apps
This commit is contained in:
parent
6678fd9c8d
commit
b89cbc36e9
@ -237,7 +237,6 @@ following rules are enabled by default:
|
|||||||
* `git_two_dashes` – adds a missing dash to commands like `git commit -amend` or `git rebase -continue`;
|
* `git_two_dashes` – adds a missing dash to commands like `git commit -amend` or `git rebase -continue`;
|
||||||
* `go_run` – appends `.go` extension when compiling/running Go programs;
|
* `go_run` – appends `.go` extension when compiling/running Go programs;
|
||||||
* `go_unknown_command` – fixes wrong `go` commands, for example `go bulid`;
|
* `go_unknown_command` – fixes wrong `go` commands, for example `go bulid`;
|
||||||
* `goenv_no_such_command` – fixes wrong `goenv` commands, such as `goenv isntall` or `goenv list`;
|
|
||||||
* `gradle_no_task` – fixes not found or ambiguous `gradle` task;
|
* `gradle_no_task` – fixes not found or ambiguous `gradle` task;
|
||||||
* `gradle_wrapper` – replaces `gradle` with `./gradlew`;
|
* `gradle_wrapper` – replaces `gradle` with `./gradlew`;
|
||||||
* `grep_arguments_order` – fixes `grep` arguments order for situations like `grep -lir . test`;
|
* `grep_arguments_order` – fixes `grep` arguments order for situations like `grep -lir . test`;
|
||||||
@ -270,18 +269,16 @@ following rules are enabled by default:
|
|||||||
* `npm_wrong_command` – fixes wrong npm commands like `npm urgrade`;
|
* `npm_wrong_command` – fixes wrong npm commands like `npm urgrade`;
|
||||||
* `no_command` – fixes wrong console commands, for example `vom/vim`;
|
* `no_command` – fixes wrong console commands, for example `vom/vim`;
|
||||||
* `no_such_file` – creates missing directories with `mv` and `cp` commands;
|
* `no_such_file` – creates missing directories with `mv` and `cp` commands;
|
||||||
* `nodenv_no_such_command` – fixes wrong `nodenv` commands, such as `nodenv isntall` or `nodenv list`;
|
* `omnienv_no_such_command` – fixes wrong commands for `goenv`, `nodenv`, `pyenv` and `rbenv` (eg.: `pyenv isntall` or `goenv list`);
|
||||||
* `open` – either prepends `http://` to address passed to `open` or create a new file or directory and passes it to `open`;
|
* `open` – either prepends `http://` to address passed to `open` or create a new file or directory and passes it to `open`;
|
||||||
* `pip_install` – fixes permission issues with `pip install` commands by adding `--user` or prepending `sudo` if necessary;
|
* `pip_install` – fixes permission issues with `pip install` commands by adding `--user` or prepending `sudo` if necessary;
|
||||||
* `pip_unknown_command` – fixes wrong `pip` commands, for example `pip instatl/pip install`;
|
* `pip_unknown_command` – fixes wrong `pip` commands, for example `pip instatl/pip install`;
|
||||||
* `php_s` – replaces `-s` by `-S` when trying to run a local php server;
|
* `php_s` – replaces `-s` by `-S` when trying to run a local php server;
|
||||||
* `port_already_in_use` – kills process that bound port;
|
* `port_already_in_use` – kills process that bound port;
|
||||||
* `prove_recursively` – adds `-r` when called with directory;
|
* `prove_recursively` – adds `-r` when called with directory;
|
||||||
* `pyenv_no_such_command` – fixes wrong pyenv commands like `pyenv isntall` or `pyenv list`;
|
|
||||||
* `python_command` – prepends `python` when you try to run non-executable/without `./` python script;
|
* `python_command` – prepends `python` when you try to run non-executable/without `./` python script;
|
||||||
* `python_execute` – appends missing `.py` when executing Python files;
|
* `python_execute` – appends missing `.py` when executing Python files;
|
||||||
* `quotation_marks` – fixes uneven usage of `'` and `"` when containing args';
|
* `quotation_marks` – fixes uneven usage of `'` and `"` when containing args';
|
||||||
* `rbenv_no_such_command` – fixes wrong `rbenv` commands, such as `rbenv isntall` or `rbenv list`;
|
|
||||||
* `path_from_history` – replaces not found path with similar absolute path from history;
|
* `path_from_history` – replaces not found path with similar absolute path from history;
|
||||||
* `react_native_command_unrecognized` – fixes unrecognized `react-native` commands;
|
* `react_native_command_unrecognized` – fixes unrecognized `react-native` commands;
|
||||||
* `remove_shell_prompt_literal` – remove leading shell prompt symbol `$`, common when copying commands from documentations;
|
* `remove_shell_prompt_literal` – remove leading shell prompt symbol `$`, common when copying commands from documentations;
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from thefuck.rules.goenv_no_such_command import get_new_command, match
|
|
||||||
from thefuck.types import Command
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def output(goenv_cmd):
|
|
||||||
return "goenv: no such command '{}'".format(goenv_cmd)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
|
||||||
def Popen(mocker):
|
|
||||||
mock = mocker.patch('thefuck.rules.goenv_no_such_command.Popen')
|
|
||||||
mock.return_value.stdout.readlines.return_value = (
|
|
||||||
b'--version\nactivate\ncommands\ncompletions\ndeactivate\nexec_\n'
|
|
||||||
b'global\nhelp\nhooks\ninit\ninstall\nlocal\nprefix_\n'
|
|
||||||
b'realpath.dylib\nrehash\nroot\nshell\nshims\nuninstall\nversion_\n'
|
|
||||||
b'version-file\nversion-file-read\nversion-file-write\nversion-name_\n'
|
|
||||||
b'version-origin\nversions\nvirtualenv\nvirtualenv-delete_\n'
|
|
||||||
b'virtualenv-init\nvirtualenv-prefix\nvirtualenvs_\n'
|
|
||||||
b'virtualenvwrapper\nvirtualenvwrapper_lazy\nwhence\nwhich_\n'
|
|
||||||
).split()
|
|
||||||
return mock
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, goenv_cmd', [
|
|
||||||
('goenv globe', 'globe'),
|
|
||||||
('goenv intall 3.8.0', 'intall'),
|
|
||||||
('goenv list', 'list'),
|
|
||||||
])
|
|
||||||
def test_match(script, goenv_cmd, output):
|
|
||||||
assert match(Command(script, output=output))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, output', [
|
|
||||||
('goenv global', 'system'),
|
|
||||||
('goenv versions', ' 3.7.0\n 3.7.1\n* 3.7.2\n'),
|
|
||||||
('goenv install --list', ' 3.7.0\n 3.7.1\n 3.7.2\n'),
|
|
||||||
])
|
|
||||||
def test_not_match(script, output):
|
|
||||||
assert not match(Command(script, output=output))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, goenv_cmd, result', [
|
|
||||||
('goenv globe', 'globe', 'goenv global'),
|
|
||||||
('goenv intall 3.8.0', 'intall', 'goenv install 3.8.0'),
|
|
||||||
('goenv list', 'list', 'goenv install --list'),
|
|
||||||
('goenv remove 3.8.0', 'remove', 'goenv uninstall 3.8.0'),
|
|
||||||
])
|
|
||||||
def test_get_new_command(script, goenv_cmd, output, result):
|
|
||||||
assert result in get_new_command(Command(script, output))
|
|
@ -1,52 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from thefuck.rules.nodenv_no_such_command import get_new_command, match
|
|
||||||
from thefuck.types import Command
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def output(nodenv_cmd):
|
|
||||||
return "nodenv: no such command `{}'".format(nodenv_cmd)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
|
||||||
def Popen(mocker):
|
|
||||||
mock = mocker.patch('thefuck.rules.nodenv_no_such_command.Popen')
|
|
||||||
mock.return_value.stdout.readlines.return_value = (
|
|
||||||
b'--version\nactivate\ncommands\ncompletions\ndeactivate\nexec_\n'
|
|
||||||
b'global\nhelp\nhooks\ninit\ninstall\nlocal\nprefix_\n'
|
|
||||||
b'realpath.dylib\nrehash\nroot\nshell\nshims\nuninstall\nversion_\n'
|
|
||||||
b'version-file\nversion-file-read\nversion-file-write\nversion-name_\n'
|
|
||||||
b'version-origin\nversions\nvirtualenv\nvirtualenv-delete_\n'
|
|
||||||
b'virtualenv-init\nvirtualenv-prefix\nvirtualenvs_\n'
|
|
||||||
b'virtualenvwrapper\nvirtualenvwrapper_lazy\nwhence\nwhich_\n'
|
|
||||||
).split()
|
|
||||||
return mock
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, nodenv_cmd', [
|
|
||||||
('nodenv globe', 'globe'),
|
|
||||||
('nodenv intall 3.8.0', 'intall'),
|
|
||||||
('nodenv list', 'list'),
|
|
||||||
])
|
|
||||||
def test_match(script, nodenv_cmd, output):
|
|
||||||
assert match(Command(script, output=output))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, output', [
|
|
||||||
('nodenv global', 'system'),
|
|
||||||
('nodenv versions', ' 3.7.0\n 3.7.1\n* 3.7.2\n'),
|
|
||||||
('nodenv install --list', ' 3.7.0\n 3.7.1\n 3.7.2\n'),
|
|
||||||
])
|
|
||||||
def test_not_match(script, output):
|
|
||||||
assert not match(Command(script, output=output))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, nodenv_cmd, result', [
|
|
||||||
('nodenv globe', 'globe', 'nodenv global'),
|
|
||||||
('nodenv intall 3.8.0', 'intall', 'nodenv install 3.8.0'),
|
|
||||||
('nodenv list', 'list', 'nodenv install --list'),
|
|
||||||
('nodenv remove 3.8.0', 'remove', 'nodenv uninstall 3.8.0'),
|
|
||||||
])
|
|
||||||
def test_get_new_command(script, nodenv_cmd, output, result):
|
|
||||||
assert result in get_new_command(Command(script, output))
|
|
@ -1,6 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from thefuck.rules.pyenv_no_such_command import get_new_command, match
|
from thefuck.rules.omnienv_no_such_command import get_new_command, match
|
||||||
from thefuck.types import Command
|
from thefuck.types import Command
|
||||||
|
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ def output(pyenv_cmd):
|
|||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def Popen(mocker):
|
def Popen(mocker):
|
||||||
mock = mocker.patch('thefuck.rules.pyenv_no_such_command.Popen')
|
mock = mocker.patch('thefuck.rules.omnienv_no_such_command.Popen')
|
||||||
mock.return_value.stdout.readlines.return_value = (
|
mock.return_value.stdout.readlines.return_value = (
|
||||||
b'--version\nactivate\ncommands\ncompletions\ndeactivate\nexec_\n'
|
b'--version\nactivate\ncommands\ncompletions\ndeactivate\nexec_\n'
|
||||||
b'global\nhelp\nhooks\ninit\ninstall\nlocal\nprefix_\n'
|
b'global\nhelp\nhooks\ninit\ninstall\nlocal\nprefix_\n'
|
||||||
@ -33,6 +33,11 @@ def test_match(script, pyenv_cmd, output):
|
|||||||
assert match(Command(script, output=output))
|
assert match(Command(script, output=output))
|
||||||
|
|
||||||
|
|
||||||
|
def test_match_goenv_output_quote():
|
||||||
|
"""test goenv's specific output with quotes (')"""
|
||||||
|
assert match(Command('goenv list', output="pyenv: no such command 'list'"))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, output', [
|
@pytest.mark.parametrize('script, output', [
|
||||||
('pyenv global', 'system'),
|
('pyenv global', 'system'),
|
||||||
('pyenv versions', ' 3.7.0\n 3.7.1\n* 3.7.2\n'),
|
('pyenv versions', ' 3.7.0\n 3.7.1\n* 3.7.2\n'),
|
@ -1,52 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from thefuck.rules.rbenv_no_such_command import get_new_command, match
|
|
||||||
from thefuck.types import Command
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def output(rbenv_cmd):
|
|
||||||
return "rbenv: no such command `{}'".format(rbenv_cmd)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
|
||||||
def Popen(mocker):
|
|
||||||
mock = mocker.patch('thefuck.rules.rbenv_no_such_command.Popen')
|
|
||||||
mock.return_value.stdout.readlines.return_value = (
|
|
||||||
b'--version\nactivate\ncommands\ncompletions\ndeactivate\nexec_\n'
|
|
||||||
b'global\nhelp\nhooks\ninit\ninstall\nlocal\nprefix_\n'
|
|
||||||
b'realpath.dylib\nrehash\nroot\nshell\nshims\nuninstall\nversion_\n'
|
|
||||||
b'version-file\nversion-file-read\nversion-file-write\nversion-name_\n'
|
|
||||||
b'version-origin\nversions\nvirtualenv\nvirtualenv-delete_\n'
|
|
||||||
b'virtualenv-init\nvirtualenv-prefix\nvirtualenvs_\n'
|
|
||||||
b'virtualenvwrapper\nvirtualenvwrapper_lazy\nwhence\nwhich_\n'
|
|
||||||
).split()
|
|
||||||
return mock
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, rbenv_cmd', [
|
|
||||||
('rbenv globe', 'globe'),
|
|
||||||
('rbenv intall 3.8.0', 'intall'),
|
|
||||||
('rbenv list', 'list'),
|
|
||||||
])
|
|
||||||
def test_match(script, rbenv_cmd, output):
|
|
||||||
assert match(Command(script, output=output))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, output', [
|
|
||||||
('rbenv global', 'system'),
|
|
||||||
('rbenv versions', ' 3.7.0\n 3.7.1\n* 3.7.2\n'),
|
|
||||||
('rbenv install --list', ' 3.7.0\n 3.7.1\n 3.7.2\n'),
|
|
||||||
])
|
|
||||||
def test_not_match(script, output):
|
|
||||||
assert not match(Command(script, output=output))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('script, rbenv_cmd, result', [
|
|
||||||
('rbenv globe', 'globe', 'rbenv global'),
|
|
||||||
('rbenv intall 3.8.0', 'intall', 'rbenv install 3.8.0'),
|
|
||||||
('rbenv list', 'list', 'rbenv install --list'),
|
|
||||||
('rbenv remove 3.8.0', 'remove', 'rbenv uninstall 3.8.0'),
|
|
||||||
])
|
|
||||||
def test_get_new_command(script, rbenv_cmd, output, result):
|
|
||||||
assert result in get_new_command(Command(script, output))
|
|
@ -1,29 +0,0 @@
|
|||||||
import re
|
|
||||||
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
|
|
||||||
from thefuck.specific.devenv import env_available, COMMON_TYPOS
|
|
||||||
from subprocess import PIPE, Popen
|
|
||||||
|
|
||||||
enabled_by_default = env_available
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('goenv')
|
|
||||||
def match(command):
|
|
||||||
return 'goenv: no such command' in command.output
|
|
||||||
|
|
||||||
|
|
||||||
def get_commands():
|
|
||||||
proc = Popen(['goenv', 'commands'], stdout=PIPE)
|
|
||||||
return [line.decode('utf-8').strip() for line in proc.stdout.readlines()]
|
|
||||||
|
|
||||||
|
|
||||||
if which('goenv'):
|
|
||||||
get_commands = cache(which('goenv'))(get_commands)
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('goenv')
|
|
||||||
def get_new_command(command):
|
|
||||||
broken = re.findall(r"goenv: no such command '([^']*)'", command.output)[0]
|
|
||||||
matched = [replace_argument(command.script, broken, common_typo)
|
|
||||||
for common_typo in COMMON_TYPOS.get(broken, [])]
|
|
||||||
matched.extend(replace_command(command, broken, get_commands()))
|
|
||||||
return matched
|
|
@ -1,29 +0,0 @@
|
|||||||
import re
|
|
||||||
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
|
|
||||||
from thefuck.specific.devenv import env_available, COMMON_TYPOS
|
|
||||||
from subprocess import PIPE, Popen
|
|
||||||
|
|
||||||
enabled_by_default = env_available
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('nodenv')
|
|
||||||
def match(command):
|
|
||||||
return 'nodenv: no such command' in command.output
|
|
||||||
|
|
||||||
|
|
||||||
def get_commands():
|
|
||||||
proc = Popen(['nodenv', 'commands'], stdout=PIPE)
|
|
||||||
return [line.decode('utf-8').strip() for line in proc.stdout.readlines()]
|
|
||||||
|
|
||||||
|
|
||||||
if which('nodenv'):
|
|
||||||
get_commands = cache(which('nodenv'))(get_commands)
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('nodenv')
|
|
||||||
def get_new_command(command):
|
|
||||||
broken = re.findall(r"nodenv: no such command `([^']*)'", command.output)[0]
|
|
||||||
matched = [replace_argument(command.script, broken, common_typo)
|
|
||||||
for common_typo in COMMON_TYPOS.get(broken, [])]
|
|
||||||
matched.extend(replace_command(command, broken, get_commands()))
|
|
||||||
return matched
|
|
34
thefuck/rules/omnienv_no_such_command.py
Normal file
34
thefuck/rules/omnienv_no_such_command.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import re
|
||||||
|
from thefuck.utils import (cache, for_app, replace_argument, replace_command,
|
||||||
|
which)
|
||||||
|
from subprocess import PIPE, Popen
|
||||||
|
|
||||||
|
|
||||||
|
supported_apps = 'goenv', 'nodenv', 'pyenv', 'rbenv'
|
||||||
|
enabled_by_default = any(which(a) for a in supported_apps)
|
||||||
|
|
||||||
|
|
||||||
|
COMMON_TYPOS = {
|
||||||
|
'list': ['versions', 'install --list'],
|
||||||
|
'remove': ['uninstall'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@for_app(*supported_apps, at_least=1)
|
||||||
|
def match(command):
|
||||||
|
return 'env: no such command ' in command.output
|
||||||
|
|
||||||
|
|
||||||
|
def get_app_commands(app):
|
||||||
|
proc = Popen([app, 'commands'], stdout=PIPE)
|
||||||
|
return [line.decode('utf-8').strip() for line in proc.stdout.readlines()]
|
||||||
|
|
||||||
|
|
||||||
|
def get_new_command(command):
|
||||||
|
app = command.script_parts[0]
|
||||||
|
app_commands = cache(which(app))(get_app_commands)(app)
|
||||||
|
broken = re.findall(r"env: no such command ['`]([^']*)'", command.output)[0]
|
||||||
|
matched = [replace_argument(command.script, broken, common_typo)
|
||||||
|
for common_typo in COMMON_TYPOS.get(broken, [])]
|
||||||
|
matched.extend(replace_command(command, broken, app_commands))
|
||||||
|
return matched
|
@ -1,29 +0,0 @@
|
|||||||
import re
|
|
||||||
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
|
|
||||||
from thefuck.specific.devenv import env_available, COMMON_TYPOS
|
|
||||||
from subprocess import PIPE, Popen
|
|
||||||
|
|
||||||
enabled_by_default = env_available
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('pyenv')
|
|
||||||
def match(command):
|
|
||||||
return 'pyenv: no such command' in command.output
|
|
||||||
|
|
||||||
|
|
||||||
def get_commands():
|
|
||||||
proc = Popen(['pyenv', 'commands'], stdout=PIPE)
|
|
||||||
return [line.decode('utf-8').strip() for line in proc.stdout.readlines()]
|
|
||||||
|
|
||||||
|
|
||||||
if which('pyenv'):
|
|
||||||
get_commands = cache(which('pyenv'))(get_commands)
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('pyenv')
|
|
||||||
def get_new_command(command):
|
|
||||||
broken = re.findall(r"pyenv: no such command `([^']*)'", command.output)[0]
|
|
||||||
matched = [replace_argument(command.script, broken, common_typo)
|
|
||||||
for common_typo in COMMON_TYPOS.get(broken, [])]
|
|
||||||
matched.extend(replace_command(command, broken, get_commands()))
|
|
||||||
return matched
|
|
@ -1,29 +0,0 @@
|
|||||||
import re
|
|
||||||
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
|
|
||||||
from thefuck.specific.devenv import env_available, COMMON_TYPOS
|
|
||||||
from subprocess import PIPE, Popen
|
|
||||||
|
|
||||||
enabled_by_default = env_available
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('rbenv')
|
|
||||||
def match(command):
|
|
||||||
return 'rbenv: no such command' in command.output
|
|
||||||
|
|
||||||
|
|
||||||
def get_commands():
|
|
||||||
proc = Popen(['rbenv', 'commands'], stdout=PIPE)
|
|
||||||
return [line.decode('utf-8').strip() for line in proc.stdout.readlines()]
|
|
||||||
|
|
||||||
|
|
||||||
if which('rbenv'):
|
|
||||||
get_commands = cache(which('rbenv'))(get_commands)
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('rbenv')
|
|
||||||
def get_new_command(command):
|
|
||||||
broken = re.findall(r"rbenv: no such command `([^']*)'", command.output)[0]
|
|
||||||
matched = [replace_argument(command.script, broken, common_typo)
|
|
||||||
for common_typo in COMMON_TYPOS.get(broken, [])]
|
|
||||||
matched.extend(replace_command(command, broken, get_commands()))
|
|
||||||
return matched
|
|
@ -1,10 +0,0 @@
|
|||||||
from thefuck.utils import which
|
|
||||||
|
|
||||||
|
|
||||||
env_available = bool(which('pyenv')) or bool(which('rbenv')) or bool(which('goenv')) or bool(which('nodenv'))
|
|
||||||
|
|
||||||
|
|
||||||
COMMON_TYPOS = {
|
|
||||||
'list': ['versions', 'install --list'],
|
|
||||||
'remove': ['uninstall'],
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user