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

Merge pull request #364 from nvbn/global-settings

Don't pass `settings` explicitly
This commit is contained in:
Vladimir Iakovlev 2015-09-07 19:09:31 +03:00
commit 293f16c3c8
164 changed files with 740 additions and 671 deletions

View File

@ -226,20 +226,21 @@ For adding your own rule you should create `your-rule-name.py`
in `~/.thefuck/rules`. The rule should contain two functions:
```python
match(command: Command, settings: Settings) -> bool
get_new_command(command: Command, settings: Settings) -> str | list[str]
match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]
```
Also the rule can contain an optional function
```python
side_effect(old_command: Command, fixed_command: str, settings: Settings) -> None
side_effect(old_command: Command, fixed_command: str) -> None
```
and optional `enabled_by_default`, `requires_output` and `priority` variables.
`Command` has three attributes: `script`, `stdout` and `stderr`.
`Settings` is a special object filled with `~/.thefuck/settings.py` and values from env ([see more below](#settings)).
*Rules api changed in 3.0:* For accessing settings in rule you need to import it with `from thefuck.conf import settings`.
`settings` is a special object filled with `~/.thefuck/settings.py` and values from env ([see more below](#settings)).
Simple example of the rule for running script with `sudo`:
@ -264,7 +265,8 @@ requires_output = True
```
[More examples of rules](https://github.com/nvbn/thefuck/tree/master/thefuck/rules),
[utility functions for rules](https://github.com/nvbn/thefuck/tree/master/thefuck/utils.py).
[utility functions for rules](https://github.com/nvbn/thefuck/tree/master/thefuck/utils.py),
[app/os-specific helpers](https://github.com/nvbn/thefuck/tree/master/thefuck/specific/).
## Settings

View File

@ -1,5 +1,6 @@
from pathlib import Path
import pytest
from mock import Mock
from thefuck import conf
def pytest_addoption(parser):
@ -14,9 +15,20 @@ def no_memoize(monkeypatch):
monkeypatch.setattr('thefuck.utils.memoize.disabled', True)
@pytest.fixture(autouse=True)
def settings(request):
def _reset_settings():
conf.settings.clear()
conf.settings.update(conf.DEFAULT_SETTINGS)
request.addfinalizer(_reset_settings)
conf.settings.user_dir = Path('~/.thefuck')
return conf.settings
@pytest.fixture
def settings():
return Mock(debug=False, no_colors=True)
def no_colors(settings):
settings.no_colors = True
@pytest.fixture(autouse=True)

View File

@ -11,7 +11,7 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='vim', stderr='vim: command not found')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, return_value', [
@ -24,7 +24,7 @@ def test_match(command):
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 match(command)
assert cmdnf_mock.CommandNotFound.called
assert get_packages.called
@ -32,7 +32,7 @@ def test_match_mocked(cmdnf_mock, command, return_value):
@pytest.mark.parametrize('command', [
Command(script='vim', stderr=''), Command()])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
# python-commandnotfound is available in ubuntu 14.04+
@ -44,7 +44,7 @@ def test_not_match(command):
(Command('sudo vim'), 'sudo apt-get install vim && sudo vim'),
(Command('sudo convert'), 'sudo apt-get install imagemagick && sudo convert')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command
@pytest.mark.parametrize('command, new_command, return_value', [
@ -63,4 +63,4 @@ def test_get_new_command(command, new_command):
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 get_new_command(command) == new_command

View File

@ -4,7 +4,7 @@ from tests.utils import Command
def test_match():
assert match(Command('apt-get search foo'), None)
assert match(Command('apt-get search foo'))
@pytest.mark.parametrize('command', [
@ -18,8 +18,8 @@ def test_match():
Command('apt-get update')
])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
def test_get_new_command():
assert get_new_command(Command('apt-get search foo'), None) == 'apt-cache search foo'
assert get_new_command(Command('apt-get search foo')) == 'apt-cache search foo'

View File

@ -28,9 +28,9 @@ def _is_not_okay_to_test():
def test_match(brew_no_available_formula, brew_already_installed,
brew_install_no_argument):
assert match(Command('brew install elsticsearch',
stderr=brew_no_available_formula), None)
stderr=brew_no_available_formula))
assert not match(Command('brew install git',
stderr=brew_already_installed), None)
stderr=brew_already_installed))
assert not match(Command('brew install', stderr=brew_install_no_argument),
None)
@ -39,7 +39,7 @@ def test_match(brew_no_available_formula, brew_already_installed,
reason='No need to run if there\'s no formula')
def test_get_new_command(brew_no_available_formula):
assert get_new_command(Command('brew install elsticsearch',
stderr=brew_no_available_formula), None)\
stderr=brew_no_available_formula))\
== 'brew install elasticsearch'
assert get_new_command(Command('brew install aa',

View File

@ -15,15 +15,15 @@ def brew_unknown_cmd2():
def test_match(brew_unknown_cmd):
assert match(Command('brew inst', stderr=brew_unknown_cmd), None)
assert match(Command('brew inst', stderr=brew_unknown_cmd))
for command in _brew_commands():
assert not match(Command('brew ' + command), None)
assert not match(Command('brew ' + command))
def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2):
assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd),
None) == ['brew list', 'brew install', 'brew uninstall']
assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd)) \
== ['brew list', 'brew install', 'brew uninstall']
cmds = get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2), None)
cmds = get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2))
assert 'brew install' in cmds
assert 'brew uninstall' in cmds

View File

@ -6,10 +6,10 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='brew upgrade')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('brew upgrade'), 'brew upgrade --all')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -12,10 +12,10 @@ no_such_subcommand = """No such subcommand
@pytest.mark.parametrize('command', [
Command(script='cargo buid', stderr=no_such_subcommand)])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('cargo buid', stderr=no_such_subcommand), 'cargo build')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -9,17 +9,17 @@ from tests.utils import Command
stderr='cd: foo: No such file or directory'),
Command(script='cd foo/bar/baz', stderr='cd: can\'t cd to foo/bar/baz')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
Command(script='cd foo', stderr=''), Command()])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('cd foo'), 'mkdir -p foo && cd foo'),
(Command('cd foo/bar/baz'), 'mkdir -p foo/bar/baz && cd foo/bar/baz')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match():
assert match(Command('cd..', stderr='cd..: command not found'), None)
assert not match(Command(), None)
assert match(Command('cd..', stderr='cd..: command not found'))
assert not match(Command())
def test_get_new_command():
assert get_new_command(
Command('cd..'), None) == 'cd ..'
Command('cd..')) == 'cd ..'

View File

@ -41,17 +41,16 @@ def composer_not_command_one_of_this():
def test_match(composer_not_command, composer_not_command_one_of_this):
assert match(Command('composer udpate',
stderr=composer_not_command), None)
stderr=composer_not_command))
assert match(Command('composer pdate',
stderr=composer_not_command_one_of_this), None)
assert not match(Command('ls update', stderr=composer_not_command),
None)
stderr=composer_not_command_one_of_this))
assert not match(Command('ls update', stderr=composer_not_command))
def test_get_new_command(composer_not_command, composer_not_command_one_of_this):
assert get_new_command(Command('composer udpate',
stderr=composer_not_command), None) \
stderr=composer_not_command)) \
== 'composer update'
assert get_new_command(
Command('composer pdate', stderr=composer_not_command_one_of_this),
None) == 'composer selfupdate'
Command('composer pdate', stderr=composer_not_command_one_of_this)) \
== 'composer selfupdate'

View File

@ -7,7 +7,7 @@ from tests.utils import Command
('cp dir', 'cp: dor: is a directory'),
('cp dir', "cp: omitting directory 'dir'")])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr), None)
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr', [
@ -15,8 +15,8 @@ def test_match(script, stderr):
('some dir', "cp: omitting directory 'dir'"),
('cp dir', '')])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr), None)
assert not match(Command(script, stderr=stderr))
def test_get_new_command():
assert get_new_command(Command(script='cp dir'), None) == 'cp -a dir'
assert get_new_command(Command(script='cp dir')) == 'cp -a dir'

View File

@ -45,14 +45,14 @@ parametrize_script = pytest.mark.parametrize('script, fixed', [
@parametrize_script
def test_match(tar_error, filename, script, fixed):
tar_error(filename)
assert match(Command(script=script.format(filename)), None)
assert match(Command(script=script.format(filename)))
@parametrize_filename
@parametrize_script
def test_side_effect(tar_error, filename, script, fixed):
tar_error(filename)
side_effect(Command(script=script.format(filename)), None, None)
side_effect(Command(script=script.format(filename)), None)
assert(os.listdir('.') == [filename])
@ -60,4 +60,4 @@ def test_side_effect(tar_error, filename, script, fixed):
@parametrize_script
def test_get_new_command(tar_error, filename, script, fixed):
tar_error(filename)
assert get_new_command(Command(script=script.format(filename)), None) == fixed.format(filename)
assert get_new_command(Command(script=script.format(filename))) == fixed.format(filename)

View File

@ -27,14 +27,14 @@ def zip_error(tmpdir):
'unzip foo',
'unzip foo.zip'])
def test_match(zip_error, script):
assert match(Command(script=script), None)
assert match(Command(script=script))
@pytest.mark.parametrize('script', [
'unzip foo',
'unzip foo.zip'])
def test_side_effect(zip_error, script):
side_effect(Command(script=script), None, None)
side_effect(Command(script=script), None)
assert(os.listdir('.') == ['foo.zip'])
@ -42,4 +42,4 @@ def test_side_effect(zip_error, script):
('unzip foo', 'unzip foo -d foo'),
('unzip foo.zip', 'unzip foo.zip -d foo')])
def test_get_new_command(zip_error, script, fixed):
assert get_new_command(Command(script=script), None) == fixed
assert get_new_command(Command(script=script)) == fixed

View File

@ -41,13 +41,13 @@ south.exceptions.GhostMigrations:
def test_match(stderr):
assert match(Command('./manage.py migrate', stderr=stderr), None)
assert match(Command('python manage.py migrate', stderr=stderr), None)
assert not match(Command('./manage.py migrate'), None)
assert not match(Command('app migrate', stderr=stderr), None)
assert not match(Command('./manage.py test', stderr=stderr), None)
assert match(Command('./manage.py migrate', stderr=stderr))
assert match(Command('python manage.py migrate', stderr=stderr))
assert not match(Command('./manage.py migrate'))
assert not match(Command('app migrate', stderr=stderr))
assert not match(Command('./manage.py test', stderr=stderr))
def test_get_new_command():
assert get_new_command(Command('./manage.py migrate auth'), None)\
assert get_new_command(Command('./manage.py migrate auth'))\
== './manage.py migrate auth --delete-ghost-migrations'

View File

@ -31,13 +31,13 @@ The following options are available:
def test_match(stderr):
assert match(Command('./manage.py migrate', stderr=stderr), None)
assert match(Command('python manage.py migrate', stderr=stderr), None)
assert not match(Command('./manage.py migrate'), None)
assert not match(Command('app migrate', stderr=stderr), None)
assert not match(Command('./manage.py test', stderr=stderr), None)
assert match(Command('./manage.py migrate', stderr=stderr))
assert match(Command('python manage.py migrate', stderr=stderr))
assert not match(Command('./manage.py migrate'))
assert not match(Command('app migrate', stderr=stderr))
assert not match(Command('./manage.py test', stderr=stderr))
def test_get_new_command():
assert get_new_command(Command('./manage.py migrate auth'), None) \
assert get_new_command(Command('./manage.py migrate auth')) \
== './manage.py migrate auth --merge'

View File

@ -110,14 +110,14 @@ def stderr(cmd):
def test_match():
assert match(Command('docker pes', stderr=stderr('pes')), None)
assert match(Command('docker pes', stderr=stderr('pes')))
@pytest.mark.parametrize('script, stderr', [
('docker ps', ''),
('cat pes', stderr('pes'))])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr), None)
assert not match(Command(script, stderr=stderr))
@pytest.mark.usefixtures('docker_help')
@ -126,4 +126,4 @@ def test_not_match(script, stderr):
('tags', ['tag', 'stats', 'images'])])
def test_get_new_command(wrong, fixed):
command = Command('docker {}'.format(wrong), stderr=stderr(wrong))
assert get_new_command(command, None) == ['docker {}'.format(x) for x in fixed]
assert get_new_command(command) == ['docker {}'.format(x) for x in fixed]

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='cd cd foo'),
Command(script='git git push origin/master')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('cd cd foo'), 'cd foo'),
(Command('git git push origin/master'), 'git push origin/master')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -11,12 +11,12 @@ def test_match():
"""
assert match(Command(u'ps -ef | grep foo',
stderr=u'-bash:  grep: command not found'), None)
assert not match(Command('ps -ef | grep foo'), None)
assert not match(Command(), None)
stderr=u'-bash:  grep: command not found'))
assert not match(Command('ps -ef | grep foo'))
assert not match(Command())
def test_get_new_command():
""" Replace the Alt+Space character by a simple space """
assert get_new_command(Command(u'ps -ef | grep foo'), None)\
assert get_new_command(Command(u'ps -ef | grep foo'))\
== 'ps -ef | grep foo'

View File

@ -184,7 +184,7 @@ E NameError: name 'mocker' is not defined
def test_match(mocker, monkeypatch, test):
mocker.patch('os.path.isfile', return_value=True)
monkeypatch.setenv('EDITOR', 'dummy_editor')
assert match(Command(stdout=test[4], stderr=test[5]), None)
assert match(Command(stdout=test[4], stderr=test[5]))
@pytest.mark.parametrize('test', tests)
@ -194,7 +194,7 @@ def test_no_editor(mocker, monkeypatch, test):
if 'EDITOR' in os.environ:
monkeypatch.delenv('EDITOR')
assert not match(Command(stdout=test[4], stderr=test[5]), None)
assert not match(Command(stdout=test[4], stderr=test[5]))
@pytest.mark.parametrize('test', tests)
@ -203,7 +203,7 @@ def test_not_file(mocker, monkeypatch, test):
mocker.patch('os.path.isfile', return_value=False)
monkeypatch.setenv('EDITOR', 'dummy_editor')
assert not match(Command(stdout=test[4], stderr=test[5]), None)
assert not match(Command(stdout=test[4], stderr=test[5]))
@pytest.mark.parametrize('test', tests)
@ -219,16 +219,16 @@ def test_get_new_command(mocker, monkeypatch, test):
@pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize')
def test_get_new_command_with_settings(mocker, monkeypatch, test):
def test_get_new_command_with_settings(mocker, monkeypatch, test, settings):
mocker.patch('os.path.isfile', return_value=True)
monkeypatch.setenv('EDITOR', 'dummy_editor')
cmd = Command(script=test[0], stdout=test[4], stderr=test[5])
settings = Settings({'fixcolcmd': '{editor} {file} +{line}:{col}'})
settings.fixcolcmd = '{editor} {file} +{line}:{col}'
if test[3]:
assert (get_new_command(cmd, settings) ==
assert (get_new_command(cmd) ==
'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0]))
else:
assert (get_new_command(cmd, settings) ==
assert (get_new_command(cmd) ==
'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))

View File

@ -18,7 +18,7 @@ def did_not_match(target, did_you_forget=True):
Command(script='git commit unknown',
stderr=did_not_match('unknown'))]) # Older versions of Git
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -27,7 +27,7 @@ def test_match(command):
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)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -36,4 +36,4 @@ def test_not_match(command):
(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
assert get_new_command(command) == new_command

View File

@ -12,11 +12,11 @@ If you are sure you want to delete it, run 'git branch -D branch'.
def test_match(stderr):
assert match(Command('git branch -d branch', stderr=stderr), None)
assert not match(Command('git branch -d branch'), None)
assert not match(Command('ls', stderr=stderr), None)
assert match(Command('git branch -d branch', stderr=stderr))
assert not match(Command('git branch -d branch'))
assert not match(Command('ls', stderr=stderr))
def test_get_new_command(stderr):
assert get_new_command(Command('git branch -d branch', stderr=stderr), None)\
assert get_new_command(Command('git branch -d branch', stderr=stderr))\
== "git branch -D branch"

View File

@ -4,16 +4,16 @@ from tests.utils import Command
def test_match():
assert match(Command('git branch list'), None)
assert match(Command('git branch list'))
def test_not_match():
assert not match(Command(), None)
assert not match(Command('git commit'), None)
assert not match(Command('git branch'), None)
assert not match(Command('git stash list'), None)
assert not match(Command())
assert not match(Command('git commit'))
assert not match(Command('git branch'))
assert not match(Command('git stash list'))
def test_get_new_command():
assert (get_new_command(Command('git branch list'), None) ==
assert (get_new_command(Command('git branch list')) ==
shells.and_('git branch --delete list', 'git branch'))

View File

@ -21,7 +21,7 @@ def get_branches(mocker):
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)
assert match(command)
@pytest.mark.parametrize('command', [
@ -30,7 +30,7 @@ def test_match(command):
Command(script='git checkout known', stderr=('')),
Command(script='git commit known', stderr=(''))])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('branches, command, new_command', [
@ -50,4 +50,4 @@ def test_not_match(command):
'git commit test-random-branch-123')])
def test_get_new_command(branches, command, new_command, get_branches):
get_branches.return_value = branches
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -7,7 +7,7 @@ from tests.utils import Command
Command(script='git diff foo'),
Command(script='git diff')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -16,11 +16,11 @@ def test_match(command):
Command(script='git branch'),
Command(script='git log')])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('git diff'), 'git diff --staged'),
(Command('git diff foo'), 'git diff --staged foo')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -20,7 +20,7 @@ usage: git stash list [<options>]
'git stash Some message',
'git stash saev Some message'])
def test_match(wrong):
assert match(Command(wrong, stderr=git_stash_err), None)
assert match(Command(wrong, stderr=git_stash_err))
@pytest.mark.parametrize('wrong,fixed', [
@ -28,4 +28,4 @@ def test_match(wrong):
('git stash Some message', 'git stash save Some message'),
('git stash saev Some message', 'git stash save Some message')])
def test_get_new_command(wrong, fixed):
assert get_new_command(Command(wrong, stderr=git_stash_err), None) == fixed
assert get_new_command(Command(wrong, stderr=git_stash_err)) == fixed

View File

@ -41,17 +41,17 @@ def git_command():
def test_match(git_not_command, git_command, git_not_command_one_of_this):
assert match(Command('git brnch', stderr=git_not_command), None)
assert match(Command('git st', stderr=git_not_command_one_of_this), None)
assert not match(Command('ls brnch', stderr=git_not_command), None)
assert not match(Command('git branch', stderr=git_command), None)
assert match(Command('git brnch', stderr=git_not_command))
assert match(Command('git st', stderr=git_not_command_one_of_this))
assert not match(Command('ls brnch', stderr=git_not_command))
assert not match(Command('git branch', stderr=git_command))
def test_get_new_command(git_not_command, git_not_command_one_of_this,
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)) \
== ['git branch']
assert get_new_command(Command('git st', stderr=git_not_command_one_of_this),
None) == ['git stats', 'git stash', 'git stage']
assert get_new_command(Command('git tags', stderr=git_not_command_closest),
None) == ['git tag', 'git stage']
assert get_new_command(Command('git st', stderr=git_not_command_one_of_this)) \
== ['git stats', 'git stash', 'git stage']
assert get_new_command(Command('git tags', stderr=git_not_command_closest)) \
== ['git tag', 'git stage']

View File

@ -19,11 +19,11 @@ If you wish to set tracking information for this branch you can do so with:
def test_match(stderr):
assert match(Command('git pull', stderr=stderr), None)
assert not match(Command('git pull'), None)
assert not match(Command('ls', stderr=stderr), None)
assert match(Command('git pull', stderr=stderr))
assert not match(Command('git pull'))
assert not match(Command('ls', stderr=stderr))
def test_get_new_command(stderr):
assert get_new_command(Command('git pull', stderr=stderr), None) \
assert get_new_command(Command('git pull', stderr=stderr)) \
== "git branch --set-upstream-to=origin/master master && git pull"

View File

@ -12,10 +12,10 @@ Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
@pytest.mark.parametrize('command', [
Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err)])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, output', [
(Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err), 'git clone git@github.com:mcarton/thefuck.git')])
def test_get_new_command(command, output):
assert get_new_command(command, None) == output
assert get_new_command(command) == output

View File

@ -14,11 +14,11 @@ To push the current branch and set the remote as upstream, use
def test_match(stderr):
assert match(Command('git push master', stderr=stderr), None)
assert not match(Command('git push master'), None)
assert not match(Command('ls', stderr=stderr), None)
assert match(Command('git push master', stderr=stderr))
assert not match(Command('git push master'))
assert not match(Command('ls', stderr=stderr))
def test_get_new_command(stderr):
assert get_new_command(Command('git push', stderr=stderr), None)\
assert get_new_command(Command('git push', stderr=stderr))\
== "git push --set-upstream origin master"

View File

@ -30,7 +30,7 @@ To /tmp/bar
Command(script='git push nvbn', stderr=git_err),
Command(script='git push nvbn master', stderr=git_err)])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -41,7 +41,7 @@ def test_match(command):
Command(script='git push nvbn', stderr=git_ok),
Command(script='git push nvbn master', stderr=git_uptodate)])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, output', [
@ -49,4 +49,4 @@ def test_not_match(command):
(Command(script='git push nvbn', stderr=git_err), 'git push --force nvbn'),
(Command(script='git push nvbn master', stderr=git_err), 'git push --force nvbn master')])
def test_get_new_command(command, output):
assert get_new_command(command, None) == output
assert get_new_command(command) == output

View File

@ -30,7 +30,7 @@ To /tmp/bar
Command(script='git push nvbn', stderr=git_err),
Command(script='git push nvbn master', stderr=git_err)])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -41,7 +41,7 @@ def test_match(command):
Command(script='git push nvbn', stderr=git_ok),
Command(script='git push nvbn master', stderr=git_uptodate)])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, output', [
@ -51,4 +51,4 @@ def test_not_match(command):
(Command(script='git push nvbn master', stderr=git_err),
'git pull nvbn master && git push nvbn master')])
def test_get_new_command(command, output):
assert get_new_command(command, None) == output
assert get_new_command(command) == output

View File

@ -18,14 +18,14 @@ rebase_error = (
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)
assert match(command)
@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)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -34,4 +34,4 @@ def test_not_match(command):
(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
assert get_new_command(command) == new_command

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='go run foo'),
Command(script='go run bar')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('go run foo'), 'go run foo.go'),
(Command('go run bar'), 'go run bar.go')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match():
assert match(Command('grep blah .', stderr='grep: .: Is a directory'), None)
assert not match(Command(), None)
assert match(Command('grep blah .', stderr='grep: .: Is a directory'))
assert not match(Command())
def test_get_new_command():
assert get_new_command(
Command('grep blah .'), None) == 'grep -r blah .'
Command('grep blah .')) == 'grep -r blah .'

View File

@ -11,18 +11,18 @@ def stdout(task):
def test_match():
assert match(Command('gulp srve', stdout('srve')), None)
assert match(Command('gulp srve', stdout('srve')))
@pytest.mark.parametrize('script, stdout', [
('gulp serve', ''),
('cat srve', stdout('srve'))])
def test_not_march(script, stdout):
assert not match(Command(script, stdout), None)
assert not match(Command(script, stdout))
def test_get_new_command(mocker):
mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[
'serve', 'build', 'default'])
command = Command('gulp srve', stdout('srve'))
assert get_new_command(command, None) == ['gulp serve', 'gulp default']
assert get_new_command(command) == ['gulp serve', 'gulp default']

View File

@ -4,17 +4,14 @@ from thefuck.rules.has_exists_script import match, get_new_command
def test_match():
with patch('os.path.exists', return_value=True):
assert match(Mock(script='main', stderr='main: command not found'),
None)
assert match(Mock(script='main', stderr='main: command not found'))
assert match(Mock(script='main --help',
stderr='main: command not found'),
None)
assert not match(Mock(script='main', stderr=''), None)
stderr='main: command not found'))
assert not match(Mock(script='main', stderr=''))
with patch('os.path.exists', return_value=False):
assert not match(Mock(script='main', stderr='main: command not found'),
None)
assert not match(Mock(script='main', stderr='main: command not found'))
def test_get_new_command():
assert get_new_command(Mock(script='main --help'), None) == './main --help'
assert get_new_command(Mock(script='main --help')) == './main --help'

View File

@ -16,14 +16,14 @@ no_suggest_stderr = ''' ! `aaaaa` is not a heroku command.
@pytest.mark.parametrize('cmd', ['log', 'pge'])
def test_match(cmd):
assert match(
Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)), None)
Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)))
@pytest.mark.parametrize('script, stderr', [
('cat log', suggest_stderr('log')),
('heroku aaa', no_suggest_stderr)])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr), None)
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('cmd, result', [
@ -31,4 +31,4 @@ def test_not_match(script, stderr):
('pge', ['heroku pg', 'heroku logs'])])
def test_get_new_command(cmd, result):
command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd))
assert get_new_command(command, None) == result
assert get_new_command(command) == result

View File

@ -25,13 +25,13 @@ def callables(mocker):
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
@pytest.mark.parametrize('script', ['ls cet', 'daff x'])
def test_match(script):
assert match(Command(script=script), None)
assert match(Command(script=script))
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
@pytest.mark.parametrize('script', ['apt-get', 'nocommand y'])
def test_not_match(script):
assert not match(Command(script=script), None)
assert not match(Command(script=script))
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
@ -39,4 +39,4 @@ def test_not_match(script):
('ls cet', 'ls cat'),
('daff x', 'diff x')])
def test_get_new_command(script, result):
assert get_new_command(Command(script), None) == result
assert get_new_command(Command(script)) == result

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='java foo.java'),
Command(script='java bar.java')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('java foo.java'), 'java foo'),
(Command('java bar.java'), 'java bar')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='javac foo'),
Command(script='javac bar')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('javac foo'), 'javac foo.java'),
(Command('javac bar'), 'javac bar.java')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -14,10 +14,10 @@ Did you mean this?
def test_match(is_not_task):
assert match(Command(script='lein rpl', stderr=is_not_task), None)
assert not match(Command(script='ls', stderr=is_not_task), None)
assert match(Command(script='lein rpl', stderr=is_not_task))
assert not match(Command(script='ls', stderr=is_not_task))
def test_get_new_command(is_not_task):
assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task),
None) == ['lein repl --help', 'lein jar --help']
assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task)) \
== ['lein repl --help', 'lein jar --help']

View File

@ -3,14 +3,14 @@ from tests.utils import Command
def test_match():
assert match(Command(script='ls'), None)
assert match(Command(script='ls file.py'), None)
assert match(Command(script='ls /opt'), None)
assert not match(Command(script='ls -lah /opt'), None)
assert not match(Command(script='pacman -S binutils'), None)
assert not match(Command(script='lsof'), None)
assert match(Command(script='ls'))
assert match(Command(script='ls file.py'))
assert match(Command(script='ls /opt'))
assert not match(Command(script='ls -lah /opt'))
assert not match(Command(script='pacman -S binutils'))
assert not match(Command(script='lsof'))
def test_get_new_command():
assert get_new_command(Command(script='ls file.py'), None) == 'ls -lah file.py'
assert get_new_command(Command(script='ls'), None) == 'ls -lah'
assert get_new_command(Command(script='ls file.py')) == 'ls -lah file.py'
assert get_new_command(Command(script='ls')) == 'ls -lah'

View File

@ -12,14 +12,14 @@ from tests.utils import Command
Command('man -s 2 read'),
Command('man -s 3 read')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
Command('man'),
Command('man ')])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -31,4 +31,4 @@ def test_not_match(command):
(Command('man -s 2 read'), 'man -s 3 read'),
(Command('man -s 3 read'), 'man -s 2 read')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match():
assert match(Command('mandiff', stderr='mandiff: command not found'), None)
assert not match(Command(), None)
assert match(Command('mandiff', stderr='mandiff: command not found'))
assert not match(Command())
def test_get_new_command():
assert get_new_command(
Command('mandiff'), None) == 'man diff'
Command('mandiff')) == 'man diff'

View File

@ -37,7 +37,7 @@ from thefuck.rules.mercurial import (
)),
])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -63,7 +63,7 @@ def test_match(command):
)),
])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, possibilities', [
@ -131,4 +131,4 @@ def test_extract_possibilities(command, possibilities):
)), 'hg rebase re'),
])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -9,7 +9,7 @@ from tests.utils import Command
Command('hdfs dfs -mkdir foo/bar/baz', stderr='mkdir: `foo/bar/baz\': No such file or directory')
])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -19,7 +19,7 @@ def test_match(command):
Command('./bin/hdfs dfs -mkdir foo/bar/baz'),
Command()])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -27,5 +27,5 @@ def test_not_match(command):
(Command('hdfs dfs -mkdir foo/bar/baz'), 'hdfs dfs -mkdir -p foo/bar/baz'),
(Command('./bin/hdfs dfs -mkdir foo/bar/baz'), './bin/hdfs dfs -mkdir -p foo/bar/baz')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -6,7 +6,7 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -30,11 +30,11 @@ def test_match(command):
Command(script='mvn -v')
])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
(Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean package', 'mvn clean install']),
(Command(script='mvn -N', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn -N clean package', 'mvn -N clean install'])])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -6,7 +6,7 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -30,11 +30,11 @@ def test_match(command):
Command(script='mvn -v')
])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
(Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean', 'mvn compile']),
(Command(script='mvn claen package', stdout='[ERROR] Unknown lifecycle phase "claen". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean package'])])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -11,19 +11,17 @@ def get_all_executables(mocker):
@pytest.mark.usefixtures('no_memoize')
def test_match():
assert match(Command(stderr='vom: not found', script='vom file.py'), None)
assert match(Command(stderr='fucck: not found', script='fucck'), None)
assert not match(Command(stderr='qweqwe: not found', script='qweqwe'), None)
assert not match(Command(stderr='some text', script='vom file.py'), None)
assert match(Command(stderr='vom: not found', script='vom file.py'))
assert match(Command(stderr='fucck: not found', script='fucck'))
assert not match(Command(stderr='qweqwe: not found', script='qweqwe'))
assert not match(Command(stderr='some text', script='vom file.py'))
@pytest.mark.usefixtures('no_memoize')
def test_get_new_command():
assert get_new_command(
Command(stderr='vom: not found',
script='vom file.py'),
None) == ['vim file.py']
script='vom file.py')) == ['vim file.py']
assert get_new_command(
Command(stderr='fucck: not found',
script='fucck'),
Command) == ['fsck']
script='fucck')) == ['fsck']

