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

#334 Speed-up rules with caching for_app decorator

This commit is contained in:
nvbn 2015-08-27 16:42:09 +03:00
parent bc78f1bbee
commit 0c283ff2b8
33 changed files with 142 additions and 113 deletions

View File

@ -1,6 +1,6 @@
import pytest
from mock import Mock
from thefuck.rules.lein_not_task import match, get_new_command
from tests.utils import Command
@pytest.fixture
@ -14,10 +14,10 @@ Did you mean this?
def test_match(is_not_task):
assert match(Mock(script='lein rpl', stderr=is_not_task), None)
assert not match(Mock(script='ls', stderr=is_not_task), None)
assert match(Command(script='lein rpl', stderr=is_not_task), None)
assert not match(Command(script='ls', stderr=is_not_task), None)
def test_get_new_command(is_not_task):
assert get_new_command(Mock(script='lein rpl --help', stderr=is_not_task),
assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task),
None) == ['lein repl --help', 'lein jar --help']

View File

@ -1,16 +1,16 @@
from mock import patch, Mock
from thefuck.rules.ls_lah import match, get_new_command
from tests.utils import Command
def test_match():
assert match(Mock(script='ls'), None)
assert match(Mock(script='ls file.py'), None)
assert match(Mock(script='ls /opt'), None)
assert not match(Mock(script='ls -lah /opt'), None)
assert not match(Mock(script='pacman -S binutils'), None)
assert not match(Mock(script='lsof'), None)
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)
def test_get_new_command():
assert get_new_command(Mock(script='ls file.py'), None) == 'ls -lah file.py'
assert get_new_command(Mock(script='ls'), None) == 'ls -lah'
assert get_new_command(Command(script='ls file.py'), None) == 'ls -lah file.py'
assert get_new_command(Command(script='ls'), None) == 'ls -lah'

View File

@ -1,6 +1,8 @@
import re
from thefuck.utils import for_app
@for_app('apt-get')
def match(command, settings):
return command.script.startswith('apt-get search')

View File

@ -1,10 +1,10 @@
import re
from thefuck.utils import replace_argument
from thefuck.utils import replace_argument, for_app
@for_app('cargo')
def match(command, settings):
return ('cargo' in command.script
and 'No such subcommand' in command.stderr
return ('No such subcommand' in command.stderr
and 'Did you mean' in command.stderr)

View File

@ -4,6 +4,7 @@ import os
from difflib import get_close_matches
from thefuck.specific.sudo import sudo_support
from thefuck.rules import cd_mkdir
from thefuck.utils import for_app
__author__ = "mmussomele"
@ -16,6 +17,7 @@ def _get_sub_dirs(parent):
@sudo_support
@for_app('cd')
def match(command, settings):
"""Match function copied from cd_mkdir.py"""
return (command.script.startswith('cd ')

View File

@ -1,13 +1,14 @@
import re
from thefuck import shells
from thefuck.utils import for_app
from thefuck.specific.sudo import sudo_support
@sudo_support
@for_app('cd')
def match(command, settings):
return (command.script.startswith('cd ')
and ('no such file or directory' in command.stderr.lower()
or 'cd: can\'t cd to' in command.stderr.lower()))
return (('no such file or directory' in command.stderr.lower()
or 'cd: can\'t cd to' in command.stderr.lower()))
@sudo_support

View File

@ -1,11 +1,11 @@
import re
from thefuck.utils import replace_argument
from thefuck.utils import replace_argument, for_app
@for_app('composer')
def match(command, settings):
return ('composer' in command.script
and ('did you mean this?' in command.stderr.lower()
or 'did you mean one of these?' in command.stderr.lower()))
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):

View File

@ -1,12 +1,13 @@
import re
from thefuck.specific.sudo import sudo_support
from thefuck.utils import for_app
@sudo_support
@for_app('cp')
def match(command, settings):
stderr = command.stderr.lower()
return command.script.startswith('cp ') \
and ('omitting directory' in stderr or 'is a directory' in stderr)
return 'omitting directory' in stderr or 'is a directory' in stderr
@sudo_support

View File

@ -1,8 +1,11 @@
from thefuck.utils import for_app
@for_app(['g++', 'clang++'])
def match(command, settings):
return (('g++' in command.script or 'clang++' in command.script) and
('This file requires compiler and library support for the '
'ISO C++ 2011 standard.' in command.stderr or
'-Wc++11-extensions' in command.stderr))
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):

View File

@ -1,6 +1,7 @@
from thefuck import shells
import os
import tarfile
from thefuck import shells
from thefuck.utils import for_app
def _is_tar_extract(cmd):
@ -20,19 +21,19 @@ def _tar_file(cmd):
for c in cmd.split():
for ext in tar_extensions:
if c.endswith(ext):
return (c, c[0:len(c)-len(ext)])
return (c, c[0:len(c) - len(ext)])
@for_app('tar')
def match(command, settings):
return (command.script.startswith('tar')
and '-C' not in command.script
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):
return shells.and_('mkdir -p {dir}', '{cmd} -C {dir}') \
.format(dir=_tar_file(command.script)[1], cmd=command.script)
.format(dir=_tar_file(command.script)[1], cmd=command.script)
def side_effect(old_cmd, command, settings):

