1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-02-21 20:38:54 +00:00

Merge branch 'master' of github.com:nvbn/thefuck into pacman

This commit is contained in:
mcarton 2015-05-17 20:24:13 +02:00
commit 881967f4c5
19 changed files with 293 additions and 9 deletions

View File

@ -6,4 +6,4 @@ python:
install: install:
- python setup.py develop - python setup.py develop
- pip install -r requirements.txt - pip install -r requirements.txt
script: py.test script: py.test -v

View File

@ -171,6 +171,7 @@ using the matched rule and runs it. Rules enabled by default are as follows:
* `ssh_known_hosts` – removes host from `known_hosts` on warning; * `ssh_known_hosts` – removes host from `known_hosts` on warning;
* `sudo` – prepends `sudo` to previous command if it failed because of permissions; * `sudo` – prepends `sudo` to previous command if it failed because of permissions;
* `switch_layout` – switches command from your local layout to en; * `switch_layout` – switches command from your local layout to en;
* `whois` – fixes `whois` command;
* `apt_get` – installs app from apt if it not installed; * `apt_get` – installs app from apt if it not installed;
* `brew_install` – fixes formula name for `brew install`; * `brew_install` – fixes formula name for `brew install`;
* `composer_not_command` – fixes composer command name. * `composer_not_command` – fixes composer command name.

0
tests/rules/__init__.py Normal file
View File

6
tests/rules/conftest.py Normal file
View File

@ -0,0 +1,6 @@
import pytest
@pytest.fixture(autouse=True)
def generic_shell(monkeypatch):
monkeypatch.setattr('thefuck.shells.and_', lambda *x: ' && '.join(x))

View File