View File

@ -8,7 +8,7 @@ from tests.utils import Command
Command(script='mv foo bar/', stderr="mv: cannot move 'foo' to 'bar/': No such file or directory"),
])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -16,7 +16,7 @@ def test_match(command):
Command(script='mv foo bar/foo', stderr="mv: permission denied"),
])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -24,4 +24,4 @@ def test_not_match(command):
(Command(script='mv foo bar/', stderr="mv: cannot move 'foo' to 'bar/': No such file or directory"), 'mkdir -p bar && mv foo bar/'),
])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -14,7 +14,7 @@ from tests.utils import Command
Command(script='gnome-open foo.com'),
Command(script='kde-open foo.com')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
@ -28,4 +28,4 @@ def test_match(command):
(Command('gnome-open foo.io'), 'gnome-open http://foo.io'),
(Command('kde-open foo.io'), 'kde-open http://foo.io')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -23,7 +23,7 @@ extra/vim-python3 7.4.712-1 \t/usr/bin/vim'''
Command(script='vim', stderr='vim: command not found'),
Command(script='sudo vim', stderr='sudo: vim: command not found')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, return_value', [
@ -33,14 +33,14 @@ def test_match(command):
@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 match(command)
@pytest.mark.parametrize('command', [
Command(script='vim', stderr=''), Command(),
Command(script='sudo vim', stderr=''), Command()])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
sudo_vim_possibilities = ['{} -S extra/gvim && sudo vim',
@ -66,7 +66,7 @@ vim_possibilities = [s.format(pacman_cmd) for s in vim_possibilities]
(Command('convert'), ['{} -S extra/imagemagick && convert'.format(pacman_cmd)]),
(Command('sudo convert'), ['{} -S extra/imagemagick && sudo convert'.format(pacman_cmd)])])
def test_get_new_command(command, new_command, mocker):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command
@pytest.mark.parametrize('command, new_command, return_value', [
@ -79,4 +79,4 @@ def test_get_new_command(command, new_command, mocker):
@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 get_new_command(command) == new_command

View File

@ -15,7 +15,7 @@ extra/llvm35 3.5.2-13/usr/bin/llc'''
Command(script='pacman llc', stderr='error: target not found: llc'),
Command(script='sudo pacman llc', stderr='error: target not found: llc')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -25,7 +25,7 @@ def test_match(command):
@patch('thefuck.specific.archlinux.subprocess')
def test_match_mocked(subp_mock, command):
subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC
assert match(command, None)
assert match(command)
@pytest.mark.skipif(not getattr(pacman_not_found, 'enabled_by_default', True),
@ -35,7 +35,7 @@ def test_match_mocked(subp_mock, command):
(Command(script='pacman -S llc', stderr='error: target not found: llc'), ['pacman -S extra/llvm', 'pacman -S extra/llvm35']),
(Command(script='sudo pacman -S llc', stderr='error: target not found: llc'), ['sudo pacman -S extra/llvm', 'sudo pacman -S extra/llvm35'])])
def test_get_new_command(command, fixed):
assert get_new_command(command, None) == fixed
assert get_new_command(command) == fixed
@pytest.mark.parametrize('command, fixed', [
@ -45,4 +45,4 @@ def test_get_new_command(command, fixed):
@patch('thefuck.specific.archlinux.subprocess')
def test_get_new_command_mocked(subp_mock, command, fixed):
subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC
assert get_new_command(command, None) == fixed
assert get_new_command(command) == fixed

View File

@ -14,12 +14,11 @@ def pip_unknown_cmd_without_recommend():
def test_match(pip_unknown_cmd, pip_unknown_cmd_without_recommend):
assert match(Command('pip instatl', stderr=pip_unknown_cmd), None)
assert match(Command('pip instatl', stderr=pip_unknown_cmd))
assert not match(Command('pip i',
stderr=pip_unknown_cmd_without_recommend),
None)
stderr=pip_unknown_cmd_without_recommend))
def test_get_new_command(pip_unknown_cmd):
assert get_new_command(Command('pip instatl', stderr=pip_unknown_cmd),
None) == 'pip install'
assert get_new_command(Command('pip instatl',
stderr=pip_unknown_cmd)) == 'pip install'

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match():
assert match(Command('temp.py', stderr='Permission denied'), None)
assert not match(Command(), None)
assert match(Command('temp.py', stderr='Permission denied'))
assert not match(Command())
def test_get_new_command():
assert get_new_command(Command('./test_sudo.py'), None)\
assert get_new_command(Command('./test_sudo.py'))\
== 'python ./test_sudo.py'

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='python foo'),
Command(script='python bar')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('python foo'), 'python foo.py'),
(Command('python bar'), 'python bar.py')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -8,7 +8,7 @@ from tests.utils import Command
Command(script="git commit -am \"Mismatched Quotation Marks\'"),
Command(script="echo \"hello\'")])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command, new_command', [
@ -16,4 +16,4 @@ def test_match(command):
(Command("git commit -am \"Mismatched Quotation Marks\'"), "git commit -am \"Mismatched Quotation Marks\""),
(Command("echo \"hello\'"), "echo \"hello\"")])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -10,7 +10,7 @@ from tests.utils import Command
Command('./bin/hdfs dfs -rm foo', stderr='rm: `foo`: Is a directory')
])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -19,13 +19,13 @@ def test_match(command):
Command('./bin/hdfs dfs -rm foo'),
Command()])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('rm foo'), 'rm -rf foo'),
(Command('hdfs dfs -rm foo'), 'hdfs dfs -rm -r foo')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -5,7 +5,7 @@ from tests.utils import Command
def test_match():
assert match(Command(script='rm -rf /',
stderr='add --no-preserve-root'), None)
stderr='add --no-preserve-root'))
@pytest.mark.parametrize('command', [
@ -13,9 +13,9 @@ def test_match():
Command(script='rm --no-preserve-root /', stderr='add --no-preserve-root'),
Command(script='rm -rf /', stderr='')])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
def test_get_new_command():
assert get_new_command(Command(script='rm -rf /'), None) \
assert get_new_command(Command(script='rm -rf /')) \
== 'rm -rf / --no-preserve-root'

