diff --git a/README.md b/README.md index 1c8fe389..4ff50cd2 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,7 @@ following rules are enabled by default: * `cd_mkdir` – creates directories before cd'ing into them; * `cd_parent` – changes `cd..` to `cd ..`; * `chmod_x` – add execution bit; +* `choco_install` – append common suffixes for chocolatey packages; * `composer_not_command` – fixes composer command name; * `cp_omitting_directory` – adds `-a` when you `cp` directory; * `cpp11` – adds missing `-std=c++11` to `g++` or `clang++`; diff --git a/tests/rules/test_choco_install.py b/tests/rules/test_choco_install.py new file mode 100644 index 00000000..0bfbb0d2 --- /dev/null +++ b/tests/rules/test_choco_install.py @@ -0,0 +1,86 @@ +import pytest +from thefuck.rules.choco_install import match, get_new_command +from thefuck.types import Command + + +package_not_found_error = ( + 'Chocolatey v0.10.15\n' + 'Installing the following packages:\n' + 'logstitcher\n' + 'By installing you accept licenses for the packages.\n' + 'logstitcher not installed. The package was not found with the source(s) listed.\n' + ' Source(s): \'https://chocolatey.org/api/v2/\'\n' + ' NOTE: When you specify explicit sources, it overrides default sources.\n' + 'If the package version is a prerelease and you didn\'t specify `--pre`,\n' + ' the package may not be found.\n' + 'Please see https://chocolatey.org/docs/troubleshooting for more\n' + ' assistance.\n' + '\n' + 'Chocolatey installed 0/1 packages. 1 packages failed.\n' + ' See the log for details (C:\\ProgramData\\chocolatey\\logs\\chocolatey.log).\n' + '\n' + 'Failures\n' + ' - logstitcher - logstitcher not installed. The package was not found with the source(s) listed.\n' + ' Source(s): \'https://chocolatey.org/api/v2/\'\n' + ' NOTE: When you specify explicit sources, it overrides default sources.\n' + 'If the package version is a prerelease and you didn\'t specify `--pre`,\n' + ' the package may not be found.\n' + 'Please see https://chocolatey.org/docs/troubleshooting for more\n' + ' assistance.\n' +) + + +@pytest.mark.parametrize('command', [ + Command('choco install logstitcher', package_not_found_error), + Command('cinst logstitcher', package_not_found_error), + Command('choco install logstitcher -y', package_not_found_error), + Command('cinst logstitcher -y', package_not_found_error), + Command('choco install logstitcher -y -n=test', package_not_found_error), + Command('cinst logstitcher -y -n=test', package_not_found_error), + Command('choco install logstitcher -y -n=test /env', package_not_found_error), + Command('cinst logstitcher -y -n=test /env', package_not_found_error), + Command('choco install chocolatey -y', package_not_found_error), + Command('cinst chocolatey -y', package_not_found_error)]) +def test_match(command): + assert match(command) + + +@pytest.mark.parametrize('command', [ + Command('choco /?', ''), + Command('choco upgrade logstitcher', ''), + Command('cup logstitcher', ''), + Command('choco upgrade logstitcher -y', ''), + Command('cup logstitcher -y', ''), + Command('choco upgrade logstitcher -y -n=test', ''), + Command('cup logstitcher -y -n=test', ''), + Command('choco upgrade logstitcher -y -n=test /env', ''), + Command('cup logstitcher -y -n=test /env', ''), + Command('choco upgrade chocolatey -y', ''), + Command('cup chocolatey -y', ''), + Command('choco uninstall logstitcher', ''), + Command('cuninst logstitcher', ''), + Command('choco uninstall logstitcher -y', ''), + Command('cuninst logstitcher -y', ''), + Command('choco uninstall logstitcher -y -n=test', ''), + Command('cuninst logstitcher -y -n=test', ''), + Command('choco uninstall logstitcher -y -n=test /env', ''), + Command('cuninst logstitcher -y -n=test /env', ''), + Command('choco uninstall chocolatey -y', ''), + Command('cuninst chocolatey -y', '')]) +def not_test_match(command): + assert not match(command) + + +@pytest.mark.parametrize('before, after', [ + ('choco install logstitcher', 'choco install logstitcher.install'), + ('cinst logstitcher', 'cinst logstitcher.install'), + ('choco install logstitcher -y', 'choco install logstitcher.install -y'), + ('cinst logstitcher -y', 'cinst logstitcher.install -y'), + ('choco install logstitcher -y -n=test', 'choco install logstitcher.install -y -n=test'), + ('cinst logstitcher -y -n=test', 'cinst logstitcher.install -y -n=test'), + ('choco install logstitcher -y -n=test /env', 'choco install logstitcher.install -y -n=test /env'), + ('cinst logstitcher -y -n=test /env', 'cinst logstitcher.install -y -n=test /env'), + ('choco install chocolatey -y', 'choco install chocolatey.install -y'), + ('cinst chocolatey -y', 'cinst chocolatey.install -y'), ]) +def test_get_new_command(before, after): + assert (get_new_command(Command(before, '')) == after) diff --git a/thefuck/rules/choco_install.py b/thefuck/rules/choco_install.py new file mode 100644 index 00000000..8c073022 --- /dev/null +++ b/thefuck/rules/choco_install.py @@ -0,0 +1,25 @@ +from thefuck.utils import for_app, which + + +@for_app("choco", "cinst") +def match(command): + return ((command.script.startswith('choco install') or 'cinst' in command.script_parts) + and 'Installing the following packages' in command.output) + + +def get_new_command(command): + # Find the argument that is the package name + for script_part in command.script_parts: + if ( + script_part not in ["choco", "cinst", "install"] + # Need exact match (bc chocolatey is a package) + and not script_part.startswith('-') + # Leading hyphens are parameters; some packages contain them though + and '=' not in script_part and '/' not in script_part + # These are certainly parameters + ): + return command.script.replace(script_part, script_part + ".install") + return [] + + +enabled_by_default = bool(which("choco")) or bool(which("cinst"))