@ -0,0 +1,59 @@
import pytest
from mock import Mock, patch
from thefuck.rules import apt_get
from thefuck.rules.apt_get import match, get_new_command
from tests.utils import Command
# python-commandnotfound is available in ubuntu 14.04+
@pytest.mark.skipif(not getattr(apt_get, 'enabled_by_default', True),
reason='Skip if python-commandnotfound is not available')
@pytest.mark.parametrize('command', [
Command(script='vim', stderr='vim: command not found')])
def test_match(command):
assert match(command, None)
@pytest.mark.parametrize('command, return_value', [
(Command(script='vim', stderr='vim: command not found'),
[('vim', 'main'), ('vim-tiny', 'main')])])
@patch('thefuck.rules.apt_get.CommandNotFound', create=True)
@patch.multiple(apt_get, create=True, apt_get='apt_get')
def test_match_mocked(cmdnf_mock, command, return_value):
get_packages = Mock(return_value=return_value)
cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages)
assert match(command, None)
assert cmdnf_mock.CommandNotFound.called
assert get_packages.called
@pytest.mark.parametrize('command', [
Command(script='vim', stderr=''), Command()])
def test_not_match(command):
assert not match(command, None)
# python-commandnotfound is available in ubuntu 14.04+
@pytest.mark.skipif(not getattr(apt_get, 'enabled_by_default', True),
reason='Skip if python-commandnotfound is not available')
@pytest.mark.parametrize('command, new_command', [
(Command('vim'), 'sudo apt-get install vim && vim'),
(Command('convert'), 'sudo apt-get install imagemagick && convert')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
@pytest.mark.parametrize('command, new_command, return_value', [
(Command('vim'), 'sudo apt-get install vim && vim',
[('vim', 'main'), ('vim-tiny', 'main')]),
(Command('convert'), 'sudo apt-get install imagemagick && convert',
[('imagemagick', 'main'),
('graphicsmagick-imagemagick-compat', 'universe')])])
@patch('thefuck.rules.apt_get.CommandNotFound', create=True)
@patch.multiple(apt_get, create=True, apt_get='apt_get')
def test_get_new_command_mocked(cmdnf_mock, command, new_command, return_value):
get_packages = Mock(return_value=return_value)
cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages)
assert get_new_command(command, None) == new_command
assert cmdnf_mock.CommandNotFound.called
assert get_packages.called

View File

@ -0,0 +1,39 @@
import pytest
from thefuck.rules.git_add import match, get_new_command
from tests.utils import Command
@pytest.fixture
def did_not_match(target, did_you_forget=True):
error = ("error: pathspec '{}' did not match any "
"file(s) known to git.".format(target))
if did_you_forget:
error = ("{}\nDid you forget to 'git add'?'".format(error))
return error
@pytest.mark.parametrize('command', [
Command(script='git submodule update unknown',
stderr=did_not_match('unknown')),
Command(script='git commit unknown',
stderr=did_not_match('unknown'))]) # Older versions of Git
def test_match(command):
assert match(command, None)
@pytest.mark.parametrize('command', [
Command(script='git submodule update known', stderr=('')),
Command(script='git commit known', stderr=('')),
Command(script='git commit unknown', # Newer versions of Git
stderr=did_not_match('unknown', False))])
def test_not_match(command):
assert not match(command, None)
@pytest.mark.parametrize('command, new_command', [
(Command('git submodule update unknown', stderr=did_not_match('unknown')),
'git add -- unknown && git submodule update unknown'),
(Command('git commit unknown', stderr=did_not_match('unknown')), # Old Git
'git add -- unknown && git commit unknown')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command

View File

@ -0,0 +1,37 @@
import pytest
from thefuck.rules.git_checkout import match, get_new_command
from tests.utils import Command
@pytest.fixture
def did_not_match(target, did_you_forget=False):
error = ("error: pathspec '{}' did not match any "
"file(s) known to git.".format(target))
if did_you_forget:
error = ("{}\nDid you forget to 'git add'?'".format(error))
return error
@pytest.mark.parametrize('command', [
Command(script='git checkout unknown', stderr=did_not_match('unknown')),
Command(script='git commit unknown', stderr=did_not_match('unknown'))])
def test_match(command):
assert match(command, None)
@pytest.mark.parametrize('command', [
Command(script='git submodule update unknown',
stderr=did_not_match('unknown', True)),
Command(script='git checkout known', stderr=('')),
Command(script='git commit known', stderr=(''))])
def test_not_match(command):
assert not match(command, None)
@pytest.mark.parametrize('command, new_command', [
(Command(script='git checkout unknown', stderr=did_not_match('unknown')),
'git branch unknown && git checkout unknown'),
(Command('git commit unknown', stderr=did_not_match('unknown')),
'git branch unknown && git commit unknown')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command

View File

@ -0,0 +1,39 @@
import pytest
from thefuck.rules.git_stash import match, get_new_command
from tests.utils import Command
@pytest.fixture
def cherry_pick_error():
return ('error: Your local changes would be overwritten by cherry-pick.\n'
'hint: Commit your changes or stash them to proceed.\n'
'fatal: cherry-pick failed')
@pytest.fixture
def rebase_error():
return ('Cannot rebase: Your index contains uncommitted changes.\n'
'Please commit or stash them.')
@pytest.mark.parametrize('command', [
Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error()),
Command(script='git rebase -i HEAD~7', stderr=rebase_error())])
def test_match(command):
assert match(command, None)
@pytest.mark.parametrize('command', [
Command(script='git cherry-pick a1b2c3d', stderr=('')),
Command(script='git rebase -i HEAD~7', stderr=(''))])
def test_not_match(command):
assert not match(command, None)
@pytest.mark.parametrize('command, new_command', [
(Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error),
'git stash && git cherry-pick a1b2c3d'),
(Command('git rebase -i HEAD~7', stderr=rebase_error),
'git stash && git rebase -i HEAD~7')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command

View File

@ -0,0 +1,53 @@
import pytest
from mock import patch
from thefuck.rules import pacman
from thefuck.rules.pacman import match, get_new_command
from tests.utils import Command
pacman_cmd = getattr(pacman, 'pacman', 'pacman')
@pytest.mark.skipif(not getattr(pacman, 'enabled_by_default', True),
reason='Skip if pacman is not available')
@pytest.mark.parametrize('command', [
Command(script='vim', stderr='vim: command not found')])
def test_match(command):
assert match(command, None)
@pytest.mark.parametrize('command, return_value', [
(Command(script='vim', stderr='vim: command not found'), 'vim foo bar')])
@patch('thefuck.rules.pacman.subprocess')
@patch.multiple(pacman, create=True, pacman=pacman_cmd)
def test_match_mocked(subp_mock, command, return_value):
subp_mock.check_output.return_value = return_value
assert match(command, None)
assert subp_mock.check_output.called
@pytest.mark.parametrize('command', [
Command(script='vim', stderr=''), Command()])
def test_not_match(command):
assert not match(command, None)
@pytest.mark.skipif(not getattr(pacman, 'enabled_by_default', True),
reason='Skip if pacman is not available')
@pytest.mark.parametrize('command, new_command', [
(Command('vim'), '{} -S vim && vim'.format(pacman_cmd)),
(Command('convert'), '{} -S imagemagick && convert'.format(pacman_cmd))])
def test_get_new_command(command, new_command, mocker):
assert get_new_command(command, None) == new_command
@pytest.mark.parametrize('command, new_command, return_value', [
(Command('vim'), '{} -S vim && vim'.format(pacman_cmd), 'vim foo bar'),
(Command('convert'), '{} -S imagemagick && convert'.format(pacman_cmd),
'imagemagick foo bar')])
@patch('thefuck.rules.pacman.subprocess')
@patch.multiple(pacman, create=True, pacman=pacman_cmd)
def test_get_new_command_mocked(subp_mock, command, new_command, return_value):
subp_mock.check_output.return_value = return_value
assert get_new_command(command, None) == new_command
assert subp_mock.check_output.called

19
tests/rules/test_whois.py Normal file
View File

@ -0,0 +1,19 @@
import pytest
from thefuck.rules.whois import match, get_new_command
from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='whois https://en.wikipedia.org/wiki/Main_Page'),
Command(script='whois https://en.wikipedia.org/'),
Command(script='whois en.wikipedia.org')])
def test_match(command):
assert match(command, None)
@pytest.mark.parametrize('command, new_command', [
(Command('whois https://en.wikipedia.org/wiki/Main_Page'), 'whois en.wikipedia.org'),
(Command('whois https://en.wikipedia.org/'), 'whois en.wikipedia.org'),
(Command('whois en.wikipedia.org'), 'whois wikipedia.org')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command

View File

@ -1,3 +1,5 @@
from thefuck import shells
try: try:
import CommandNotFound import CommandNotFound
except ImportError: except ImportError:
@ -20,4 +22,5 @@ def get_new_command(command, settings):
c = CommandNotFound.CommandNotFound() c = CommandNotFound.CommandNotFound()
pkgs = c.getPackages(command.script.split(" ")[0]) pkgs = c.getPackages(command.script.split(" ")[0])
name, _ = pkgs[0] name, _ = pkgs[0]
return "sudo apt-get install {} && {}".format(name, command.script) formatme = shells.and_('sudo apt-get install {}', '{}')
return formatme.format(name, command.script)

View File

@ -1,4 +1,5 @@
import re import re
from thefuck import shells
from thefuck.utils import sudo_support from thefuck.utils import sudo_support
@ -11,4 +12,5 @@ def match(command, settings):
@sudo_support @sudo_support
def get_new_command(command, settings): def get_new_command(command, settings):
return re.sub(r'^cd (.*)', 'mkdir -p \\1 && cd \\1', command.script) repl = shells.and_('mkdir -p \\1', 'cd \\1')
return re.sub(r'^cd (.*)', repl, command.script)

View File

@ -1,4 +1,5 @@
import re import re
from thefuck import shells
def match(command, settings): def match(command, settings):
@ -12,4 +13,5 @@ def get_new_command(command, settings):
r"error: pathspec '([^']*)' " r"error: pathspec '([^']*)' "
"did not match any file\(s\) known to git.", command.stderr)[0] "did not match any file\(s\) known to git.", command.stderr)[0]
return 'git add -- {} && {}'.format(missing_file, command.script) formatme = shells.and_('git add -- {}', '{}')
return formatme.format(missing_file, command.script)

View File

@ -1,4 +1,5 @@
import re import re
from thefuck import shells
def match(command, settings): def match(command, settings):
@ -12,4 +13,5 @@ def get_new_command(command, settings):
r"error: pathspec '([^']*)' " r"error: pathspec '([^']*)' "
"did not match any file\(s\) known to git.", command.stderr)[0] "did not match any file\(s\) known to git.", command.stderr)[0]
return 'git branch {} && {}'.format(missing_file, command.script) formatme = shells.and_('git branch {}', '{}')
return formatme.format(missing_file, command.script)