View File

@ -9,20 +9,20 @@ def sed_unterminated_s():
def test_match(sed_unterminated_s):
assert match(Command('sed -e s/foo/bar', stderr=sed_unterminated_s), None)
assert match(Command('sed -es/foo/bar', stderr=sed_unterminated_s), None)
assert match(Command('sed -e s/foo/bar -e s/baz/quz', stderr=sed_unterminated_s), None)
assert not match(Command('sed -e s/foo/bar'), None)
assert not match(Command('sed -es/foo/bar'), None)
assert not match(Command('sed -e s/foo/bar -e s/baz/quz'), None)
assert match(Command('sed -e s/foo/bar', stderr=sed_unterminated_s))
assert match(Command('sed -es/foo/bar', stderr=sed_unterminated_s))
assert match(Command('sed -e s/foo/bar -e s/baz/quz', stderr=sed_unterminated_s))
assert not match(Command('sed -e s/foo/bar'))
assert not match(Command('sed -es/foo/bar'))
assert not match(Command('sed -e s/foo/bar -e s/baz/quz'))
def test_get_new_command(sed_unterminated_s):
assert get_new_command(Command('sed -e s/foo/bar', stderr=sed_unterminated_s), None) \
assert get_new_command(Command('sed -e s/foo/bar', stderr=sed_unterminated_s)) \
== 'sed -e s/foo/bar/'
assert get_new_command(Command('sed -es/foo/bar', stderr=sed_unterminated_s), None) \
assert get_new_command(Command('sed -es/foo/bar', stderr=sed_unterminated_s)) \
== 'sed -es/foo/bar/'
assert get_new_command(Command(r"sed -e 's/\/foo/bar'", stderr=sed_unterminated_s), None) \
assert get_new_command(Command(r"sed -e 's/\/foo/bar'", stderr=sed_unterminated_s)) \
== r"sed -e 's/\/foo/bar/'"
assert get_new_command(Command(r"sed -e s/foo/bar -es/baz/quz", stderr=sed_unterminated_s), None) \
assert get_new_command(Command(r"sed -e s/foo/bar -es/baz/quz", stderr=sed_unterminated_s)) \
== r"sed -e s/foo/bar/ -es/baz/quz/"

