mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 20:11:17 +00:00
Merge branch 'master' into 682-instant-fuck-mode
This commit is contained in:
commit
f83e41137b
4
setup.py
4
setup.py
@ -53,5 +53,5 @@ setup(name='thefuck',
|
|||||||
install_requires=install_requires,
|
install_requires=install_requires,
|
||||||
extras_require=extras_require,
|
extras_require=extras_require,
|
||||||
entry_points={'console_scripts': [
|
entry_points={'console_scripts': [
|
||||||
'thefuck = thefuck.main:main',
|
'thefuck = thefuck.entrypoints.main:main',
|
||||||
'fuck = thefuck.not_configured:main']})
|
'fuck = thefuck.entrypoints.not_configured:main']})
|
||||||
|
0
tests/entrypoints/__init__.py
Normal file
0
tests/entrypoints/__init__.py
Normal file
26
tests/entrypoints/test_fix_command.py
Normal file
26
tests/entrypoints/test_fix_command.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import pytest
|
||||||
|
from mock import Mock
|
||||||
|
from thefuck.entrypoints.fix_command import _get_raw_command
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetRawCommand(object):
|
||||||
|
def test_from_force_command_argument(self):
|
||||||
|
known_args = Mock(force_command=['git', 'brunch'])
|
||||||
|
assert _get_raw_command(known_args) == ['git', 'brunch']
|
||||||
|
|
||||||
|
def test_from_command_argument(self, os_environ):
|
||||||
|
os_environ['TF_HISTORY'] = None
|
||||||
|
known_args = Mock(force_command=None,
|
||||||
|
command=['sl'])
|
||||||
|
assert _get_raw_command(known_args) == ['sl']
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('history, result', [
|
||||||
|
('git br', 'git br'),
|
||||||
|
('git br\nfcuk', 'git br'),
|
||||||
|
('git br\nfcuk\nls', 'ls'),
|
||||||
|
('git br\nfcuk\nls\nfuk', 'ls')])
|
||||||
|
def test_from_history(self, os_environ, history, result):
|
||||||
|
os_environ['TF_HISTORY'] = history
|
||||||
|
known_args = Mock(force_command=None,
|
||||||
|
command=None)
|
||||||
|
assert _get_raw_command(known_args) == [result]
|
@ -3,13 +3,13 @@ import json
|
|||||||
from six import StringIO
|
from six import StringIO
|
||||||
from mock import MagicMock
|
from mock import MagicMock
|
||||||
from thefuck.shells.generic import ShellConfiguration
|
from thefuck.shells.generic import ShellConfiguration
|
||||||
from thefuck.not_configured import main
|
from thefuck.entrypoints.not_configured import main
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def usage_tracker(mocker):
|
def usage_tracker(mocker):
|
||||||
return mocker.patch(
|
return mocker.patch(
|
||||||
'thefuck.not_configured._get_not_configured_usage_tracker_path',
|
'thefuck.entrypoints.not_configured._get_not_configured_usage_tracker_path',
|
||||||
new_callable=MagicMock)
|
new_callable=MagicMock)
|
||||||
|
|
||||||
|
|
||||||
@ -44,13 +44,13 @@ def _change_tracker(usage_tracker_io, pid):
|
|||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def shell_pid(mocker):
|
def shell_pid(mocker):
|
||||||
return mocker.patch('thefuck.not_configured._get_shell_pid',
|
return mocker.patch('thefuck.entrypoints.not_configured._get_shell_pid',
|
||||||
new_callable=MagicMock)
|
new_callable=MagicMock)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def shell(mocker):
|
def shell(mocker):
|
||||||
shell = mocker.patch('thefuck.not_configured.shell',
|
shell = mocker.patch('thefuck.entrypoints.not_configured.shell',
|
||||||
new_callable=MagicMock)
|
new_callable=MagicMock)
|
||||||
shell.get_history.return_value = []
|
shell.get_history.return_value = []
|
||||||
shell.how_to_configure.return_value = ShellConfiguration(
|
shell.how_to_configure.return_value = ShellConfiguration(
|
||||||
@ -63,7 +63,7 @@ def shell(mocker):
|
|||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def shell_config(mocker):
|
def shell_config(mocker):
|
||||||
path_mock = mocker.patch('thefuck.not_configured.Path',
|
path_mock = mocker.patch('thefuck.entrypoints.not_configured.Path',
|
||||||
new_callable=MagicMock)
|
new_callable=MagicMock)
|
||||||
return path_mock.return_value \
|
return path_mock.return_value \
|
||||||
.expanduser.return_value \
|
.expanduser.return_value \
|
||||||
@ -73,7 +73,7 @@ def shell_config(mocker):
|
|||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def logs(mocker):
|
def logs(mocker):
|
||||||
return mocker.patch('thefuck.not_configured.logs',
|
return mocker.patch('thefuck.entrypoints.not_configured.logs',
|
||||||
new_callable=MagicMock)
|
new_callable=MagicMock)
|
||||||
|
|
||||||
|
|
0
thefuck/entrypoints/__init__.py
Normal file
0
thefuck/entrypoints/__init__.py
Normal file
20
thefuck/entrypoints/alias.py
Normal file
20
thefuck/entrypoints/alias.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import six
|
||||||
|
from ..logs import warn
|
||||||
|
from ..shells import shell
|
||||||
|
|
||||||
|
|
||||||
|
def print_alias(known_args):
|
||||||
|
if six.PY2:
|
||||||
|
warn("The Fuck will drop Python 2 support soon, more details "
|
||||||
|
"https://github.com/nvbn/thefuck/issues/685")
|
||||||
|
|
||||||
|
if known_args.enable_experimental_instant_mode:
|
||||||
|
if six.PY2:
|
||||||
|
warn("Instant mode not supported with Python 2")
|
||||||
|
alias = shell.app_alias(known_args.alias)
|
||||||
|
else:
|
||||||
|
alias = shell.instant_mode_alias(known_args.alias)
|
||||||
|
else:
|
||||||
|
alias = shell.app_alias(known_args.alias)
|
||||||
|
|
||||||
|
print(alias)
|
47
thefuck/entrypoints/fix_command.py
Normal file
47
thefuck/entrypoints/fix_command.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
from pprint import pformat
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from difflib import SequenceMatcher
|
||||||
|
from .. import logs, types, const
|
||||||
|
from ..conf import settings
|
||||||
|
from ..corrector import get_corrected_commands
|
||||||
|
from ..exceptions import EmptyCommand
|
||||||
|
from ..ui import select_command
|
||||||
|
from ..utils import get_alias, get_all_executables
|
||||||
|
|
||||||
|
|
||||||
|
def _get_raw_command(known_args):
|
||||||
|
if known_args.force_command:
|
||||||
|
return known_args.force_command
|
||||||
|
elif not os.environ.get('TF_HISTORY'):
|
||||||
|
return known_args.command
|
||||||
|
else:
|
||||||
|
history = os.environ['TF_HISTORY'].split('\n')[::-1]
|
||||||
|
alias = get_alias()
|
||||||
|
executables = get_all_executables()
|
||||||
|
for command in history:
|
||||||
|
diff = SequenceMatcher(a=alias, b=command).ratio()
|
||||||
|
if diff < const.DIFF_WITH_ALIAS or command in executables:
|
||||||
|
return [command]
|
||||||
|
|
||||||
|
|
||||||
|
def fix_command(known_args):
|
||||||
|
"""Fixes previous command. Used when `thefuck` called without arguments."""
|
||||||
|
settings.init(known_args)
|
||||||
|
with logs.debug_time('Total'):
|
||||||
|
logs.debug(u'Run with settings: {}'.format(pformat(settings)))
|
||||||
|
raw_command = _get_raw_command(known_args)
|
||||||
|
|
||||||
|
try:
|
||||||
|
command = types.Command.from_raw_script(raw_command)
|
||||||
|
except EmptyCommand:
|
||||||
|
logs.debug('Empty command, nothing to do')
|
||||||
|
return
|
||||||
|
|
||||||
|
corrected_commands = get_corrected_commands(command)
|
||||||
|
selected_command = select_command(corrected_commands)
|
||||||
|
|
||||||
|
if selected_command:
|
||||||
|
selected_command.run(command)
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
29
thefuck/entrypoints/main.py
Normal file
29
thefuck/entrypoints/main.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Initialize output before importing any module, that can use colorama.
|
||||||
|
from ..system import init_output
|
||||||
|
|
||||||
|
init_output()
|
||||||
|
|
||||||
|
import os # noqa: E402
|
||||||
|
import sys # noqa: E402
|
||||||
|
from .. import logs # noqa: E402
|
||||||
|
from ..argument_parser import Parser # noqa: E402
|
||||||
|
from ..utils import get_installation_info # noqa: E402
|
||||||
|
from .alias import print_alias # noqa: E402
|
||||||
|
from .fix_command import fix_command # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = Parser()
|
||||||
|
known_args = parser.parse(sys.argv)
|
||||||
|
|
||||||
|
if known_args.help:
|
||||||
|
parser.print_help()
|
||||||
|
elif known_args.version:
|
||||||
|
logs.version(get_installation_info().version,
|
||||||
|
sys.version.split()[0])
|
||||||
|
elif known_args.command or 'TF_HISTORY' in os.environ:
|
||||||
|
fix_command(known_args)
|
||||||
|
elif known_args.alias:
|
||||||
|
print_alias(known_args)
|
||||||
|
else:
|
||||||
|
parser.print_usage()
|
@ -1,5 +1,5 @@
|
|||||||
# Initialize output before importing any module, that can use colorama.
|
# Initialize output before importing any module, that can use colorama.
|
||||||
from .system import init_output
|
from ..system import init_output
|
||||||
|
|
||||||
init_output()
|
init_output()
|
||||||
|
|
||||||
@ -8,11 +8,11 @@ import json # noqa: E402
|
|||||||
import time # noqa: E402
|
import time # noqa: E402
|
||||||
import six # noqa: E402
|
import six # noqa: E402
|
||||||
from psutil import Process # noqa: E402
|
from psutil import Process # noqa: E402
|
||||||
from . import logs, const # noqa: E402
|
from .. import logs, const # noqa: E402
|
||||||
from .shells import shell # noqa: E402
|
from ..shells import shell # noqa: E402
|
||||||
from .conf import settings # noqa: E402
|
from ..conf import settings # noqa: E402
|
||||||
from .system import Path # noqa: E402
|
from ..system import Path # noqa: E402
|
||||||
from .utils import get_cache_dir # noqa: E402
|
from ..utils import get_cache_dir # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
def _get_shell_pid():
|
def _get_shell_pid():
|
@ -1,87 +0,0 @@
|
|||||||
# Initialize output before importing any module, that can use colorama.
|
|
||||||
from .system import init_output
|
|
||||||
|
|
||||||
init_output()
|
|
||||||
|
|
||||||
from pprint import pformat # noqa: E402
|
|
||||||
import os # noqa: E402
|
|
||||||
import sys # noqa: E402
|
|
||||||
from difflib import SequenceMatcher # noqa: E402
|
|
||||||
import six # noqa: E402
|
|
||||||
from . import logs, types, const # noqa: E402
|
|
||||||
from .shells import shell # noqa: E402
|
|
||||||
from .conf import settings # noqa: E402
|
|
||||||
from .corrector import get_corrected_commands # noqa: E402
|
|
||||||
from .exceptions import EmptyCommand # noqa: E402
|
|
||||||
from .ui import select_command # noqa: E402
|
|
||||||
from .argument_parser import Parser # noqa: E402
|
|
||||||
from .utils import (get_installation_info, get_alias,
|
|
||||||
get_all_executables) # noqa: E402
|
|
||||||
from .logs import warn # noqa: E402
|
|
||||||
|
|
||||||
|
|
||||||
def _get_raw_command(known_args):
|
|
||||||
if known_args.force_command:
|
|
||||||
return known_args.force_command
|
|
||||||
elif 'TF_HISTORY' not in os.environ:
|
|
||||||
return known_args.command
|
|
||||||
else:
|
|
||||||
history = os.environ['TF_HISTORY'].split('\n')[::-1]
|
|
||||||
alias = get_alias()
|
|
||||||
executables = get_all_executables()
|
|
||||||
for command in history:
|
|
||||||
diff = SequenceMatcher(a=alias, b=command).ratio()
|
|
||||||
if diff < const.DIFF_WITH_ALIAS or command in executables:
|
|
||||||
return [command]
|
|
||||||
|
|
||||||
|
|
||||||
def fix_command(known_args):
|
|
||||||
"""Fixes previous command. Used when `thefuck` called without arguments."""
|
|
||||||
settings.init(known_args)
|
|
||||||
with logs.debug_time('Total'):
|
|
||||||
logs.debug(u'Run with settings: {}'.format(pformat(settings)))
|
|
||||||
raw_command = _get_raw_command(known_args)
|
|
||||||
|
|
||||||
try:
|
|
||||||
command = types.Command.from_raw_script(raw_command)
|
|
||||||
except EmptyCommand:
|
|
||||||
logs.debug('Empty command, nothing to do')
|
|
||||||
return
|
|
||||||
|
|
||||||
corrected_commands = get_corrected_commands(command)
|
|
||||||
selected_command = select_command(corrected_commands)
|
|
||||||
|
|
||||||
if selected_command:
|
|
||||||
selected_command.run(command)
|
|
||||||
else:
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = Parser()
|
|
||||||
known_args = parser.parse(sys.argv)
|
|
||||||
|
|
||||||
if known_args.help:
|
|
||||||
parser.print_help()
|
|
||||||
elif known_args.version:
|
|
||||||
logs.version(get_installation_info().version,
|
|
||||||
sys.version.split()[0])
|
|
||||||
elif known_args.command or 'TF_HISTORY' in os.environ:
|
|
||||||
fix_command(known_args)
|
|
||||||
elif known_args.alias:
|
|
||||||
if six.PY2:
|
|
||||||
warn("The Fuck will drop Python 2 support soon, more details "
|
|
||||||
"https://github.com/nvbn/thefuck/issues/685")
|
|
||||||
|
|
||||||
if known_args.enable_experimental_instant_mode:
|
|
||||||
if six.PY2:
|
|
||||||
warn("Instant mode not supported with Python 2")
|
|
||||||
alias = shell.app_alias(known_args.alias)
|
|
||||||
else:
|
|
||||||
alias = shell.instant_mode_alias(known_args.alias)
|
|
||||||
else:
|
|
||||||
alias = shell.app_alias(known_args.alias)
|
|
||||||
|
|
||||||
print(alias)
|
|
||||||
else:
|
|
||||||
parser.print_usage()
|
|
@ -75,7 +75,7 @@ def default_settings(params):
|
|||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
@default_settings({'apt': '/usr/bin/apt'})
|
@default_settings({'apt': '/usr/bin/apt'})
|
||||||
def match(command, settings):
|
def match(command):
|
||||||
print(settings.apt)
|
print(settings.apt)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user