mirror of
				https://github.com/nvbn/thefuck.git
				synced 2025-10-30 22:54:14 +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_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_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; | ||||
|   | ||||
							
								
								
									
										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