From 301de75aeed2f502a405ad9b81e005e5b46dcfa4 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Wed, 26 Aug 2015 14:58:45 +0100 Subject: [PATCH] #35 - Fuzzy matching on maven lifecycle targets --- README.md | 1 + .../rules/test_mvn_unknown_lifecycle_phase.py | 41 +++++++++++++++++++ thefuck/rules/mvn_unknown_lifecycle_phase.py | 20 +++++++++ 3 files changed, 62 insertions(+) create mode 100644 tests/rules/test_mvn_unknown_lifecycle_phase.py create mode 100644 thefuck/rules/mvn_unknown_lifecycle_phase.py diff --git a/README.md b/README.md index a78cd643..93832b9f 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `mercurial` – fixes wrong `hg` commands; * `mkdir_p` – adds `-p` when you trying to create directory without parent; * `mvn_no_command` – adds `clean package` to `mvn`; +* `mvn_unknown_lifecycle_phase` – fixes miss spelt lifecycle phases with `mvn`; * `no_command` – fixes wrong console commands, for example `vom/vim`; * `no_such_file` – creates missing directories with `mv` and `cp` commands; * `open` – prepends `http` to address passed to `open`; diff --git a/tests/rules/test_mvn_unknown_lifecycle_phase.py b/tests/rules/test_mvn_unknown_lifecycle_phase.py new file mode 100644 index 00000000..47ff4470 --- /dev/null +++ b/tests/rules/test_mvn_unknown_lifecycle_phase.py @@ -0,0 +1,41 @@ +import pytest +from thefuck.rules.mvn_unknown_lifecycle_phase import match, get_new_command +from tests.utils import Command + + +@pytest.mark.parametrize('command', [ + Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format : or :[:]:. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')]) +def test_match(command): + assert match(command, None) + + +@pytest.mark.parametrize('command', [ + Command(script='mvn clean', stdout=""" +[INFO] Scanning for projects...[INFO] +[INFO] ------------------------------------------------------------------------ +[INFO] Building test 0.2 +[INFO] ------------------------------------------------------------------------ +[INFO] +[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ test --- +[INFO] Deleting /home/mlk/code/test/target +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 0.477s +[INFO] Finished at: Wed Aug 26 13:05:47 BST 2015 +[INFO] Final Memory: 6M/240M +[INFO] ------------------------------------------------------------------------ +"""), + Command(script='mvn --help'), + Command(script='mvn -v') +]) +def test_not_match(command): + assert not match(command, None) + +@pytest.mark.parametrize('command, new_command', [ + (Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format : or :[:]:. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean', 'mvn compile']), + (Command(script='mvn claen package', stdout='[ERROR] Unknown lifecycle phase "claen". You must specify a valid lifecycle phase or a goal in the format : or :[:]:. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean package'])]) +def test_get_new_command(command, new_command): + print new_command + assert get_new_command(command, None) == new_command + diff --git a/thefuck/rules/mvn_unknown_lifecycle_phase.py b/thefuck/rules/mvn_unknown_lifecycle_phase.py new file mode 100644 index 00000000..1dcf1ad1 --- /dev/null +++ b/thefuck/rules/mvn_unknown_lifecycle_phase.py @@ -0,0 +1,20 @@ +from thefuck import shells +from thefuck.utils import replace_command +from difflib import get_close_matches +import re + + +def match(command, settings): + failedLifecycle = re.search('\[ERROR\] Unknown lifecycle phase "(.+)"', command.stdout) + availableLifecycles = re.search('Available lifecycle phases are: (.+) -> \[Help 1\]', command.stdout) + return availableLifecycles and failedLifecycle and command.script.startswith('mvn') + + +def get_new_command(command, settings): + failedLifecycle = re.search('\[ERROR\] Unknown lifecycle phase "(.+)"', command.stdout) + availableLifecycles = re.search('Available lifecycle phases are: (.+) -> \[Help 1\]', command.stdout) + if availableLifecycles and failedLifecycle: + selectedLifecycle = get_close_matches(failedLifecycle.group(1), availableLifecycles.group(1).split(", "), 3, 0.6) + return replace_command(command, failedLifecycle.group(1), selectedLifecycle) + else: + return []