1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-03-13 22:28:33 +00:00

#962: Add the new apt_unable_to_locate rule

Fix #962
This commit is contained in:
Josh 2020-02-29 20:22:30 -06:00 committed by Josh Martin
parent 2ced7a7f33
commit 1d5e40a7c9
3 changed files with 209 additions and 0 deletions

View File

@ -313,6 +313,7 @@ The following rules are enabled by default on specific platforms only:
* `apt_get_search` – changes trying to search using `apt-get` with searching using `apt-cache`;
* `apt_invalid_operation` – fixes invalid `apt` and `apt-get` calls, like `apt-get isntall vim`;
* `apt_list_upgradable` – helps you run `apt list --upgradable` after `apt update`;
* `apt_unable_to_locate rule` – search for packages similar to the one intended with `apt-get` or `apt`;
* `apt_upgrade` – helps you run `apt upgrade` after `apt list --upgradable`;
* `brew_cask_dependency` – installs cask dependencies;
* `brew_install` – fixes formula name for `brew install`;

View File

@ -0,0 +1,153 @@
from io import BytesIO
import pytest
from thefuck.rules.apt_unable_to_locate import match, get_new_command, _get_search_results
from thefuck.types import Command
invalid_operation = 'E: Unable to locate package {}'.format
apt_rabbitmq_search_results = b''' kamailio-rabbitmq-modules/bionic 5.1.2-1ubuntu2 amd64
RabbitMQ and AMQP integration modules for the Kamailio SIP server
libanyevent-rabbitmq-perl/bionic 1.19+dfsg-1 all
asynchronous and multi channel Perl AMQP client
libmojo-rabbitmq-client-perl/bionic 0.1.0-1 all
Mojo::IOLoop based RabbitMQ client
libmono-messaging-rabbitmq4.0-cil/bionic 4.6.2.7+dfsg-1ubuntu1 all
Mono Messaging RabbitMQ library (for CLI 4.0)
libmono-rabbitmq4.0-cil/bionic 4.6.2.7+dfsg-1ubuntu1 all
Mono RabbitMQ.Client library (for CLI 4.0)
librabbitmq-client-java/bionic 5.0.0-1 all
RabbitMQ Java client
librabbitmq-dbg/bionic-updates,bionic-security 0.8.0-1ubuntu0.18.04.2 amd64
AMQP client library written in C - Debug Files
librabbitmq-dev/bionic-updates,bionic-security 0.8.0-1ubuntu0.18.04.2 amd64
AMQP client library written in C - Dev Files
librabbitmq4/bionic-updates,bionic-security 0.8.0-1ubuntu0.18.04.2 amd64
AMQP client library written in C
nagios-plugins-rabbitmq/bionic-updates 1:1.2.0-2.2ubuntu0.18.04.1 all
Set of Nagios checks useful for monitoring a RabbitMQ server
opensips-rabbitmq-module/bionic 2.2.2-3build4 amd64
Interface module to interact with a RabbitMQ server
puppet-module-puppetlabs-rabbitmq/bionic 5.3.1-2 all
Puppet module for rabbitmq, manage everything from vhosts to exchanges
rabbitmq-server/bionic 3.6.10-1 all
AMQP server written in Erlang
'''
apt_get_rabbitmq_search_results = b'''
kamailio-rabbitmq-modules - RabbitMQ and AMQP integration modules for the Kamailio SIP server
libanyevent-rabbitmq-perl - asynchronous and multi channel Perl AMQP client
libmojo-rabbitmq-client-perl - Mojo::IOLoop based RabbitMQ client
libmono-messaging-rabbitmq4.0-cil - Mono Messaging RabbitMQ library (for CLI 4.0)
libmono-rabbitmq4.0-cil - Mono RabbitMQ.Client library (for CLI 4.0)
librabbitmq-client-java - RabbitMQ Java client
librabbitmq-dbg - AMQP client library written in C - Debug Files
librabbitmq-dev - AMQP client library written in C - Dev Files
librabbitmq4 - AMQP client library written in C
nagios-plugins-rabbitmq - Set of Nagios checks useful for monitoring a RabbitMQ server
opensips-rabbitmq-module - Interface module to interact with a RabbitMQ server
puppet-module-puppetlabs-rabbitmq - Puppet module for rabbitmq, manage everything from vhosts to exchanges
rabbitmq-server - AMQP server written in Erlang
'''
rabbitmq_search_search_results = [
'kamailio-rabbitmq-modules',
'libanyevent-rabbitmq-perl',
'libmojo-rabbitmq-client-perl',
'libmono-messaging-rabbitmq4.0-cil',
'libmono-rabbitmq4.0-cil',
'librabbitmq-client-java',
'librabbitmq-dbg',
'librabbitmq-dev',
'librabbitmq4',
'nagios-plugins-rabbitmq',
'opensips-rabbitmq-module',
'puppet-module-puppetlabs-rabbitmq',
'rabbitmq-server'
]
@pytest.mark.parametrize(
'command',
[
(
Command('apt install rabbitmq', invalid_operation('rabbitmq'))
),
(
Command('apt-get install rabbitmq', invalid_operation('rabbitmq'))
)
]
)
def test_match(command):
assert match(command)
@pytest.mark.parametrize(
'command',
[
(
Command('yarn install reactjs', 'a_bad_cmd: command not found')
),
(
Command('npm install reactjs', 'a_bad_cmd: command not found')
),
(
Command('apt upgrade', 'a_bad_cmd: command not found')
)
]
)
def test_not_match(command):
assert not match(command)
@pytest.fixture
def set_search(mocker):
mock = mocker.patch('subprocess.Popen')
def _set_text(text):
mock.return_value.stdout = BytesIO(text)
return _set_text
@pytest.mark.parametrize(
'app, command, search_text, search_results',
[
('apt', 'rabbitmq', apt_rabbitmq_search_results, rabbitmq_search_search_results),
('apt-get', 'rabbitmq', apt_get_rabbitmq_search_results, rabbitmq_search_search_results),
]
)
def test_get_search_results(set_search, app, command, search_text, search_results):
set_search(search_text)
assert _get_search_results(app, command) == search_results
@pytest.mark.parametrize(
'command, expected_command, search_text',
[
(
Command('sudo apt install rabbitmq', invalid_operation('rabbitmq')),
[
'sudo apt install librabbitmq4',
'sudo apt install rabbitmq-server',
'sudo apt install librabbitmq-dev'
],
apt_rabbitmq_search_results,
)
]
)
def test_get_new_command(set_search, command, expected_command, search_text):
set_search(search_text)
actual_command = get_new_command(command)
assert actual_command == expected_command

View File

@ -0,0 +1,55 @@
import subprocess
from thefuck.specific.sudo import sudo_support
from thefuck.utils import for_app, replace_command
@sudo_support
@for_app('apt', 'apt-get')
def match(command):
return "E: Unable to locate package" in command.output
def _parse_apt_search_results(search_text_lines):
search_results = []
for line in search_text_lines:
line = line.decode().strip()
if line.find('/') > 0:
search_results.append(line.split('/')[0])
return search_results
def _parse_apt_cache_search_results(search_text_lines):
search_results = []
for line in search_text_lines:
line = line.decode().strip()
if line.find(' - ') > 0: # spaces are important
search_results.append(line.split(' - ')[0])
return search_results
def _get_search_results(app, command):
_parser = _parse_apt_search_results
if app == 'apt-get':
app = 'apt-cache'
_parser = _parse_apt_cache_search_results
proc = subprocess.Popen([app, 'search', command],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
lines = proc.stdout.readlines()
return _parser(lines)
@sudo_support
def get_new_command(command):
invalid_operation = command.script_parts[-1]
search_results = _get_search_results(command.script_parts[0], invalid_operation)
return replace_command(command, invalid_operation, search_results)