mirror of
				https://github.com/nvbn/thefuck.git
				synced 2025-10-31 07:04:12 +00:00 
			
		
		
		
	Merge branch 'master' of github.com:nvbn/thefuck into pacman
This commit is contained in:
		| @@ -6,4 +6,4 @@ python: | ||||
| install: | ||||
|   - python setup.py develop | ||||
|   - pip install -r requirements.txt | ||||
| script: py.test | ||||
| script: py.test -v | ||||
|   | ||||
| @@ -171,6 +171,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: | ||||
| * `ssh_known_hosts` – removes host from `known_hosts` on warning; | ||||
| * `sudo` – prepends `sudo` to previous command if it failed because of permissions; | ||||
| * `switch_layout` – switches command from your local layout to en; | ||||
| * `whois` – fixes `whois` command; | ||||
| * `apt_get` – installs app from apt if it not installed; | ||||
| * `brew_install` – fixes formula name for `brew install`; | ||||
| * `composer_not_command` – fixes composer command name. | ||||
|   | ||||
							
								
								
									
										0
									
								
								tests/rules/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/rules/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										6
									
								
								tests/rules/conftest.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/rules/conftest.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| import pytest | ||||
|  | ||||
|  | ||||
| @pytest.fixture(autouse=True) | ||||
| def generic_shell(monkeypatch): | ||||
|     monkeypatch.setattr('thefuck.shells.and_', lambda *x: ' && '.join(x)) | ||||
							
								
								
									
										59
									
								
								tests/rules/test_apt_get.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								tests/rules/test_apt_get.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| import pytest | ||||
| from mock import Mock, patch | ||||
| from thefuck.rules import apt_get | ||||
| from thefuck.rules.apt_get import match, get_new_command | ||||
| from tests.utils import Command | ||||
|  | ||||
|  | ||||
| # python-commandnotfound is available in ubuntu 14.04+ | ||||
| @pytest.mark.skipif(not getattr(apt_get, 'enabled_by_default', True), | ||||
|                     reason='Skip if python-commandnotfound is not available') | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='vim', stderr='vim: command not found')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, return_value', [ | ||||
|     (Command(script='vim', stderr='vim: command not found'), | ||||
|      [('vim', 'main'), ('vim-tiny', 'main')])]) | ||||
| @patch('thefuck.rules.apt_get.CommandNotFound', create=True) | ||||
| @patch.multiple(apt_get, create=True, apt_get='apt_get') | ||||
| 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 cmdnf_mock.CommandNotFound.called | ||||
|     assert get_packages.called | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='vim', stderr=''), Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|  | ||||
|  | ||||
| # python-commandnotfound is available in ubuntu 14.04+ | ||||
| @pytest.mark.skipif(not getattr(apt_get, 'enabled_by_default', True), | ||||
|                     reason='Skip if python-commandnotfound is not available') | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('vim'), 'sudo apt-get install vim && vim'), | ||||
|     (Command('convert'), 'sudo apt-get install imagemagick && convert')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command, return_value', [ | ||||
|     (Command('vim'), 'sudo apt-get install vim && vim', | ||||
|      [('vim', 'main'), ('vim-tiny', 'main')]), | ||||
|     (Command('convert'), 'sudo apt-get install imagemagick && convert', | ||||
|      [('imagemagick', 'main'), | ||||
|       ('graphicsmagick-imagemagick-compat', 'universe')])]) | ||||
| @patch('thefuck.rules.apt_get.CommandNotFound', create=True) | ||||
| @patch.multiple(apt_get, create=True, apt_get='apt_get') | ||||
| 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 cmdnf_mock.CommandNotFound.called | ||||
|     assert get_packages.called | ||||
							
								
								
									
										39
									
								
								tests/rules/test_git_add.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								tests/rules/test_git_add.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| import pytest | ||||
| from thefuck.rules.git_add import match, get_new_command | ||||
| from tests.utils import Command | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def did_not_match(target, did_you_forget=True): | ||||
|     error = ("error: pathspec '{}' did not match any " | ||||
|              "file(s) known to git.".format(target)) | ||||
|     if did_you_forget: | ||||
|         error = ("{}\nDid you forget to 'git add'?'".format(error)) | ||||
|     return error | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='git submodule update unknown', | ||||
|             stderr=did_not_match('unknown')), | ||||
|     Command(script='git commit unknown', | ||||
|             stderr=did_not_match('unknown'))])  # Older versions of Git | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='git submodule update known', stderr=('')), | ||||
|     Command(script='git commit known', stderr=('')), | ||||
|     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) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('git submodule update unknown', stderr=did_not_match('unknown')), | ||||
|      'git add -- unknown && git submodule update unknown'), | ||||
|     (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 | ||||
							
								
								
									
										37
									
								
								tests/rules/test_git_checkout.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								tests/rules/test_git_checkout.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import pytest | ||||
| from thefuck.rules.git_checkout import match, get_new_command | ||||
| from tests.utils import Command | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def did_not_match(target, did_you_forget=False): | ||||
|     error = ("error: pathspec '{}' did not match any " | ||||
|              "file(s) known to git.".format(target)) | ||||
|     if did_you_forget: | ||||
|         error = ("{}\nDid you forget to 'git add'?'".format(error)) | ||||
|     return error | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     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) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='git submodule update unknown', | ||||
|             stderr=did_not_match('unknown', True)), | ||||
|     Command(script='git checkout known', stderr=('')), | ||||
|     Command(script='git commit known', stderr=(''))]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command(script='git checkout unknown', stderr=did_not_match('unknown')), | ||||
|      'git branch unknown && git checkout unknown'), | ||||
|     (Command('git commit unknown', stderr=did_not_match('unknown')), | ||||
|      'git branch unknown && git commit unknown')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
							
								
								
									
										39
									
								
								tests/rules/test_git_stash.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								tests/rules/test_git_stash.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| import pytest | ||||
