mirror of
				https://github.com/nvbn/thefuck.git
				synced 2025-10-31 07:04:12 +00:00 
			
		
		
		
	Merge pull request #430 from nvbn/429-apt-invalid-operation
#429: Add `apt_invalid_operation` rule
This commit is contained in:
		| @@ -211,6 +211,7 @@ Enabled by default only on specific platforms: | |||||||
|  |  | ||||||
| * `apt_get` – installs app from apt if it not installed (requires `python-commandnotfound` / `python3-commandnotfound`); | * `apt_get` – installs app from apt if it not installed (requires `python-commandnotfound` / `python3-commandnotfound`); | ||||||
| * `apt_get_search` – changes trying to search using `apt-get` with searching using `apt-cache`; | * `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`; | ||||||
| * `brew_install` – fixes formula name for `brew install`; | * `brew_install` – fixes formula name for `brew install`; | ||||||
| * `brew_unknown_command` – fixes wrong brew commands, for example `brew docto/brew doctor`; | * `brew_unknown_command` – fixes wrong brew commands, for example `brew docto/brew doctor`; | ||||||
| * `brew_upgrade` – appends `--all` to `brew upgrade` as per Homebrew's new behaviour; | * `brew_upgrade` – appends `--all` to `brew upgrade` as per Homebrew's new behaviour; | ||||||
|   | |||||||
							
								
								
									
										122
									
								
								tests/rules/test_apt_invalid_operation.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								tests/rules/test_apt_invalid_operation.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | |||||||