View File

@ -4,9 +4,9 @@ from tests.utils import Command
def test_match():
assert match(Command('sl'), None)
assert not match(Command('ls'), None)
assert match(Command('sl'))
assert not match(Command('ls'))
def test_get_new_command():
assert get_new_command(Command('sl'), None) == 'ls'
assert get_new_command(Command('sl')) == 'ls'

View File

@ -44,23 +44,23 @@ Host key verification failed.""".format(path, '98.765.432.321')
def test_match(ssh_error):
errormsg, _, _, _ = ssh_error
assert match(Command('ssh', stderr=errormsg), None)
assert match(Command('ssh', stderr=errormsg), None)
assert match(Command('scp something something', stderr=errormsg), None)
assert match(Command('scp something something', stderr=errormsg), None)
assert not match(Command(stderr=errormsg), None)
assert not match(Command('notssh', stderr=errormsg), None)
assert not match(Command('ssh'), None)
assert match(Command('ssh', stderr=errormsg))
assert match(Command('ssh', stderr=errormsg))
assert match(Command('scp something something', stderr=errormsg))
assert match(Command('scp something something', stderr=errormsg))
assert not match(Command(stderr=errormsg))
assert not match(Command('notssh', stderr=errormsg))
assert not match(Command('ssh'))
def test_side_effect(ssh_error):
errormsg, path, reset, known_hosts = ssh_error
command = Command('ssh user@host', stderr=errormsg)
side_effect(command, None, None)
side_effect(command, None)
expected = ['123.234.567.890 asdjkasjdakjsd\n', '111.222.333.444 qwepoiwqepoiss\n']
assert known_hosts(path) == expected
def test_get_new_command(ssh_error, monkeypatch):
errormsg, _, _, _ = ssh_error
assert get_new_command(Command('ssh user@host', stderr=errormsg), None) == 'ssh user@host'
assert get_new_command(Command('ssh user@host', stderr=errormsg)) == 'ssh user@host'

View File

@ -14,11 +14,11 @@ from tests.utils import Command
('You don\'t have access to the history DB.', ''),
('', "error: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/ipaddr.py'")])
def test_match(stderr, stdout):
assert match(Command(stderr=stderr, stdout=stdout), None)
assert match(Command(stderr=stderr, stdout=stdout))
def test_not_match():
assert not match(Command(), None)
assert not match(Command())
@pytest.mark.parametrize('before, after', [
@ -26,4 +26,4 @@ def test_not_match():
('echo a > b', 'sudo sh -c "echo a > b"'),
('echo "a" >> b', 'sudo sh -c "echo \\"a\\" >> b"')])
def test_get_new_command(before, after):
assert get_new_command(Command(before), None) == after
assert get_new_command(Command(before)) == after

View File

@ -9,7 +9,7 @@ from tests.utils import Command
Command(stderr='command not found: фзе-пуе', script=u'фзе-пуе'),
Command(stderr='command not found: λσ', script=u'λσ')])
def test_match(command):
assert switch_lang.match(command, None)
assert switch_lang.match(command)
@pytest.mark.parametrize('command', [
@ -18,11 +18,11 @@ def test_match(command):
Command(stderr='command not found: агсл', script=u'агсл'),
Command(stderr='some info', script=u'фзе-пуе')])
def test_not_match(command):
assert not switch_lang.match(command, None)
assert not switch_lang.match(command)
@pytest.mark.parametrize('command, new_command', [
(Command(u'фзе-пуе штыефдд мшь'), 'apt-get install vim'),
(Command(u'λσ -λα'), 'ls -la')])
def test_get_new_command(command, new_command):
assert switch_lang.get_new_command(command, None) == new_command
assert switch_lang.get_new_command(command) == new_command

View File

@ -4,15 +4,15 @@ from tests.utils import Command
def test_match():
assert match(Command('systemctl nginx start', stderr='Unknown operation \'nginx\'.'), None)
assert match(Command('sudo systemctl nginx start', stderr='Unknown operation \'nginx\'.'), None)
assert not match(Command('systemctl start nginx'), None)
assert not match(Command('systemctl start nginx'), None)
assert not match(Command('sudo systemctl nginx', stderr='Unknown operation \'nginx\'.'), None)
assert not match(Command('systemctl nginx', stderr='Unknown operation \'nginx\'.'), None)
assert not match(Command('systemctl start wtf', stderr='Failed to start wtf.service: Unit wtf.service failed to load: No such file or directory.'), None)
assert match(Command('systemctl nginx start', stderr='Unknown operation \'nginx\'.'))
assert match(Command('sudo systemctl nginx start', stderr='Unknown operation \'nginx\'.'))
assert not match(Command('systemctl start nginx'))
assert not match(Command('systemctl start nginx'))
assert not match(Command('sudo systemctl nginx', stderr='Unknown operation \'nginx\'.'))
assert not match(Command('systemctl nginx', stderr='Unknown operation \'nginx\'.'))
assert not match(Command('systemctl start wtf', stderr='Failed to start wtf.service: Unit wtf.service failed to load: No such file or directory.'))
def test_get_new_command():
assert get_new_command(Command('systemctl nginx start'), None) == "systemctl start nginx"
assert get_new_command(Command('sudo systemctl nginx start'), None) == "sudo systemctl start nginx"
assert get_new_command(Command('systemctl nginx start')) == "systemctl start nginx"
assert get_new_command(Command('sudo systemctl nginx start')) == "sudo systemctl start nginx"

View File

@ -11,9 +11,9 @@ def tmux_ambiguous():
def test_match(tmux_ambiguous):
assert match(Command('tmux list', stderr=tmux_ambiguous), None)
assert match(Command('tmux list', stderr=tmux_ambiguous))
def test_get_new_command(tmux_ambiguous):
assert get_new_command(Command('tmux list', stderr=tmux_ambiguous), None)\
assert get_new_command(Command('tmux list', stderr=tmux_ambiguous))\
== ['tmux list-keys', 'tmux list-panes', 'tmux list-windows']

View File

@ -15,7 +15,7 @@ error_msg = (
Command(script='tsuru app-log -f', stderr=error_msg[1]),
])
def test_match(command):
assert match(command, {})
assert match(command)
@pytest.mark.parametrize('command', [
@ -24,7 +24,7 @@ def test_match(command):
Command(script='tsuru app-log -f', stderr=('Error: unparseable data')),
])
def test_not_match(command):
assert not match(command, {})
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -34,4 +34,4 @@ def test_not_match(command):
'tsuru login && tsuru app-log -f'),
])
def test_get_new_command(command, new_command):
assert get_new_command(command, {}) == new_command
assert get_new_command(command) == new_command

View File

@ -30,7 +30,7 @@ from thefuck.rules.tsuru_not_command import match, get_new_command
)),
])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -58,7 +58,7 @@ def test_match(command):
Command('tsuru env-get', stderr='Error: App thefuck not found.'),
])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_commands', [
@ -87,4 +87,4 @@ def test_not_match(command):
)), ['tsuru target-list']),
])
def test_get_new_command(command, new_commands):
assert get_new_command(command, None) == new_commands
assert get_new_command(command) == new_commands

View File

@ -9,7 +9,7 @@ from tests.utils import Command
stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'),
Command(script='hdfs dfs ls /foo/bar', stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -18,7 +18,7 @@ def test_match(command):
Command(script='hdfs dfs -ls -R /foo/bar', stderr=''),
Command()])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -31,5 +31,5 @@ def test_not_match(command):
(Command('./bin/hdfs dfs -Dtest=fred ls -R /foo/bar',
stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), ['./bin/hdfs dfs -Dtest=fred -ls -R /foo/bar'])])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -11,7 +11,7 @@ from tests.utils import Command
Command(script='vagrant rdp devbox',
stderr='VM must be created before running this command. Run `vagrant up` first.')])
def test_match(command):
assert match(command, None)
assert match(command)
@pytest.mark.parametrize('command', [
@ -20,7 +20,7 @@ def test_match(command):
Command(script='vagrant ssh', stderr='A Vagrant environment or target machine is required to run this command. Run `vagrant init` to create a new Vagrant environment. Or, get an ID of a target machine from `vagrant global-status` to run this command on. A final option is to change to a directory with a Vagrantfile and to try again.'),
Command()])
def test_not_match(command):
assert not match(command, None)
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
@ -31,5 +31,5 @@ def test_not_match(command):
(Command(script='vagrant rdp devbox',
stderr='VM must be created before running this command. Run `vagrant up` first.'), ['vagrant up devbox && vagrant rdp devbox', 'vagrant up && vagrant rdp devbox'])])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -8,11 +8,11 @@ from tests.utils import Command
Command(script='whois https://en.wikipedia.org/'),
Command(script='whois meta.unix.stackexchange.com')])
def test_match(command):
assert match(command, None)
assert match(command)
def test_not_match():
assert not match(Command(script='whois'), None)
assert not match(Command(script='whois'))
# `whois com` actually makes sense
@ -23,4 +23,4 @@ def test_not_match():
'whois stackexchange.com',
'whois com'])])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command
assert get_new_command(command) == new_command

View File

@ -9,9 +9,10 @@ from tests.utils import Command
"19:23:25.470911 git.c:282 trace: alias expansion: com => 'commit' '--verbose'")])
def test_git_support(called, command, stderr):
@git_support
def fn(command, settings): return command.script
def fn(command):
return command.script
assert fn(Command(script=called, stderr=stderr), None) == command
assert fn(Command(script=called, stderr=stderr)) == command
@pytest.mark.parametrize('command, is_git', [
@ -24,6 +25,7 @@ def test_git_support(called, command, stderr):
('cat hub', False)])
def test_git_support_match(command, is_git):
@git_support
def fn(command, settings): return True
def fn(command):
return True
assert fn(Command(script=command), None) == is_git
assert fn(Command(script=command)) == is_git

View File

@ -13,8 +13,8 @@ from tests.utils import Command
(False, 'sudo ls', 'ls', False),
(False, 'ls', 'ls', False)])
def test_sudo_support(return_value, command, called, result):
def fn(command, settings):
def fn(command):
assert command == Command(called)
return return_value
assert sudo_support(fn)(Command(command), None) == result
assert sudo_support(fn)(Command(command)) == result

View File

@ -26,22 +26,23 @@ def environ(monkeypatch):
@pytest.mark.usefixture('environ')
def test_settings_defaults(load_source):
def test_settings_defaults(load_source, settings):
load_source.return_value = object()
conf.init_settings(Mock())
for key, val in conf.DEFAULT_SETTINGS.items():
assert getattr(conf.get_settings(Mock()), key) == val
assert getattr(settings, key) == val
@pytest.mark.usefixture('environ')
class TestSettingsFromFile(object):
def test_from_file(self, load_source):
def test_from_file(self, load_source, settings):
load_source.return_value = Mock(rules=['test'],
wait_command=10,
require_confirmation=True,
no_colors=True,
priority={'vim': 100},
exclude_rules=['git'])
settings = conf.get_settings(Mock())
conf.init_settings(Mock())
assert settings.rules == ['test']
assert settings.wait_command == 10
assert settings.require_confirmation is True
@ -49,26 +50,26 @@ class TestSettingsFromFile(object):
assert settings.priority == {'vim': 100}
assert settings.exclude_rules == ['git']
def test_from_file_with_DEFAULT(self, load_source):
def test_from_file_with_DEFAULT(self, load_source, settings):
load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'],
wait_command=10,
exclude_rules=[],
require_confirmation=True,
no_colors=True)
settings = conf.get_settings(Mock())
conf.init_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['test']
@pytest.mark.usefixture('load_source')
class TestSettingsFromEnv(object):
def test_from_env(self, environ):
def test_from_env(self, environ, settings):
environ.update({'THEFUCK_RULES': 'bash:lisp',
'THEFUCK_EXCLUDE_RULES': 'git:vim',
'THEFUCK_WAIT_COMMAND': '55',
'THEFUCK_REQUIRE_CONFIRMATION': 'true',
'THEFUCK_NO_COLORS': 'false',
'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'})
settings = conf.get_settings(Mock())
conf.init_settings(Mock())
assert settings.rules == ['bash', 'lisp']
assert settings.exclude_rules == ['git', 'vim']
assert settings.wait_command == 55
@ -76,9 +77,9 @@ class TestSettingsFromEnv(object):
assert settings.no_colors is False
assert settings.priority == {'bash': 10, 'vim': 15}
def test_from_env_with_DEFAULT(self, environ):
def test_from_env_with_DEFAULT(self, environ, settings):
environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'})
settings = conf.get_settings(Mock())
conf.init_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp']

View File

@ -16,7 +16,7 @@ def test_load_rule(mocker):
enabled_by_default=True,
priority=900,
requires_output=True))
assert corrector.load_rule(Path('/rules/bash.py'), settings=Mock(priority={})) \
assert corrector.load_rule(Path('/rules/bash.py')) \
== Rule('bash', match, get_new_command, priority=900)
load_source.assert_called_once_with('bash', '/rules/bash.py')
@ -25,7 +25,7 @@ class TestGetRules(object):
@pytest.fixture
def glob(self, mocker):
results = {}
mocker.patch('thefuck.corrector.Path.glob',
mocker.patch('pathlib.Path.glob',
new_callable=lambda: lambda *_: results.pop('value', []))
return lambda value: results.update({'value': value})
@ -48,54 +48,55 @@ class TestGetRules(object):
(['git.py', 'bash.py'], ['git'], [], ['git']),
(['git.py', 'bash.py'], conf.DEFAULT_RULES, ['git'], ['bash']),
(['git.py', 'bash.py'], ['git'], ['git'], [])])
def test_get_rules(self, glob, paths, conf_rules, exclude_rules, loaded_rules):
def test_get_rules(self, glob, settings, paths, conf_rules, exclude_rules,
loaded_rules):
glob([PosixPath(path) for path in paths])
settings = Mock(rules=self._prepare_rules(conf_rules),
settings.update(rules=self._prepare_rules(conf_rules),
priority={},
exclude_rules=self._prepare_rules(exclude_rules))
rules = corrector.get_rules(Path('~'), settings)
rules = corrector.get_rules()
self._compare_names(rules, loaded_rules)
class TestIsRuleMatch(object):
def test_no_match(self, settings):
def test_no_match(self):
assert not corrector.is_rule_match(
Command('ls'), Rule('', lambda *_: False), settings)
Command('ls'), Rule('', lambda _: False))
def test_match(self, settings):
rule = Rule('', lambda x, _: x.script == 'cd ..')
assert corrector.is_rule_match(Command('cd ..'), rule, settings)
def test_match(self):
rule = Rule('', lambda x: x.script == 'cd ..')
assert corrector.is_rule_match(Command('cd ..'), rule)
def test_when_rule_failed(self, capsys, settings):
@pytest.mark.usefixtures('no_colors')
def test_when_rule_failed(self, capsys):
rule = Rule('test', Mock(side_effect=OSError('Denied')),
requires_output=False)
assert not corrector.is_rule_match(
Command('ls'), rule, settings)
assert not corrector.is_rule_match(Command('ls'), rule)
assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:'
class TestMakeCorrectedCommands(object):
def test_with_rule_returns_list(self):
rule = Rule(get_new_command=lambda x, _: [x.script + '!', x.script + '@'],
rule = Rule(get_new_command=lambda x: [x.script + '!', x.script + '@'],
priority=100)
assert list(make_corrected_commands(Command(script='test'), rule, None)) \
assert list(make_corrected_commands(Command(script='test'), rule)) \
== [CorrectedCommand(script='test!', priority=100),
CorrectedCommand(script='test@', priority=200)]
def test_with_rule_returns_command(self):
rule = Rule(get_new_command=lambda x, _: x.script + '!',
rule = Rule(get_new_command=lambda x: x.script + '!',
priority=100)
assert list(make_corrected_commands(Command(script='test'), rule, None)) \
assert list(make_corrected_commands(Command(script='test'), rule)) \
== [CorrectedCommand(script='test!', priority=100)]
def test_get_corrected_commands(mocker):
command = Command('test', 'test', 'test')
rules = [Rule(match=lambda *_: False),
Rule(match=lambda *_: True,
get_new_command=lambda x, _: x.script + '!', priority=100),
Rule(match=lambda *_: True,
get_new_command=lambda x, _: [x.script + '@', x.script + ';'],
rules = [Rule(match=lambda _: False),
Rule(match=lambda _: True,
get_new_command=lambda x: x.script + '!', priority=100),
Rule(match=lambda _: True,
get_new_command=lambda x: [x.script + '@', x.script + ';'],
priority=60)]
mocker.patch('thefuck.corrector.get_rules', return_value=rules)
assert [cmd.script for cmd in get_corrected_commands(command, None, Mock(debug=False))] \
assert [cmd.script for cmd in get_corrected_commands(command)] \
== ['test!', 'test@', 'test;']

View File

@ -1,14 +1,20 @@
import pytest
from mock import Mock
from thefuck import logs
def test_color():
assert logs.color('red', Mock(no_colors=False)) == 'red'
assert logs.color('red', Mock(no_colors=True)) == ''
def test_color(settings):
settings.no_colors = False
assert logs.color('red') == 'red'
settings.no_colors = True
assert logs.color('red') == ''
def test_debug(capsys):
logs.debug('test', Mock(no_colors=True, debug=True))
assert capsys.readouterr() == ('', 'DEBUG: test\n')
logs.debug('test', Mock(no_colors=True, debug=False))
assert capsys.readouterr() == ('', '')
@pytest.mark.usefixtures('no_colors')
@pytest.mark.parametrize('debug, stderr', [
(True, 'DEBUG: test\n'),
(False, '')])
def test_debug(capsys, settings, debug, stderr):
settings.debug = debug
logs.debug('test')
assert capsys.readouterr() == ('', stderr)

View File

@ -24,9 +24,9 @@ class TestGetCommand(object):
monkeypatch.setattr('thefuck.shells.from_shell', lambda x: x)
monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x)
def test_get_command_calls(self, Popen):
assert main.get_command(Mock(env={}),
['thefuck', 'apt-get', 'search', 'vim']) \
def test_get_command_calls(self, Popen, settings):
settings.env = {}
assert main.get_command(['thefuck', 'apt-get', 'search', 'vim']) \
== Command('apt-get search vim', 'stdout', 'stderr')
Popen.assert_called_once_with('apt-get search vim',
shell=True,
@ -41,6 +41,6 @@ class TestGetCommand(object):
(['thefuck', 'ls'], 'ls')])
def test_get_command_script(self, args, result):
if result:
assert main.get_command(Mock(env={}), args).script == result
assert main.get_command(args).script == result
else:
assert main.get_command(Mock(env={}), args) is None
assert main.get_command(args) is None

View File

@ -10,14 +10,6 @@ def test_rules_names_list():
assert Rule('bash') not in RulesNamesList(['lisp'])
def test_update_settings():
settings = Settings({'key': 'val'})
new_settings = settings.update(key='new-val', unset='unset-value')
assert new_settings.key == 'val'
assert new_settings.unset == 'unset-value'
assert settings.key == 'val'
class TestSortedCorrectedCommandsSequence(object):
def test_realises_generator_only_on_demand(self, settings):
should_realise = False
@ -28,24 +20,23 @@ class TestSortedCorrectedCommandsSequence(object):
assert should_realise
yield CorrectedCommand('git checkout', priority=100)
commands = SortedCorrectedCommandsSequence(gen(), settings)
commands = SortedCorrectedCommandsSequence(gen())
assert commands[0] == CorrectedCommand('git commit')
should_realise = True
assert commands[1] == CorrectedCommand('git checkout', priority=100)
assert commands[2] == CorrectedCommand('git branch', priority=200)
def test_remove_duplicates(self, settings):
def test_remove_duplicates(self):
side_effect = lambda *_: None
seq = SortedCorrectedCommandsSequence(
iter([CorrectedCommand('ls', priority=100),
CorrectedCommand('ls', priority=200),
CorrectedCommand('ls', side_effect, 300)]),
settings)
CorrectedCommand('ls', side_effect, 300)]))
assert set(seq) == {CorrectedCommand('ls', priority=100),
CorrectedCommand('ls', side_effect, 300)}
def test_with_blank(self, settings):
seq = SortedCorrectedCommandsSequence(iter([]), settings)
def test_with_blank(self):
seq = SortedCorrectedCommandsSequence(iter([]))
assert list(seq) == []

View File

@ -56,66 +56,55 @@ def test_command_selector():
assert changes == [1, 2, 3, 1, 3]
@pytest.mark.usefixtures('no_colors')
class TestSelectCommand(object):
@pytest.fixture
def commands_with_side_effect(self, settings):
def commands_with_side_effect(self):
return SortedCorrectedCommandsSequence(
iter([CorrectedCommand('ls', lambda *_: None, 100),
CorrectedCommand('cd', lambda *_: None, 100)]),
settings)
CorrectedCommand('cd', lambda *_: None, 100)]))
@pytest.fixture
def commands(self, settings):
def commands(self):
return SortedCorrectedCommandsSequence(
iter([CorrectedCommand('ls', None, 100),
CorrectedCommand('cd', None, 100)]),
settings)
CorrectedCommand('cd', None, 100)]))
def test_without_commands(self, capsys):
assert ui.select_command([], Mock(debug=False, no_color=True)) is None
assert ui.select_command([]) is None
assert capsys.readouterr() == ('', 'No fucks given\n')
def test_without_confirmation(self, capsys, commands):
assert ui.select_command(commands,
Mock(debug=False, no_color=True,
require_confirmation=False)) == commands[0]
def test_without_confirmation(self, capsys, commands, settings):
settings.require_confirmation = False
assert ui.select_command(commands) == commands[0]
assert capsys.readouterr() == ('', 'ls\n')
def test_without_confirmation_with_side_effects(self, capsys,
commands_with_side_effect):
assert ui.select_command(commands_with_side_effect,
Mock(debug=False, no_color=True,
require_confirmation=False)) \
def test_without_confirmation_with_side_effects(
self, capsys, commands_with_side_effect, settings):
settings.require_confirmation = False
assert ui.select_command(commands_with_side_effect) \
== commands_with_side_effect[0]
assert capsys.readouterr() == ('', 'ls (+side effect)\n')
def test_with_confirmation(self, capsys, patch_getch, commands):
patch_getch(['\n'])
assert ui.select_command(commands,
Mock(debug=False, no_color=True,
require_confirmation=True)) == commands[0]
assert ui.select_command(commands) == commands[0]
assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\n')
def test_with_confirmation_abort(self, capsys, patch_getch, commands):
patch_getch([KeyboardInterrupt])
assert ui.select_command(commands,
Mock(debug=False, no_color=True,
require_confirmation=True)) is None
assert ui.select_command(commands) is None
assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\nAborted\n')
def test_with_confirmation_with_side_effct(self, capsys, patch_getch,
commands_with_side_effect):
patch_getch(['\n'])
assert ui.select_command(commands_with_side_effect,
Mock(debug=False, no_color=True,
require_confirmation=True))\
assert ui.select_command(commands_with_side_effect)\
== commands_with_side_effect[0]
assert capsys.readouterr() == ('', u'\x1b[1K\rls (+side effect) [enter/↑/↓/ctrl+c]\n')
def test_with_confirmation_select_second(self, capsys, patch_getch, commands):
patch_getch(['\x1b', '[', 'B', '\n'])
assert ui.select_command(commands,
Mock(debug=False, no_color=True,
require_confirmation=True)) == commands[1]
assert ui.select_command(commands) == commands[1]
assert capsys.readouterr() == (
'', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\x1b[1K\rcd [enter/↑/↓/ctrl+c]\n')

View File

@ -1,10 +1,9 @@
import pytest
from mock import Mock
import six
from thefuck.utils import wrap_settings, \
from thefuck.utils import default_settings, \
memoize, get_closest, get_all_executables, replace_argument, \
get_all_matched_commands, is_app, for_app, cache
from thefuck.types import Settings
get_all_matched_commands, is_app, for_app, cache, compatibility_call
from tests.utils import Command
@ -12,9 +11,12 @@ from tests.utils import Command
({'key': 'val'}, {}, {'key': 'val'}),
({'key': 'new-val'}, {'key': 'val'}, {'key': 'val'}),
({'key': 'new-val', 'unset': 'unset'}, {'key': 'val'}, {'key': 'val', 'unset': 'unset'})])
def test_wrap_settings(override, old, new):
fn = lambda _, settings: settings
assert wrap_settings(override)(fn)(None, Settings(old)) == new
def test_default_settings(settings, override, old, new):
settings.clear()
settings.update(old)
fn = lambda _: _
default_settings(override)(fn)(None)
assert settings == new
def test_memoize():
@ -112,10 +114,10 @@ def test_is_app(script, names, result):
('hg diff', ['git', 'hub'], False)])
def test_for_app(script, names, result):
@for_app(*names)
def match(command, settings):
def match(command):
return True
assert match(Command(script), None) == result
assert match(Command(script)) == result
class TestCache(object):
@ -180,3 +182,50 @@ class TestCache(object):
shelve.update({key: {'etag': '-1', 'value': 'old-value'}})
assert fn() == 'test'
assert shelve == {key: {'etag': '0', 'value': 'test'}}
class TestCompatibilityCall(object):
def test_match(self):
def match(command):
assert command == Command()
return True
assert compatibility_call(match, Command())
def test_old_match(self, settings):
def match(command, _settings):
assert command == Command()
assert settings == _settings
return True
assert compatibility_call(match, Command())
def test_get_new_command(self):
def get_new_command(command):
assert command == Command()
return True
assert compatibility_call(get_new_command, Command())
def test_old_get_new_command(self, settings):
def get_new_command(command, _settings):
assert command == Command()
assert settings == _settings
return True
assert compatibility_call(get_new_command, Command())
def test_side_effect(self):
def side_effect(command, new_command):
assert command == Command() == new_command
return True
assert compatibility_call(side_effect, Command(), Command())
def test_old_side_effect(self, settings):
def side_effect(command, new_command, _settings):
assert command == Command() == new_command
assert settings == _settings
return True
assert compatibility_call(side_effect, Command(), Command())

View File

@ -1,12 +1,11 @@
from copy import copy
from imp import load_source
import os
import sys
from six import text_type
from . import logs, types
from .types import RulesNamesList, Settings
class _DefaultRulesNames(types.RulesNamesList):
class _DefaultRulesNames(RulesNamesList):
def __add__(self, items):
return _DefaultRulesNames(list(self) + items)
@ -24,7 +23,6 @@ class _DefaultRulesNames(types.RulesNamesList):
DEFAULT_RULES = _DefaultRulesNames([])
DEFAULT_PRIORITY = 1000
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'exclude_rules': [],
'wait_command': 3,
@ -42,7 +40,6 @@ ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
'THEFUCK_PRIORITY': 'priority',
'THEFUCK_DEBUG': 'debug'}
SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file
#
# The rules are defined as in the example bellow:
@ -105,30 +102,30 @@ def _settings_from_env():
if env in os.environ}
def get_settings(user_dir):
"""Returns settings filled with values from `settings.py` and env."""
conf = copy(DEFAULT_SETTINGS)
try:
conf.update(_settings_from_file(user_dir))
except Exception:
logs.exception("Can't load settings from file",
sys.exc_info(),
types.Settings(conf))
settings = Settings(DEFAULT_SETTINGS)
def init_settings(user_dir):
"""Fills `settings` with values from `settings.py` and env."""
from .logs import exception
settings.user_dir = user_dir
try:
conf.update(_settings_from_env())
settings.update(_settings_from_file(user_dir))
except Exception:
logs.exception("Can't load settings from env",
sys.exc_info(),
types.Settings(conf))
exception("Can't load settings from file", sys.exc_info())
if not isinstance(conf['rules'], types.RulesNamesList):
conf['rules'] = types.RulesNamesList(conf['rules'])
try:
settings.update(_settings_from_env())
except Exception:
exception("Can't load settings from env", sys.exc_info())
if not isinstance(conf['exclude_rules'], types.RulesNamesList):
conf['exclude_rules'] = types.RulesNamesList(conf['exclude_rules'])
if not isinstance(settings['rules'], RulesNamesList):
settings.rules = RulesNamesList(settings['rules'])
return types.Settings(conf)
if not isinstance(settings.exclude_rules, RulesNamesList):
settings.exclude_rules = RulesNamesList(settings.exclude_rules)
def initialize_settings_file(user_dir):

View File

@ -1,44 +1,47 @@
import sys
from imp import load_source
from pathlib import Path
from . import conf, types, logs
from .conf import settings, DEFAULT_PRIORITY
from .types import Rule, CorrectedCommand, SortedCorrectedCommandsSequence
from .utils import compatibility_call
from . import logs
def load_rule(rule, settings):
def load_rule(rule):
"""Imports rule module and returns it."""
name = rule.name[:-3]
with logs.debug_time(u'Importing rule: {};'.format(name), settings):
with logs.debug_time(u'Importing rule: {};'.format(name)):
rule_module = load_source(name, str(rule))
priority = getattr(rule_module, 'priority', conf.DEFAULT_PRIORITY)
return types.Rule(name, rule_module.match,
rule_module.get_new_command,
getattr(rule_module, 'enabled_by_default', True),
getattr(rule_module, 'side_effect', None),
settings.priority.get(name, priority),
getattr(rule_module, 'requires_output', True))
priority = getattr(rule_module, 'priority', DEFAULT_PRIORITY)
return Rule(name, rule_module.match,
rule_module.get_new_command,
getattr(rule_module, 'enabled_by_default', True),
getattr(rule_module, 'side_effect', None),
settings.priority.get(name, priority),
getattr(rule_module, 'requires_output', True))
def get_loaded_rules(rules, settings):
def get_loaded_rules(rules):
"""Yields all available rules."""
for rule in rules:
if rule.name != '__init__.py':
loaded_rule = load_rule(rule, settings)
loaded_rule = load_rule(rule)
if loaded_rule in settings.rules and \
loaded_rule not in settings.exclude_rules:
loaded_rule not in settings.exclude_rules:
yield loaded_rule
def get_rules(user_dir, settings):
def get_rules():
"""Returns all enabled rules."""
bundled = Path(__file__).parent \
.joinpath('rules') \
.glob('*.py')
user = user_dir.joinpath('rules').glob('*.py')
return sorted(get_loaded_rules(sorted(bundled) + sorted(user), settings),
user = settings.user_dir.joinpath('rules').glob('*.py')
return sorted(get_loaded_rules(sorted(bundled) + sorted(user)),
key=lambda rule: rule.priority)
def is_rule_match(command, rule, settings):
def is_rule_match(command, rule):
"""Returns first matched rule for command."""
script_only = command.stdout is None and command.stderr is None
@ -46,27 +49,26 @@ def is_rule_match(command, rule, settings):
return False
try:
with logs.debug_time(u'Trying rule: {};'.format(rule.name),
settings):
if rule.match(command, settings):
with logs.debug_time(u'Trying rule: {};'.format(rule.name)):
if compatibility_call(rule.match, command):
return True
except Exception:
logs.rule_failed(rule, sys.exc_info(), settings)
logs.rule_failed(rule, sys.exc_info())
def make_corrected_commands(command, rule, settings):
new_commands = rule.get_new_command(command, settings)
def make_corrected_commands(command, rule):
new_commands = compatibility_call(rule.get_new_command, command)
if not isinstance(new_commands, list):
new_commands = (new_commands,)
for n, new_command in enumerate(new_commands):
yield types.CorrectedCommand(script=new_command,
side_effect=rule.side_effect,
priority=(n + 1) * rule.priority)
yield CorrectedCommand(script=new_command,
side_effect=rule.side_effect,
priority=(n + 1) * rule.priority)
def get_corrected_commands(command, user_dir, settings):
def get_corrected_commands(command):
corrected_commands = (
corrected for rule in get_rules(user_dir, settings)
if is_rule_match(command, rule, settings)
for corrected in make_corrected_commands(command, rule, settings))
return types.SortedCorrectedCommandsSequence(corrected_commands, settings)
corrected for rule in get_rules()
if is_rule_match(command, rule)
for corrected in make_corrected_commands(command, rule))
return SortedCorrectedCommandsSequence(corrected_commands)

View File

@ -5,9 +5,10 @@ from datetime import datetime
import sys
from traceback import format_exception
import colorama
from .conf import settings
def color(color_, settings):
def color(color_):
"""Utility for ability to disabling colored output."""
if settings.no_colors:
return ''
@ -15,37 +16,37 @@ def color(color_, settings):
return color_
def exception(title, exc_info, settings):
def exception(title, exc_info):
sys.stderr.write(
u'{warn}[WARN] {title}:{reset}\n{trace}'
u'{warn}----------------------------{reset}\n\n'.format(
warn=color(colorama.Back.RED + colorama.Fore.WHITE
+ colorama.Style.BRIGHT, settings),
reset=color(colorama.Style.RESET_ALL, settings),
+ colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL),
title=title,
trace=''.join(format_exception(*exc_info))))
def rule_failed(rule, exc_info, settings):
exception('Rule {}'.format(rule.name), exc_info, settings)
def rule_failed(rule, exc_info):
exception('Rule {}'.format(rule.name), exc_info)
def failed(msg, settings):
def failed(msg):
sys.stderr.write('{red}{msg}{reset}\n'.format(
msg=msg,
red=color(colorama.Fore.RED, settings),
reset=color(colorama.Style.RESET_ALL, settings)))
red=color(colorama.Fore.RED),
reset=color(colorama.Style.RESET_ALL)))
def show_corrected_command(corrected_command, settings):
def show_corrected_command(corrected_command):
sys.stderr.write('{bold}{script}{reset}{side_effect}\n'.format(
script=corrected_command.script,
side_effect=' (+side effect)' if corrected_command.side_effect else '',
bold=color(colorama.Style.BRIGHT, settings),
reset=color(colorama.Style.RESET_ALL, settings)))
bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL)))
def confirm_text(corrected_command, settings):
def confirm_text(corrected_command):
sys.stderr.write(
('{clear}{bold}{script}{reset}{side_effect} '
'[{green}enter{reset}/{blue}{reset}/{blue}{reset}'
@ -53,42 +54,42 @@ def confirm_text(corrected_command, settings):
script=corrected_command.script,
side_effect=' (+side effect)' if corrected_command.side_effect else '',
clear='\033[1K\r',
bold=color(colorama.Style.BRIGHT, settings),
green=color(colorama.Fore.GREEN, settings),
red=color(colorama.Fore.RED, settings),
reset=color(colorama.Style.RESET_ALL, settings),
blue=color(colorama.Fore.BLUE, settings)))
bold=color(colorama.Style.BRIGHT),
green=color(colorama.Fore.GREEN),
red=color(colorama.Fore.RED),
reset=color(colorama.Style.RESET_ALL),
blue=color(colorama.Fore.BLUE)))
def debug(msg, settings):
def debug(msg):
if settings.debug:
sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format(
msg=msg,
reset=color(colorama.Style.RESET_ALL, settings),
blue=color(colorama.Fore.BLUE, settings),
bold=color(colorama.Style.BRIGHT, settings)))
reset=color(colorama.Style.RESET_ALL),
blue=color(colorama.Fore.BLUE),
bold=color(colorama.Style.BRIGHT)))
@contextmanager
def debug_time(msg, settings):
def debug_time(msg):
started = datetime.now()
try:
yield
finally:
debug(u'{} took: {}'.format(msg, datetime.now() - started), settings)
debug(u'{} took: {}'.format(msg, datetime.now() - started))
def how_to_configure_alias(configuration_details, settings):
def how_to_configure_alias(configuration_details):
print("Seems like {bold}fuck{reset} alias isn't configured!".format(
bold=color(colorama.Style.BRIGHT, settings),
reset=color(colorama.Style.RESET_ALL, settings)))
bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL)))
if configuration_details:
content, path = configuration_details
print(
"Please put {bold}{content}{reset} in your "
"{bold}{path}{reset}.".format(
bold=color(colorama.Style.BRIGHT, settings),
reset=color(colorama.Style.RESET_ALL, settings),
bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL),
path=path,
content=content))
print('More details - https://github.com/nvbn/thefuck#manual-installation')

View File

@ -10,8 +10,10 @@ import sys
from psutil import Process, TimeoutExpired
import colorama
import six
from . import logs, conf, types, shells
from . import logs, types, shells
from .conf import initialize_settings_file, init_settings, settings
from .corrector import get_corrected_commands
from .utils import compatibility_call
from .ui import select_command
@ -21,11 +23,11 @@ def setup_user_dir():
rules_dir = user_dir.joinpath('rules')
if not rules_dir.is_dir():
rules_dir.mkdir(parents=True)
conf.initialize_settings_file(user_dir)
initialize_settings_file(user_dir)
return user_dir
def wait_output(settings, popen):
def wait_output(popen):
"""Returns `True` if we can get output of the command in the
`settings.wait_command` time.
@ -43,7 +45,7 @@ def wait_output(settings, popen):
return False
def get_command(settings, args):
def get_command(args):
"""Creates command from `args` and executes it."""
if six.PY2:
script = ' '.join(arg.decode('utf-8') for arg in args[1:])
@ -58,26 +60,25 @@ def get_command(settings, args):
env = dict(os.environ)
env.update(settings.env)
with logs.debug_time(u'Call: {}; with env: {};'.format(script, env),
settings):
with logs.debug_time(u'Call: {}; with env: {};'.format(script, env)):
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env)
if wait_output(settings, result):
if wait_output(result):
stdout = result.stdout.read().decode('utf-8')
stderr = result.stderr.read().decode('utf-8')
logs.debug(u'Received stdout: {}'.format(stdout), settings)
logs.debug(u'Received stderr: {}'.format(stderr), settings)
logs.debug(u'Received stdout: {}'.format(stdout))
logs.debug(u'Received stderr: {}'.format(stderr))
return types.Command(script, stdout, stderr)
else:
logs.debug(u'Execution timed out!', settings)
logs.debug(u'Execution timed out!')
return types.Command(script, None, None)
def run_command(old_cmd, command, settings):
def run_command(old_cmd, command):
"""Runs command from rule for passed command."""
if command.side_effect:
command.side_effect(old_cmd, command.script, settings)
compatibility_call(command.side_effect, old_cmd, command.script)
shells.put_to_history(command.script)
print(command.script)
@ -87,20 +88,20 @@ def run_command(old_cmd, command, settings):
def fix_command():
colorama.init()
user_dir = setup_user_dir()
settings = conf.get_settings(user_dir)
with logs.debug_time('Total', settings):
logs.debug(u'Run with settings: {}'.format(pformat(settings)), settings)
init_settings(user_dir)
with logs.debug_time('Total'):
logs.debug(u'Run with settings: {}'.format(pformat(settings)))
command = get_command(settings, sys.argv)
command = get_command(sys.argv)
if not command:
logs.debug('Empty command, nothing to do', settings)
logs.debug('Empty command, nothing to do')
return
corrected_commands = get_corrected_commands(command, user_dir, settings)
selected_command = select_command(corrected_commands, settings)
corrected_commands = get_corrected_commands(command)
selected_command = select_command(corrected_commands)
if selected_command:
run_command(command, selected_command, settings)
run_command(command, selected_command)
def _get_current_version():
@ -128,8 +129,8 @@ def how_to_configure_alias():
"""
colorama.init()
user_dir = setup_user_dir()
settings = conf.get_settings(user_dir)
logs.how_to_configure_alias(shells.how_to_configure(), settings)
init_settings(user_dir)
logs.how_to_configure_alias(shells.how_to_configure())
def main():

View File

@ -20,11 +20,11 @@ def get_package(command):
return None
def match(command, settings):
def match(command):
return 'not found' in command.stderr and get_package(command.script)
def get_new_command(command, settings):
def get_new_command(command):
name = get_package(command.script)
formatme = shells.and_('sudo apt-get install {}', '{}')
return formatme.format(name, command.script)

View File

@ -3,9 +3,9 @@ from thefuck.utils import for_app
@for_app('apt-get')
def match(command, settings):
def match(command):
return command.script.startswith('apt-get search')
def get_new_command(command, settings):
def get_new_command(command):
return re.sub(r'^apt-get', 'apt-cache', command.script)

View File

@ -24,7 +24,7 @@ def _get_similar_formula(formula_name):
return get_closest(formula_name, _get_formulas(), 1, 0.85)
def match(command, settings):
def match(command):
is_proper_command = ('brew install' in command.script and
'No available formula' in command.stderr)
@ -35,7 +35,7 @@ def match(command, settings):
return False
def get_new_command(command, settings):
def get_new_command(command):
not_exist_formula = re.findall(r'Error: No available formula for ([a-z]+)',
command.stderr)[0]
exist_formula = _get_similar_formula(not_exist_formula)

View File

@ -63,7 +63,7 @@ def _brew_commands():
'doctor', 'create', 'edit']
def match(command, settings):
def match(command):
is_proper_command = ('brew' in command.script and
'Unknown command' in command.stderr)
@ -74,7 +74,7 @@ def match(command, settings):
return False
def get_new_command(command, settings):
def get_new_command(command):
broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)',
command.stderr)[0]
return replace_command(command, broken_cmd, _brew_commands())

View File

@ -6,9 +6,9 @@
# It currently upgrades all formula but this will soon change to require '--all'.
def match(command, settings):
def match(command):
return command.script == 'brew upgrade'
def get_new_command(command, settings):
def get_new_command(command):
return command.script + ' --all'

View File

@ -1,6 +1,6 @@
def match(command, settings):
def match(command):
return command.script == 'cargo'
def get_new_command(command, settings):
def get_new_command(command):
return 'cargo build'

View File

@ -3,12 +3,12 @@ from thefuck.utils import replace_argument, for_app
@for_app('cargo')
def match(command, settings):
def match(command):
return ('No such subcommand' in command.stderr
and 'Did you mean' in command.stderr)
def get_new_command(command, settings):
def get_new_command(command):
broken = command.script.split()[1]
fix = re.findall(r'Did you mean `([^`]*)`', command.stderr)[0]

View File

@ -18,7 +18,7 @@ def _get_sub_dirs(parent):
@sudo_support
@for_app('cd')
def match(command, settings):
def match(command):
"""Match function copied from cd_mkdir.py"""
return (command.script.startswith('cd ')
and ('no such file or directory' in command.stderr.lower()
@ -26,7 +26,7 @@ def match(command, settings):
@sudo_support
def get_new_command(command, settings):
def get_new_command(command):
"""
Attempt to rebuild the path string by spellchecking the directories.
If it fails (i.e. no directories are a close enough match), then it
@ -47,7 +47,7 @@ def get_new_command(command, settings):
if best_matches:
cwd = os.path.join(cwd, best_matches[0])
else:
return cd_mkdir.get_new_command(command, settings)
return cd_mkdir.get_new_command(command)
return 'cd "{0}"'.format(cwd)

