mirror of
				https://github.com/nvbn/thefuck.git
				synced 2025-10-29 22:24:44 +00:00 
			
		
		
		
	This commit is contained in:
		| @@ -50,6 +50,11 @@ class TestGetCommand(object): | ||||
|         monkeypatch.setattr('thefuck.main.os.environ', {}) | ||||
|         monkeypatch.setattr('thefuck.main.wait_output', lambda *_: True) | ||||
|  | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def generic_shell(self, monkeypatch): | ||||
|         monkeypatch.setattr('thefuck.shells.from_shell', lambda x: x) | ||||
|         monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x) | ||||
|  | ||||
|     def test_get_command_calls(self, Popen): | ||||
|         assert main.get_command(Mock(), Mock(), | ||||
|             ['thefuck', 'apt-get', 'search', 'vim']) \ | ||||
|   | ||||
							
								
								
									
										53
									
								
								tests/test_shells.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/test_shells.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| import pytest | ||||
| from mock import Mock | ||||
| from thefuck import shells | ||||
|  | ||||
|  | ||||
| class TestGeneric(object): | ||||
|     def test_from_shell(self): | ||||
|         assert shells.Generic().from_shell('pwd') == 'pwd' | ||||
|  | ||||
|     def test_to_shell(self): | ||||
|         assert shells.Bash().to_shell('pwd') == 'pwd' | ||||
|  | ||||
|  | ||||
| class TestBash(object): | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def Popen(self, monkeypatch): | ||||
|         mock = Mock() | ||||
|         monkeypatch.setattr('thefuck.shells.Popen', mock) | ||||
|         mock.return_value.stdout.read.return_value = ( | ||||
|             b'alias l=\'ls -CF\'\n' | ||||
|             b'alias la=\'ls -A\'\n' | ||||
|             b'alias ll=\'ls -alF\'') | ||||
|         return mock | ||||
|  | ||||
|     @pytest.mark.parametrize('before, after', [ | ||||
|         ('pwd', 'pwd'), | ||||
|         ('ll', 'ls -alF')]) | ||||
|     def test_from_shell(self, before, after): | ||||
|         assert shells.Bash().from_shell(before) == after | ||||
|  | ||||
|     def test_to_shell(self): | ||||
|         assert shells.Bash().to_shell('pwd') == 'pwd' | ||||
|  | ||||
|  | ||||
| class TestZsh(object): | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def Popen(self, monkeypatch): | ||||
|         mock = Mock() | ||||
|         monkeypatch.setattr('thefuck.shells.Popen', mock) | ||||
|         mock.return_value.stdout.read.return_value = ( | ||||
|             b'l=\'ls -CF\'\n' | ||||
|             b'la=\'ls -A\'\n' | ||||
|             b'll=\'ls -alF\'') | ||||
|         return mock | ||||
|  | ||||
|     @pytest.mark.parametrize('before, after', [ | ||||
|         ('pwd', 'pwd'), | ||||
|         ('ll', 'ls -alF')]) | ||||
|     def test_from_shell(self, before, after): | ||||
|         assert shells.Zsh().from_shell(before) == after | ||||
|  | ||||
|     def test_to_shell(self): | ||||
|         assert shells.Zsh().to_shell('pwd') == 'pwd' | ||||
| @@ -7,7 +7,7 @@ import sys | ||||
| from psutil import Process, TimeoutExpired | ||||
| import colorama | ||||
| from .history import History | ||||
| from . import logs, conf, types | ||||
| from . import logs, conf, types, shells | ||||
|  | ||||
|  | ||||
| def setup_user_dir(): | ||||
| @@ -73,6 +73,7 @@ def get_command(settings, history, args): | ||||
|     if not script: | ||||
|         return | ||||
|  | ||||
|     script = shells.from_shell(script) | ||||
|     history.update(last_command=script, | ||||
|                    last_fixed_command=None) | ||||
|     result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, | ||||
| @@ -109,7 +110,7 @@ def confirm(new_command, side_effect, settings): | ||||
|  | ||||
| def run_rule(rule, command, history, settings): | ||||
|     """Runs command from rule for passed command.""" | ||||
|     new_command = rule.get_new_command(command, settings) | ||||
|     new_command = shells.to_shell(rule.get_new_command(command, settings)) | ||||
|     if confirm(new_command, rule.side_effect, settings): | ||||
|         if rule.side_effect: | ||||
|             rule.side_effect(command, settings) | ||||
|   | ||||
							
								
								
									
										80
									
								
								thefuck/shells.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								thefuck/shells.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| """Module with shell specific actions, each shell class should | ||||
| implement `from_shell` and `to_shell` methods. | ||||
|  | ||||
| """ | ||||
| from collections import defaultdict | ||||
| from subprocess import Popen, PIPE | ||||
| import os | ||||
| from psutil import Process | ||||
|  | ||||
|  | ||||
| FNULL = open(os.devnull, 'w') | ||||
|  | ||||
|  | ||||
| class Generic(object): | ||||
|     def _get_aliases(self): | ||||
|         return {} | ||||
|  | ||||
|     def _expand_aliases(self, command_script): | ||||
|         aliases = self._get_aliases() | ||||
|         binary = command_script.split(' ')[0] | ||||
|         if binary in aliases: | ||||
|             return command_script.replace(binary, aliases[binary], 1) | ||||
|         else: | ||||
|             return command_script | ||||
|  | ||||
|     def from_shell(self, command_script): | ||||
|         """Prepares command before running in app.""" | ||||
|         return self._expand_aliases(command_script) | ||||
|  | ||||
|     def to_shell(self, command_script): | ||||
|         """Prepares command for running in shell.""" | ||||
|         return command_script | ||||
|  | ||||
|  | ||||
| class Bash(Generic): | ||||
|     def _parse_alias(self, alias): | ||||
|         name, value = alias.replace('alias ', '', 1).split('=', 1) | ||||
|         if value[0] == value[-1] == '"' or value[0] == value[-1] == "'": | ||||
|             value = value[1:-1] | ||||
|         return name, value | ||||
|  | ||||
|     def _get_aliases(self): | ||||
|         proc = Popen('bash -ic alias', stdout=PIPE, stderr=FNULL, shell=True) | ||||
|         return dict( | ||||
|             self._parse_alias(alias) | ||||
|             for alias in proc.stdout.read().decode('utf-8').split('\n') | ||||
|             if alias) | ||||
|  | ||||
|  | ||||
| class Zsh(Generic): | ||||
|     def _parse_alias(self, alias): | ||||
|         name, value = alias.split('=', 1) | ||||
|         if value[0] == value[-1] == '"' or value[0] == value[-1] == "'": | ||||
|             value = value[1:-1] | ||||
|         return name, value | ||||
|  | ||||
|     def _get_aliases(self): | ||||
|         proc = Popen('zsh -ic alias', stdout=PIPE, stderr=FNULL, shell=True) | ||||
|         return dict( | ||||
|             self._parse_alias(alias) | ||||
|             for alias in proc.stdout.read().decode('utf-8').split('\n') | ||||
|             if alias) | ||||
|  | ||||
|  | ||||
| shells = defaultdict(lambda: Generic(), { | ||||
|     'bash': Bash(), | ||||
|     'zsh': Zsh()}) | ||||
|  | ||||
|  | ||||
| def _get_shell(): | ||||
|     shell = Process(os.getpid()).parent().cmdline()[0] | ||||
|     return shells[shell] | ||||
|  | ||||
|  | ||||
| def from_shell(command): | ||||
|     return _get_shell().from_shell(command) | ||||
|  | ||||
|  | ||||
| def to_shell(command): | ||||
|     return _get_shell().to_shell(command) | ||||
		Reference in New Issue
	
	Block a user