View File

@ -1,5 +1,6 @@
import os
import zipfile
from thefuck.utils import for_app
def _is_bad_zip(file):
@ -20,9 +21,9 @@ def _zip_file(command):
return '{}.zip'.format(c)
@for_app('unzip')
def match(command, settings):
return (command.script.startswith('unzip')
and '-d' not in command.script
return ('-d' not in command.script
and _is_bad_zip(_zip_file(command)))

View File

@ -1,14 +1,14 @@
from itertools import dropwhile, takewhile, islice
import re
import subprocess
from thefuck.utils import replace_command
from thefuck.utils import replace_command, for_app
from thefuck.specific.sudo import sudo_support
@sudo_support
@for_app('docker')
def match(command, settings):
return command.script.startswith('docker') \
and 'is not a docker command' in command.stderr
return 'is not a docker command' in command.stderr
def get_docker_commands():

View File

@ -1,4 +1,3 @@
from thefuck import utils
from thefuck.utils import replace_argument
from thefuck.specific.git import git_support

View File

@ -1,3 +1,4 @@
from thefuck.utils import for_app
# Appends .go when compiling go files
#
# Example:
@ -5,6 +6,7 @@
# error: go run: no go files listed
@for_app('go')
def match(command, settings):
return (command.script.startswith('go run ')
and not command.script.endswith('.go'))

View File

@ -1,6 +1,9 @@
from thefuck.utils import for_app
@for_app('grep')
def match(command, settings):
return (command.script.startswith('grep')
and 'is a directory' in command.stderr.lower())
return 'is a directory' in command.stderr.lower()
def get_new_command(command, settings):

View File

@ -1,11 +1,11 @@
import re
import subprocess
from thefuck.utils import replace_command
from thefuck.utils import replace_command, for_app
@for_app('gulp')
def match(command, script):
return command.script.startswith('gulp')\
and 'is not in your gulpfile' in command.stdout
return 'is not in your gulpfile' in command.stdout
def get_gulp_tasks():

View File

@ -1,10 +1,10 @@
import re
from thefuck.utils import replace_command
from thefuck.utils import replace_command, for_app
@for_app('heroku')
def match(command, settings):
return command.script.startswith('heroku') and \
'is not a heroku command' in command.stderr and \
return 'is not a heroku command' in command.stderr and \
'Perhaps you meant' in command.stderr

View File

@ -1,13 +1,16 @@
# Fixes common java command mistake
#
# Example:
# > java foo.java
# Error: Could not find or load main class foo.java
"""Fixes common java command mistake
Example:
> java foo.java
Error: Could not find or load main class foo.java
"""
from thefuck.utils import for_app
@for_app('java')
def match(command, settings):
return (command.script.startswith('java ')
and command.script.endswith('.java'))
return command.script.endswith('.java')
def get_new_command(command, settings):

View File

@ -1,14 +1,17 @@
# Appends .java when compiling java files
#
# Example:
# > javac foo
# error: Class names, 'foo', are only accepted if annotation
# processing is explicitly requested
"""Appends .java when compiling java files
Example:
> javac foo
error: Class names, 'foo', are only accepted if annotation
processing is explicitly requested
"""
from thefuck.utils import for_app
@for_app('javac')
def match(command, settings):
return (command.script.startswith('javac ')
and not command.script.endswith('.java'))
return not command.script.endswith('.java')
def get_new_command(command, settings):

View File

@ -1,9 +1,10 @@
import re
from thefuck.utils import replace_command, get_all_matched_commands
from thefuck.utils import replace_command, get_all_matched_commands, for_app
from thefuck.specific.sudo import sudo_support
@sudo_support
@for_app('lein')
def match(command, settings):
return (command.script.startswith('lein')
and "is not a task. See 'lein help'" in command.stderr

View File

@ -1,7 +1,9 @@
from thefuck.utils import for_app
@for_app('ls')
def match(command, settings):
return (command.script == 'ls'
or command.script.startswith('ls ')
and 'ls -' not in command.script)
return 'ls -' not in command.script
def get_new_command(command, settings):

View File

@ -1,5 +1,5 @@
import re
from thefuck.utils import get_closest
from thefuck.utils import get_closest, for_app
def extract_possibilities(command):
@ -12,14 +12,12 @@ def extract_possibilities(command):
return possib
@for_app('hg')
def match(command, settings):
return (command.script.startswith('hg ')
and ('hg: unknown command' in command.stderr
and '(did you mean one of ' in command.stderr
or "hg: command '" in command.stderr
and "' is ambiguous:" in command.stderr
)
)
return ('hg: unknown command' in command.stderr
and '(did you mean one of ' in command.stderr
or "hg: command '" in command.stderr
and "' is ambiguous:" in command.stderr)
def get_new_command(command, settings):

View File

@ -5,21 +5,21 @@
# The file ~/github.com does not exist.
# Perhaps you meant 'http://github.com'?
#
from thefuck.utils import for_app
@for_app('open', 'xdg-open', 'gnome-open', 'kde-open')
def match(command, settings):
return (command.script.startswith(('open', 'xdg-open', 'gnome-open', 'kde-open'))
and (
'.com' in command.script
or '.net' in command.script
or '.org' in command.script
or '.ly' in command.script
or '.io' in command.script
or '.se' in command.script
or '.edu' in command.script
or '.info' in command.script
or '.me' in command.script
or 'www.' in command.script))
return ('.com' in command.script
or '.net' in command.script
or '.org' in command.script
or '.ly' in command.script
or '.io' in command.script
or '.se' in command.script
or '.edu' in command.script
or '.info' in command.script
or '.me' in command.script
or 'www.' in command.script)
def get_new_command(command, settings):

View File

@ -1,7 +1,10 @@
import re
from thefuck.utils import replace_argument
from thefuck.utils import replace_argument, for_app
from thefuck.specific.sudo import sudo_support
@sudo_support
@for_app('pip')
def match(command, settings):
return ('pip' in command.script and
'unknown command' in command.stderr and

View File

@ -3,11 +3,12 @@
# Example:
# > python foo
# error: python: can't open file 'foo': [Errno 2] No such file or directory
from thefuck.utils import for_app
@for_app('python')
def match(command, settings):
return (command.script.startswith('python ')
and not command.script.endswith('.py'))
return not command.script.endswith('.py')
def get_new_command(command, settings):

View File

@ -1,10 +1,10 @@
import shlex
from thefuck.utils import quote
from thefuck.utils import quote, for_app
@for_app('sed')
def match(command, settings):
return ('sed' in command.script
and "unterminated `s' command" in command.stderr)
return "unterminated `s' command" in command.stderr
def get_new_command(command, settings):

View File

@ -1,4 +1,5 @@
import re
from thefuck.utils import for_app
patterns = [
r'WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!',
@ -12,6 +13,7 @@ offending_pattern = re.compile(
commands = ['ssh', 'scp']
@for_app(*commands)
def match(command, settings):
if not command.script:
return False

View File

@ -2,15 +2,16 @@
The confusion in systemctl's param order is massive.
"""
from thefuck.specific.sudo import sudo_support
from thefuck.utils import for_app
@sudo_support
@for_app('systemctl')
def match(command, settings):
# Catches 'Unknown operation 'service'.' when executing systemctl with
# misordered arguments
cmd = command.script.split()
return ('systemctl' in command.script and
'Unknown operation \'' in command.stderr and
return ('Unknown operation \'' in command.stderr and
len(cmd) - cmd.index('systemctl') == 3)

View File

@ -1,10 +1,10 @@
from thefuck.utils import replace_command
import re
from thefuck.utils import replace_command, for_app
@for_app('tmux')
def match(command, settings):
return ('tmux' in command.script
and 'ambiguous command:' in command.stderr
return ('ambiguous command:' in command.stderr
and 'could be:' in command.stderr)

View File

@ -1,9 +1,10 @@
from thefuck import shells
from thefuck.utils import for_app
@for_app('tsuru')
def match(command, settings):
return (command.script.startswith('tsuru')
and 'not authenticated' in command.stderr
return ('not authenticated' in command.stderr
and 'session has expired' in command.stderr)

View File

@ -1,10 +1,10 @@
import re
from thefuck.utils import get_all_matched_commands, replace_command
from thefuck.utils import get_all_matched_commands, replace_command, for_app
@for_app('tsuru')
def match(command, settings):
return (command.script.startswith('tsuru ')
and ' is not a tsuru command. See "tsuru help".' in command.stderr
return (' is not a tsuru command. See "tsuru help".' in command.stderr
and '\nDid you mean?\n\t' in command.stderr)

View File

@ -1,8 +1,10 @@
from thefuck import shells
from thefuck.utils import for_app
@for_app('vagrant')
def match(command, settings):
return command.script.startswith('vagrant ') and 'run `vagrant up`' in command.stderr.lower()
return 'run `vagrant up`' in command.stderr.lower()
def get_new_command(command, settings):

View File

@ -2,21 +2,18 @@ from functools import wraps
import re
from shlex import split
from ..types import Command
from ..utils import quote
from ..utils import quote, for_app
def git_support(fn):
"""Resolves git aliases and supports testing for both git and hub."""
# supports GitHub's `hub` command
# which is recommended to be used with `alias git=hub`
# but at this point, shell aliases have already been resolved
@for_app('git', 'hub')
@wraps(fn)
def wrapper(command, settings):
# supports GitHub's `hub` command
# which is recommended to be used with `alias git=hub`
# but at this point, shell aliases have already been resolved
is_git_cmd = command.script.startswith(('git', 'hub'))
if not is_git_cmd:
return False
# perform git aliases expansion
if 'trace: alias expansion:' in command.stderr:
search = re.search("trace: alias expansion: ([^ ]*) => ([^\n]*)",