View File

@ -6,12 +6,12 @@ from thefuck.specific.sudo import sudo_support
@sudo_support
@for_app('cd')
def match(command, settings):
def match(command):
return (('no such file or directory' in command.stderr.lower()
or 'cd: can\'t cd to' in command.stderr.lower()))
@sudo_support
def get_new_command(command, settings):
def get_new_command(command):
repl = shells.and_('mkdir -p \\1', 'cd \\1')
return re.sub(r'^cd (.*)', repl, command.script)

View File

@ -8,9 +8,9 @@
# cd..: command not found
def match(command, settings):
def match(command):
return command.script == 'cd..'
def get_new_command(command, settings):
def get_new_command(command):
return 'cd ..'

View File

@ -3,12 +3,12 @@ from thefuck.utils import replace_argument, for_app
@for_app('composer')
def match(command, settings):
def match(command):
return (('did you mean this?' in command.stderr.lower()
or 'did you mean one of these?' in command.stderr.lower()))
def get_new_command(command, settings):
def get_new_command(command):
broken_cmd = re.findall(r"Command \"([^']*)\" is not defined", command.stderr)[0]
new_cmd = re.findall(r'Did you mean this\?[^\n]*\n\s*([^\n]*)', command.stderr)
if not new_cmd:

View File

@ -5,11 +5,11 @@ from thefuck.utils import for_app
@sudo_support
@for_app('cp')
def match(command, settings):
def match(command):
stderr = command.stderr.lower()
return 'omitting directory' in stderr or 'is a directory' in stderr
@sudo_support
def get_new_command(command, settings):
def get_new_command(command):
return re.sub(r'^cp', 'cp -a', command.script)