View File

@ -1,3 +1,6 @@
from thefuck import shells
def match(command, settings): def match(command, settings):
# catches "Please commit or stash them" and "Please, commit your changes or # catches "Please commit or stash them" and "Please, commit your changes or
# stash them before you can switch branches." # stash them before you can switch branches."
@ -5,4 +8,5 @@ def match(command, settings):
def get_new_command(command, settings): def get_new_command(command, settings):
return 'git stash && ' + command.script formatme = shells.and_('git stash', '{}')
return formatme.format(command.script)

View File

@ -1,4 +1,5 @@
import re import re
from thefuck import shells
patterns = ( patterns = (
@ -25,4 +26,5 @@ def get_new_command(command, settings):
file = file[0] file = file[0]
dir = file[0:file.rfind('/')] dir = file[0:file.rfind('/')]
return 'mkdir -p {} && {}'.format(dir, command.script) formatme = shells.and_('mkdir -p {}', '{}')
return formatme.format(dir, command.script)

View File

@ -1,5 +1,6 @@
import subprocess import subprocess
from thefuck.utils import DEVNULL, which from thefuck.utils import DEVNULL, which
from thefuck import shells
def __get_pkgfile(command): def __get_pkgfile(command):
@ -19,7 +20,8 @@ def match(command, settings):
def get_new_command(command, settings): def get_new_command(command, settings):
package = __get_pkgfile(command)[0] package = __get_pkgfile(command)[0]
return '{} -S {} && {}'.format(pacman, package, command.script) formatme = shells.and_('{} -S {}', '{}')
return formatme.format(pacman, package, command.script)
if not which('pkgfile'): if not which('pkgfile'):

View File

@ -1,4 +1,5 @@
from urllib.parse import urlparse # -*- encoding: utf-8 -*-
from six.moves.urllib.parse import urlparse
def match(command, settings): def match(command, settings):

View File

@ -47,8 +47,14 @@ class Generic(object):
with open(history_file_name, 'a') as history: with open(history_file_name, 'a') as history:
history.write(self._get_history_line(command_script)) history.write(self._get_history_line(command_script))
def and_(self, *commands):
return ' && '.join(commands)
class Bash(Generic): class Bash(Generic):
def app_alias(self):
return "\nalias fuck='eval $(thefuck $(fc -ln -1)); history -r'\n"
def _parse_alias(self, alias): def _parse_alias(self, alias):
name, value = alias.replace('alias ', '', 1).split('=', 1) name, value = alias.replace('alias ', '', 1).split('=', 1)
if value[0] == value[-1] == '"' or value[0] == value[-1] == "'": if value[0] == value[-1] == '"' or value[0] == value[-1] == "'":
@ -71,6 +77,9 @@ class Bash(Generic):
class Zsh(Generic): class Zsh(Generic):
def app_alias(self):
return "\nalias fuck='eval $(thefuck $(fc -ln -1 | tail -n 1)); fc -R'\n"
def _parse_alias(self, alias): def _parse_alias(self, alias):
name, value = alias.split('=', 1) name, value = alias.split('=', 1)
if value[0] == value[-1] == '"' or value[0] == value[-1] == "'": if value[0] == value[-1] == '"' or value[0] == value[-1] == "'":
@ -144,3 +153,7 @@ def app_alias():
def put_to_history(command): def put_to_history(command):
return _get_shell().put_to_history(command) return _get_shell().put_to_history(command)
def and_(*commands):
return _get_shell().and_(*commands)