| from thefuck.rules.git_stash import match, get_new_command | ||||
| from tests.utils import Command | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def cherry_pick_error(): | ||||
|     return ('error: Your local changes would be overwritten by cherry-pick.\n' | ||||
|             'hint: Commit your changes or stash them to proceed.\n' | ||||
|             'fatal: cherry-pick failed') | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def rebase_error(): | ||||
|     return ('Cannot rebase: Your index contains uncommitted changes.\n' | ||||
|             'Please commit or stash them.') | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     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) | ||||
|  | ||||
|  | ||||
| @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) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error), | ||||
|      'git stash && git cherry-pick a1b2c3d'), | ||||
|     (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 | ||||
							
								
								
									
										53
									
								
								tests/rules/test_pacman.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/rules/test_pacman.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| import pytest | ||||
| from mock import patch | ||||
| from thefuck.rules import pacman | ||||
| from thefuck.rules.pacman import match, get_new_command | ||||
| from tests.utils import Command | ||||
|  | ||||
|  | ||||
| pacman_cmd = getattr(pacman, 'pacman', 'pacman') | ||||
|  | ||||
|  | ||||
| @pytest.mark.skipif(not getattr(pacman, 'enabled_by_default', True), | ||||
|                     reason='Skip if pacman is not available') | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='vim', stderr='vim: command not found')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, return_value', [ | ||||
|     (Command(script='vim', stderr='vim: command not found'), 'vim foo bar')]) | ||||
| @patch('thefuck.rules.pacman.subprocess') | ||||
| @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 subp_mock.check_output.called | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='vim', stderr=''), Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|  | ||||
|  | ||||
| @pytest.mark.skipif(not getattr(pacman, 'enabled_by_default', True), | ||||
|                     reason='Skip if pacman is not available') | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('vim'), '{} -S vim && vim'.format(pacman_cmd)), | ||||
|     (Command('convert'), '{} -S imagemagick && convert'.format(pacman_cmd))]) | ||||
| def test_get_new_command(command, new_command, mocker): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command, return_value', [ | ||||
|     (Command('vim'), '{} -S vim && vim'.format(pacman_cmd), 'vim foo bar'), | ||||
|     (Command('convert'), '{} -S imagemagick && convert'.format(pacman_cmd), | ||||
|      'imagemagick foo bar')]) | ||||
| @patch('thefuck.rules.pacman.subprocess') | ||||
| @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 subp_mock.check_output.called | ||||
							
								
								
									
										19
									
								
								tests/rules/test_whois.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/rules/test_whois.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| import pytest | ||||
