mirror of
https://github.com/nvbn/thefuck.git
synced 2025-04-14 06:40:49 +01: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.os.environ', {})
|
||||||
monkeypatch.setattr('thefuck.main.wait_output', lambda *_: True)
|
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):
|
def test_get_command_calls(self, Popen):
|
||||||
assert main.get_command(Mock(), Mock(),
|
assert main.get_command(Mock(), Mock(),
|
||||||
['thefuck', 'apt-get', 'search', 'vim']) \
|
['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
|
from psutil import Process, TimeoutExpired
|
||||||
import colorama
|
import colorama
|
||||||
from .history import History
|
from .history import History
|
||||||
from . import logs, conf, types
|
from . import logs, conf, types, shells
|
||||||
|
|
||||||
|
|
||||||
def setup_user_dir():
|
def setup_user_dir():
|
||||||
@ -73,6 +73,7 @@ def get_command(settings, history, args):
|
|||||||
if not script:
|
if not script:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
script = shells.from_shell(script)
|
||||||
history.update(last_command=script,
|
history.update(last_command=script,
|
||||||
last_fixed_command=None)
|
last_fixed_command=None)
|
||||||
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE,
|
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):
|
def run_rule(rule, command, history, settings):
|
||||||
"""Runs command from rule for passed command."""
|
"""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 confirm(new_command, rule.side_effect, settings):
|
||||||
if rule.side_effect:
|
if rule.side_effect:
|
||||||
rule.side_effect(command, settings)
|
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