mirror of
				https://github.com/nvbn/thefuck.git
				synced 2025-10-31 07:04:12 +00:00 
			
		
		
		
	Merge branch 'master' into 682-instant-fuck-mode
This commit is contained in:
		
							
								
								
									
										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) | ||||||
|  |  | ||||||
|     """ |     """ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user