| from thefuck.rules.whois import match, get_new_command | ||||
| from tests.utils import Command | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='whois https://en.wikipedia.org/wiki/Main_Page'), | ||||
|     Command(script='whois https://en.wikipedia.org/'), | ||||
|     Command(script='whois en.wikipedia.org')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('whois https://en.wikipedia.org/wiki/Main_Page'), 'whois en.wikipedia.org'), | ||||
|     (Command('whois https://en.wikipedia.org/'), 'whois en.wikipedia.org'), | ||||
|     (Command('whois en.wikipedia.org'), 'whois wikipedia.org')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
| @@ -1,3 +1,5 @@ | ||||
| from thefuck import shells | ||||
|  | ||||
| try: | ||||
|     import CommandNotFound | ||||
| except ImportError: | ||||
| @@ -20,4 +22,5 @@ def get_new_command(command, settings): | ||||
|     c = CommandNotFound.CommandNotFound() | ||||
|     pkgs = c.getPackages(command.script.split(" ")[0]) | ||||
|     name, _ = pkgs[0] | ||||
|     return "sudo apt-get install {} && {}".format(name, command.script) | ||||
|     formatme = shells.and_('sudo apt-get install {}', '{}') | ||||
|     return formatme.format(name, command.script) | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import re | ||||
| from thefuck import shells | ||||
| from thefuck.utils import sudo_support | ||||
|  | ||||
|  | ||||
| @@ -11,4 +12,5 @@ def match(command, settings): | ||||
|  | ||||
| @sudo_support | ||||
| def get_new_command(command, settings): | ||||
|     return re.sub(r'^cd (.*)', 'mkdir -p \\1 && cd \\1', command.script) | ||||
|     repl = shells.and_('mkdir -p \\1', 'cd \\1') | ||||
|     return re.sub(r'^cd (.*)', repl, command.script) | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import re | ||||
| from thefuck import shells | ||||
|  | ||||
|  | ||||
| def match(command, settings): | ||||
| @@ -12,4 +13,5 @@ def get_new_command(command, settings): | ||||
|             r"error: pathspec '([^']*)' " | ||||
|             "did not match any file\(s\) known to git.", command.stderr)[0] | ||||
|  | ||||
|     return 'git add -- {} && {}'.format(missing_file, command.script) | ||||
|     formatme = shells.and_('git add -- {}', '{}') | ||||
|     return formatme.format(missing_file, command.script) | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import re | ||||
| from thefuck import shells | ||||
|  | ||||
|  | ||||
| def match(command, settings): | ||||
| @@ -12,4 +13,5 @@ def get_new_command(command, settings): | ||||
|             r"error: pathspec '([^']*)' " | ||||
|             "did not match any file\(s\) known to git.", command.stderr)[0] | ||||
|  | ||||
|     return 'git branch {} && {}'.format(missing_file, command.script) | ||||
|     formatme = shells.and_('git branch {}', '{}') | ||||
|     return formatme.format(missing_file, command.script) | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| from thefuck import shells | ||||
|  | ||||
|  | ||||
| def match(command, settings): | ||||
|     # catches "Please commit or stash them" and "Please, commit your changes or | ||||
|     # stash them before you can switch branches." | ||||
| @@ -5,4 +8,5 @@ def match(command, settings): | ||||
|  | ||||
|  | ||||
| def get_new_command(command, settings): | ||||
|     return 'git stash && ' + command.script | ||||
|     formatme = shells.and_('git stash', '{}') | ||||
|     return formatme.format(command.script) | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import re | ||||
| from thefuck import shells | ||||
|  | ||||
|  | ||||
| patterns = ( | ||||
| @@ -25,4 +26,5 @@ def get_new_command(command, settings): | ||||
|             file = file[0] | ||||
|             dir = file[0:file.rfind('/')] | ||||
|  | ||||
|             return 'mkdir -p {} && {}'.format(dir, command.script) | ||||
|             formatme = shells.and_('mkdir -p {}', '{}') | ||||
|             return formatme.format(dir, command.script) | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import subprocess | ||||
| from thefuck.utils import DEVNULL, which | ||||
| from thefuck import shells | ||||
|  | ||||
|  | ||||
| def __get_pkgfile(command): | ||||
| @@ -19,7 +20,8 @@ def match(command, settings): | ||||
| def get_new_command(command, settings): | ||||
|     package = __get_pkgfile(command)[0] | ||||
|  | ||||
|     return '{} -S {} && {}'.format(pacman, package, command.script) | ||||
|     formatme = shells.and_('{} -S {}', '{}') | ||||
|     return formatme.format(pacman, package, command.script) | ||||
|  | ||||
|  | ||||
| if not which('pkgfile'): | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from urllib.parse import urlparse | ||||
| # -*- encoding: utf-8 -*- | ||||
| from six.moves.urllib.parse import urlparse | ||||
|  | ||||
|  | ||||
| def match(command, settings): | ||||
|   | ||||
| @@ -47,8 +47,14 @@ class Generic(object): | ||||
|             with open(history_file_name, 'a') as history: | ||||
|                 history.write(self._get_history_line(command_script)) | ||||
|  | ||||
|     def and_(self, *commands): | ||||
|         return ' && '.join(commands) | ||||
|  | ||||
|  | ||||
| class Bash(Generic): | ||||
|     def app_alias(self): | ||||
|         return "\nalias fuck='eval $(thefuck $(fc -ln -1)); history -r'\n" | ||||
|  | ||||
|     def _parse_alias(self, alias): | ||||
|         name, value = alias.replace('alias ', '', 1).split('=', 1) | ||||
|         if value[0] == value[-1] == '"' or value[0] == value[-1] == "'": | ||||
| @@ -71,6 +77,9 @@ class Bash(Generic): | ||||
|  | ||||
|  | ||||
| class Zsh(Generic): | ||||
|     def app_alias(self): | ||||
|         return "\nalias fuck='eval $(thefuck $(fc -ln -1 | tail -n 1)); fc -R'\n" | ||||
|  | ||||
|     def _parse_alias(self, alias): | ||||
|         name, value = alias.split('=', 1) | ||||
|         if value[0] == value[-1] == '"' or value[0] == value[-1] == "'": | ||||
| @@ -144,3 +153,7 @@ def app_alias(): | ||||
|  | ||||
| def put_to_history(command): | ||||
|     return _get_shell().put_to_history(command) | ||||
|  | ||||
|  | ||||
| def and_(*commands): | ||||
|     return _get_shell().and_(*commands) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user