diff --git a/tests/rules/test_no_command.py b/tests/rules/test_no_command_apt.py similarity index 74% rename from tests/rules/test_no_command.py rename to tests/rules/test_no_command_apt.py index 1de466a6..c3356dff 100644 --- a/tests/rules/test_no_command.py +++ b/tests/rules/test_no_command_apt.py @@ -1,7 +1,7 @@ from subprocess import PIPE from mock import patch, Mock import pytest -from thefuck.rules.no_command import match, get_new_command +from thefuck.rules.no_command_apt import match, get_new_command from thefuck.main import Command @@ -19,8 +19,17 @@ vom: command not found ''' +@pytest.fixture +def bins_exists(request): + p = patch('thefuck.rules.no_command_apt.which', + return_value=True) + p.start() + request.addfinalizer(p.stop) + + +@pytest.mark.usefixtures('bins_exists') def test_match(command_found, command_not_found): - with patch('thefuck.rules.no_command.Popen') as Popen: + with patch('thefuck.rules.no_command_apt.Popen') as Popen: Popen.return_value.stderr.read.return_value = command_found assert match(Command('aptget install vim', '', ''), None) Popen.assert_called_once_with('/usr/lib/command-not-found aptget', @@ -28,7 +37,7 @@ def test_match(command_found, command_not_found): Popen.return_value.stderr.read.return_value = command_not_found assert not match(Command('ls', '', ''), None) - with patch('thefuck.rules.no_command.Popen') as Popen: + with patch('thefuck.rules.no_command_apt.Popen') as Popen: Popen.return_value.stderr.read.return_value = command_found assert match(Command('sudo aptget install vim', '', ''), Mock(command_not_found='test')) @@ -36,8 +45,9 @@ def test_match(command_found, command_not_found): shell=True, stderr=PIPE) +@pytest.mark.usefixtures('bins_exists') def test_get_new_command(command_found): - with patch('thefuck.rules.no_command._get_output', + with patch('thefuck.rules.no_command_apt._get_output', return_value=command_found.decode()): assert get_new_command(Command('aptget install vim', '', ''), None)\ == 'apt-get install vim' diff --git a/thefuck/rules/no_command.py b/thefuck/rules/no_command_apt.py similarity index 63% rename from thefuck/rules/no_command.py rename to thefuck/rules/no_command_apt.py index 122dbd6f..3e4b628b 100644 --- a/thefuck/rules/no_command.py +++ b/thefuck/rules/no_command_apt.py @@ -1,19 +1,23 @@ from subprocess import Popen, PIPE import re +from thefuck.utils import which + + +def _get_bin(settings): + return getattr(settings, 'command_not_found', '/usr/lib/command-not-found') def _get_output(command, settings): name = command.script.split(' ')[command.script.startswith('sudo')] - check_script = '{} {}'.format(getattr(settings, 'command_not_found', - '/usr/lib/command-not-found'), - name) + check_script = '{} {}'.format(_get_bin(settings), name) result = Popen(check_script, shell=True, stderr=PIPE) return result.stderr.read().decode() def match(command, settings): - output = _get_output(command, settings) - return "No command" in output and "from package" in output + if which('apt-get') and which(_get_bin(settings)): + output = _get_output(command, settings) + return "No command" in output and "from package" in output def get_new_command(command, settings): diff --git a/thefuck/utils.py b/thefuck/utils.py new file mode 100644 index 00000000..2046c4c2 --- /dev/null +++ b/thefuck/utils.py @@ -0,0 +1,19 @@ +import os + + +def which(program): + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + + return None