mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 20:11:17 +00:00
git push origin masterMerge branch 'mlk-35_mvn'
This commit is contained in:
commit
bc78f1bbee
@ -181,6 +181,8 @@ using the matched rule and runs it. Rules enabled by default are as follows:
|
||||
* `man_no_space` – fixes man commands without spaces, for example `mandiff`;
|
||||
* `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`;
|
||||
|
40
tests/rules/test_mvn_no_command.py
Normal file
40
tests/rules/test_mvn_no_command.py
Normal file
@ -0,0 +1,40 @@
|
||||
import pytest
|
||||
from thefuck.rules.mvn_no_command import match, get_new_command
|
||||
from tests.utils import Command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('command', [
|
||||
Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. 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', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. 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', 'mvn clean install']),
|
||||
(Command(script='mvn -N', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. 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 -N clean package', 'mvn -N clean install'])])
|
||||
def test_get_new_command(command, new_command):
|
||||
assert get_new_command(command, None) == new_command
|
||||
|
40
tests/rules/test_mvn_unknown_lifecycle_phase.py
Normal file
40
tests/rules/test_mvn_unknown_lifecycle_phase.py
Normal file
@ -0,0 +1,40 @@
|
||||
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 <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. 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 <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. 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 <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. 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):
|
||||
assert get_new_command(command, None) == new_command
|
||||
|
@ -2,8 +2,9 @@ import pytest
|
||||
from mock import Mock
|
||||
from thefuck.utils import wrap_settings,\
|
||||
memoize, get_closest, get_all_executables, replace_argument, \
|
||||
get_all_matched_commands
|
||||
get_all_matched_commands, is_app, for_app
|
||||
from thefuck.types import Settings
|
||||
from tests.utils import Command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('override, old, new', [
|
||||
@ -93,3 +94,25 @@ def test_replace_argument(args, result):
|
||||
'service-status', 'service-unbind'])])
|
||||
def test_get_all_matched_commands(stderr, result):
|
||||
assert list(get_all_matched_commands(stderr)) == result
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('no_memoize')
|
||||
@pytest.mark.parametrize('script, names, result', [
|
||||
('git diff', ['git', 'hub'], True),
|
||||
('hub diff', ['git', 'hub'], True),
|
||||
('hg diff', ['git', 'hub'], False)])
|
||||
def test_is_app(script, names, result):
|
||||
assert is_app(Command(script), *names) == result
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('no_memoize')
|
||||
@pytest.mark.parametrize('script, names, result', [
|
||||
('git diff', ['git', 'hub'], True),
|
||||
('hub diff', ['git', 'hub'], True),
|
||||
('hg diff', ['git', 'hub'], False)])
|
||||
def test_for_app(script, names, result):
|
||||
@for_app(*names)
|
||||
def match(command, settings):
|
||||
return True
|
||||
|
||||
assert match(Command(script), None) == result
|
||||
|
11
thefuck/rules/mvn_no_command.py
Normal file
11
thefuck/rules/mvn_no_command.py
Normal file
@ -0,0 +1,11 @@
|
||||
from thefuck.utils import for_app
|
||||
|
||||
|
||||
@for_app('mvn')
|
||||
def match(command, settings):
|
||||
return 'No goals have been specified for this build' in command.stdout
|
||||
|
||||
|
||||
def get_new_command(command, settings):
|
||||
return [command.script + ' clean package',
|
||||
command.script + ' clean install']
|
32
thefuck/rules/mvn_unknown_lifecycle_phase.py
Normal file
32
thefuck/rules/mvn_unknown_lifecycle_phase.py
Normal file
@ -0,0 +1,32 @@
|
||||
from thefuck.utils import replace_command, for_app
|
||||
from difflib import get_close_matches
|
||||
import re
|
||||
|
||||
|
||||
def _get_failed_lifecycle(command):
|
||||
return re.search(r'\[ERROR\] Unknown lifecycle phase "(.+)"',
|
||||
command.stdout)
|
||||
|
||||
|
||||
def _getavailable_lifecycles(command):
|
||||
return re.search(
|
||||
r'Available lifecycle phases are: (.+) -> \[Help 1\]', command.stdout)
|
||||
|
||||
|
||||
@for_app('mvn')
|
||||
def match(command, settings):
|
||||
failed_lifecycle = _get_failed_lifecycle(command)
|
||||
available_lifecycles = _getavailable_lifecycles(command)
|
||||
return available_lifecycles and failed_lifecycle
|
||||
|
||||
|
||||
def get_new_command(command, settings):
|
||||
failed_lifecycle = _get_failed_lifecycle(command)
|
||||
available_lifecycles = _getavailable_lifecycles(command)
|
||||
if available_lifecycles and failed_lifecycle:
|
||||
selected_lifecycle = get_close_matches(
|
||||
failed_lifecycle.group(1), available_lifecycles.group(1).split(", "),
|
||||
3, 0.6)
|
||||
return replace_command(command, failed_lifecycle.group(1), selected_lifecycle)
|
||||
else:
|
||||
return []
|
@ -132,3 +132,27 @@ def replace_command(command, broken, matched):
|
||||
new_cmds = get_close_matches(broken, matched, cutoff=0.1)
|
||||
return [replace_argument(command.script, broken, new_cmd.strip())
|
||||
for new_cmd in new_cmds]
|
||||
|
||||
|
||||
@memoize
|
||||
def is_app(command, *app_names):
|
||||
"""Returns `True` if command is call to one of passed app names."""
|
||||
for name in app_names:
|
||||
if command.script == name \
|
||||
or command.script.startswith(u'{} '.format(name)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def for_app(*app_names):
|
||||
"""Specifies that matching script is for on of app names."""
|
||||
def decorator(fn):
|
||||
@wraps(fn)
|
||||
def wrapper(command, settings):
|
||||
if is_app(command, *app_names):
|
||||
return fn(command, settings)
|
||||
else:
|
||||
return False
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
Loading…
x
Reference in New Issue
Block a user