View File

@ -2,11 +2,11 @@ from thefuck.utils import for_app
@for_app(['g++', 'clang++'])
def match(command, settings):
def match(command):
return ('This file requires compiler and library support for the '
'ISO C++ 2011 standard.' in command.stderr or
'-Wc++11-extensions' in command.stderr)
def get_new_command(command, settings):
def get_new_command(command):
return command.script + ' -std=c++11'

View File

@ -25,18 +25,18 @@ def _tar_file(cmd):
@for_app('tar')
def match(command, settings):
def match(command):
return ('-C' not in command.script
and _is_tar_extract(command.script)
and _tar_file(command.script) is not None)
def get_new_command(command, settings):
def get_new_command(command):
return shells.and_('mkdir -p {dir}', '{cmd} -C {dir}') \
.format(dir=_tar_file(command.script)[1], cmd=command.script)
def side_effect(old_cmd, command, settings):
def side_effect(old_cmd, command):
with tarfile.TarFile(_tar_file(old_cmd.script)[0]) as archive:
for file in archive.getnames():
os.remove(file)

View File

@ -22,16 +22,16 @@ def _zip_file(command):
@for_app('unzip')
def match(command, settings):
def match(command):
return ('-d' not in command.script
and _is_bad_zip(_zip_file(command)))
def get_new_command(command, settings):
def get_new_command(command):
return '{} -d {}'.format(command.script, _zip_file(command)[:-4])
def side_effect(old_cmd, command, settings):
def side_effect(old_cmd, command):
with zipfile.ZipFile(_zip_file(old_cmd), 'r') as archive:
for file in archive.namelist():
os.remove(file)

Some files were not shown because too many files have changed in this diff Show More