mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 20:11:17 +00:00
This commit is contained in:
parent
938f1df035
commit
fcc2a1a40a
@ -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)
|
Loading…
x
Reference in New Issue
Block a user