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:
parent
bc78f1bbee
commit
0c283ff2b8
@ -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']
|
||||
|
@ -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'
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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 ')
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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)))
|
||||
|
||||
|
||||
|
@ -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():
|
||||
|
@ -1,4 +1,3 @@
|
||||
from thefuck import utils
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
@ -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'))
|
||||
|
@ -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):
|
||||
|
@ -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():
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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]*)",
|
||||
|
Loading…
x
Reference in New Issue
Block a user