|  | from io import BytesIO | ||||||
|  | import pytest | ||||||
|  | from tests.utils import Command | ||||||
|  | from thefuck.rules.apt_invalid_operation import match, get_new_command, \ | ||||||
|  |     _get_operations | ||||||
|  |  | ||||||
|  | invalid_operation = 'E: Invalid operation {}'.format | ||||||
|  | apt_help = b'''apt 1.0.10.2ubuntu1 for amd64 compiled on Oct  5 2015 15:55:05 | ||||||
|  | Usage: apt [options] command | ||||||
|  |  | ||||||
|  | CLI for apt. | ||||||
|  | Basic commands: | ||||||
|  |  list - list packages based on package names | ||||||
|  |  search - search in package descriptions | ||||||
|  |  show - show package details | ||||||
|  |  | ||||||
|  |  update - update list of available packages | ||||||
|  |  | ||||||
|  |  install - install packages | ||||||
|  |  remove  - remove packages | ||||||
|  |  | ||||||
|  |  upgrade - upgrade the system by installing/upgrading packages | ||||||
|  |  full-upgrade - upgrade the system by removing/installing/upgrading packages | ||||||
|  |  | ||||||
|  |  edit-sources - edit the source information file | ||||||
|  | ''' | ||||||
|  | apt_operations = ['list', 'search', 'show', 'update', 'install', 'remove', | ||||||
|  |                   'upgrade', 'full-upgrade', 'edit-sources'] | ||||||
|  |  | ||||||
|  | apt_get_help = b'''apt 1.0.10.2ubuntu1 for amd64 compiled on Oct  5 2015 15:55:05 | ||||||
|  | Usage: apt-get [options] command | ||||||
|  |        apt-get [options] install|remove pkg1 [pkg2 ...] | ||||||
|  |        apt-get [options] source pkg1 [pkg2 ...] | ||||||
|  |  | ||||||
|  | apt-get is a simple command line interface for downloading and | ||||||
|  | installing packages. The most frequently used commands are update | ||||||
|  | and install. | ||||||
|  |  | ||||||
|  | Commands: | ||||||
|  |    update - Retrieve new lists of packages | ||||||
|  |    upgrade - Perform an upgrade | ||||||
|  |    install - Install new packages (pkg is libc6 not libc6.deb) | ||||||
|  |    remove - Remove packages | ||||||
|  |    autoremove - Remove automatically all unused packages | ||||||
|  |    purge - Remove packages and config files | ||||||
|  |    source - Download source archives | ||||||
|  |    build-dep - Configure build-dependencies for source packages | ||||||
|  |    dist-upgrade - Distribution upgrade, see apt-get(8) | ||||||
|  |    dselect-upgrade - Follow dselect selections | ||||||
|  |    clean - Erase downloaded archive files | ||||||
|  |    autoclean - Erase old downloaded archive files | ||||||
|  |    check - Verify that there are no broken dependencies | ||||||
|  |    changelog - Download and display the changelog for the given package | ||||||
|  |    download - Download the binary package into the current directory | ||||||
|  |  | ||||||
|  | Options: | ||||||
|  |   -h  This help text. | ||||||
|  |   -q  Loggable output - no progress indicator | ||||||
|  |   -qq No output except for errors | ||||||
|  |   -d  Download only - do NOT install or unpack archives | ||||||
|  |   -s  No-act. Perform ordering simulation | ||||||
|  |   -y  Assume Yes to all queries and do not prompt | ||||||
|  |   -f  Attempt to correct a system with broken dependencies in place | ||||||
|  |   -m  Attempt to continue if archives are unlocatable | ||||||
|  |   -u  Show a list of upgraded packages as well | ||||||
|  |   -b  Build the source package after fetching it | ||||||
|  |   -V  Show verbose version numbers | ||||||
|  |   -c=? Read this configuration file | ||||||
|  |   -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp | ||||||
|  | See the apt-get(8), sources.list(5) and apt.conf(5) manual | ||||||
|  | pages for more information and options. | ||||||
|  |                        This APT has Super Cow Powers. | ||||||
|  | ''' | ||||||
|  | apt_get_operations = ['update', 'upgrade', 'install', 'remove', 'autoremove', | ||||||
|  |                       'purge', 'source', 'build-dep', 'dist-upgrade', | ||||||
|  |                       'dselect-upgrade', 'clean', 'autoclean', 'check', | ||||||
|  |                       'changelog', 'download'] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.mark.parametrize('script, stderr', [ | ||||||
|  |     ('apt', invalid_operation('saerch')), | ||||||
|  |     ('apt-get', invalid_operation('isntall')), | ||||||
|  |     ('apt-cache', invalid_operation('rumove'))]) | ||||||
|  | def test_match(script, stderr): | ||||||
|  |     assert match(Command(script, stderr=stderr)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.mark.parametrize('script, stderr', [ | ||||||
|  |     ('vim', invalid_operation('vim')), | ||||||
|  |     ('apt-get', "")]) | ||||||
|  | def test_not_match(script, stderr): | ||||||
|  |     assert not match(Command(script, stderr=stderr)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.fixture | ||||||
|  | def set_help(mocker): | ||||||
|  |     mock = mocker.patch('subprocess.Popen') | ||||||
|  |  | ||||||
|  |     def _set_text(text): | ||||||
|  |         mock.return_value.stdout = BytesIO(text) | ||||||
|  |  | ||||||
|  |     return _set_text | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.mark.parametrize('app, help_text, operations', [ | ||||||
|  |     ('apt', apt_help, apt_operations), | ||||||
|  |     ('apt-get', apt_get_help, apt_get_operations) | ||||||
|  | ]) | ||||||
|  | def test_get_operations(set_help, app, help_text, operations): | ||||||
|  |     set_help(help_text) | ||||||
|  |     assert _get_operations(app) == operations | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.mark.parametrize('script, stderr, help_text, result', [ | ||||||
|  |     ('apt-get isntall vim', invalid_operation('isntall'), | ||||||
|  |      apt_get_help, 'apt-get install vim'), | ||||||
|  |     ('apt saerch vim', invalid_operation('saerch'), | ||||||
|  |      apt_help, 'apt search vim'), | ||||||
|  | ]) | ||||||
|  | def test_get_new_command(set_help, stderr, script, help_text, result): | ||||||
|  |     set_help(help_text) | ||||||
|  |     assert get_new_command(Command(script, stderr=stderr))[0] == result | ||||||
							
								
								
									
										53
									
								
								thefuck/rules/apt_invalid_operation.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								thefuck/rules/apt_invalid_operation.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | import subprocess | ||||||
|  | from thefuck.specific.sudo import sudo_support | ||||||
|  | from thefuck.utils import for_app, eager, replace_command | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @for_app('apt', 'apt-get', 'apt-cache') | ||||||
|  | @sudo_support | ||||||
|  | def match(command): | ||||||
|  |     return 'E: Invalid operation' in command.stderr | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @eager | ||||||
|  | def _parse_apt_operations(help_text_lines): | ||||||
|  |     is_commands_list = False | ||||||
|  |     for line in help_text_lines: | ||||||
|  |         line = line.decode().strip() | ||||||
|  |         if is_commands_list and line: | ||||||
|  |             yield line.split()[0] | ||||||
|  |         elif line.startswith('Basic commands:'): | ||||||
|  |             is_commands_list = True | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @eager | ||||||
|  | def _parse_apt_get_and_cache_operations(help_text_lines): | ||||||
|  |     is_commands_list = False | ||||||
|  |     for line in help_text_lines: | ||||||
|  |         line = line.decode().strip() | ||||||
|  |         if is_commands_list: | ||||||
|  |             if not line: | ||||||
|  |                 return | ||||||
|  |  | ||||||
|  |             yield line.split()[0] | ||||||
|  |         elif line.startswith('Commands:'): | ||||||
|  |             is_commands_list = True | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _get_operations(app): | ||||||
|  |     proc = subprocess.Popen([app, '--help'], | ||||||
|  |                             stdout=subprocess.PIPE, | ||||||
|  |                             stderr=subprocess.PIPE) | ||||||
|  |     lines = proc.stdout.readlines() | ||||||
|  |  | ||||||
|  |     if app == 'apt': | ||||||
|  |         return _parse_apt_operations(lines) | ||||||
|  |     else: | ||||||
|  |         return _parse_apt_get_and_cache_operations(lines) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @sudo_support | ||||||
|  | def get_new_command(command): | ||||||
|  |     invalid_operation = command.stderr.split()[-1] | ||||||
|  |     operations = _get_operations(command.script_parts[0]) | ||||||
|  |     return replace_command(command, invalid_operation, operations) | ||||||
		Reference in New Issue
	
	Block a user