Skip to content

Commit

Permalink
Merge 9d49d39 into 365db1e
Browse files Browse the repository at this point in the history
  • Loading branch information
gkodosis committed Jul 6, 2020
2 parents 365db1e + 9d49d39 commit e3e9c6f
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 30 deletions.
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -238,6 +238,7 @@ following rules are enabled by default:
* `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_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_wrapper` – replaces `gradle` with `./gradlew`;
* `grep_arguments_order` – fixes `grep` arguments order for situations like `grep -lir . test`;
Expand Down Expand Up @@ -270,6 +271,7 @@ following rules are enabled by default:
* `npm_wrong_command` – fixes wrong npm commands like `npm urgrade`;
* `no_command` – fixes wrong console commands, for example `vom/vim`;
* `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`;
* `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_unknown_command` – fixes wrong `pip` commands, for example `pip instatl/pip install`;
Expand All @@ -280,6 +282,7 @@ following rules are enabled by default:
* `python_command` – prepends `python` when you try to run non-executable/without `./` python script;
* `python_execute` – appends missing `.py` when executing Python files;
* `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;
* `react_native_command_unrecognized` – fixes unrecognized `react-native` commands;
* `remove_shell_prompt_literal` – remove leading shell prompt symbol `$`, common when copying commands from documentations;
Expand Down
37 changes: 37 additions & 0 deletions tests/rules/test_goenv_no_such_command.py
@@ -0,0 +1,37 @@
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.mark.parametrize('script, goenv_cmd', [
('goenv globe', 'globe'),
('goenv intall 1.4.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', ' 1.5.0\n 1.5.1\n* 1.5.2\n'),
('goenv install --list', ' 1.5.0\n 1.5.1\n 1.5.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))
37 changes: 37 additions & 0 deletions tests/rules/test_nodenv_no_such_command.py
@@ -0,0 +1,37 @@
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.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))
15 changes: 0 additions & 15 deletions tests/rules/test_pyenv_no_such_command.py
Expand Up @@ -9,21 +9,6 @@ def output(pyenv_cmd):
return "pyenv: no such command `{}'".format(pyenv_cmd)


@pytest.fixture(autouse=True)
def Popen(mocker):
mock = mocker.patch('thefuck.rules.pyenv_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, pyenv_cmd', [
('pyenv globe', 'globe'),
('pyenv intall 3.8.0', 'intall'),
Expand Down
37 changes: 37 additions & 0 deletions tests/rules/test_rbenv_no_such_command.py
@@ -0,0 +1,37 @@
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.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))
16 changes: 16 additions & 0 deletions tests/specific/test_devenv.py
@@ -0,0 +1,16 @@
import pytest


@pytest.fixture(autouse=True)
def Popen(mocker):
mock = mocker.patch('thefuck.specific.devenv.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
23 changes: 23 additions & 0 deletions thefuck/rules/goenv_no_such_command.py
@@ -0,0 +1,23 @@
import re
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
from thefuck.specific.devenv import env_available, COMMON_TYPOS, get_commands

enabled_by_default = env_available


@for_app('goenv')
def match(command):
return 'goenv: no such command' in command.output


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
23 changes: 23 additions & 0 deletions thefuck/rules/nodenv_no_such_command.py
@@ -0,0 +1,23 @@
import re
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
from thefuck.specific.devenv import env_available, COMMON_TYPOS, get_commands

enabled_by_default = env_available


@for_app('nodenv')
def match(command):
return 'nodenv: no such command' in command.output


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
20 changes: 5 additions & 15 deletions thefuck/rules/pyenv_no_such_command.py
@@ -1,33 +1,23 @@
import re
from subprocess import PIPE, Popen
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
from thefuck.specific.devenv import env_available, COMMON_TYPOS, get_commands

from thefuck.utils import (cache, for_app, replace_argument, replace_command,
which)

COMMON_TYPOS = {
'list': ['versions', 'install --list'],
'remove': ['uninstall'],
}
enabled_by_default = env_available


@for_app('pyenv')
def match(command):
return 'pyenv: no such command' in command.output


def get_pyenv_commands():
proc = Popen(['pyenv', 'commands'], stdout=PIPE)
return [line.decode('utf-8').strip() for line in proc.stdout.readlines()]


if which('pyenv'):
get_pyenv_commands = cache(which('pyenv'))(get_pyenv_commands)
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_pyenv_commands()))
matched.extend(replace_command(command, broken, get_commands()))
return matched
23 changes: 23 additions & 0 deletions thefuck/rules/rbenv_no_such_command.py
@@ -0,0 +1,23 @@
import re
from thefuck.utils import cache, for_app, replace_argument, replace_command, which
from thefuck.specific.devenv import env_available, COMMON_TYPOS, get_commands

enabled_by_default = env_available


@for_app('rbenv')
def match(command):
return 'rbenv: no such command' in command.output


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
24 changes: 24 additions & 0 deletions thefuck/specific/devenv.py
@@ -0,0 +1,24 @@
from thefuck.utils import which
from subprocess import Popen, PIPE


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'],
}


def get_commands():
if which('pyenv'):
env = 'pyenv'
elif which('rbenv'):
env = 'rbenv'
elif which('goenv'):
env = 'goenv'
else:
env = 'nodenv'
proc = Popen([env, 'commands'], stdout=PIPE)
return [line.decode('utf-8').strip() for line in proc.stdout.readlines()]

0 comments on commit e3e9c6f

Please sign in to comment.