1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-01-18 12:06:04 +00:00

Add kedro_no_such_command rule

This commit is contained in:
Deepyaman Datta 2022-11-21 11:47:04 -05:00
parent ceeaeab94b
commit ec224fb1c9
6 changed files with 101 additions and 6 deletions

View File

@ -288,6 +288,7 @@ following rules are enabled by default:
* `ifconfig_device_not_found` – fixes wrong device names like `wlan0` to `wlp2s0`;
* `java` – removes `.java` extension when running Java programs;
* `javac` – appends missing `.java` when compiling Java files;
* `kedro_no_such_command` – fixes wrong `kedro` commands like `kedro ne`;
* `lein_not_task` – fixes wrong `lein` tasks like `lein rpl`;
* `long_form_help` – changes `-h` to `--help` when the short form version is not supported
* `ln_no_hard_link` – catches hard link creation on directories, suggest symbolic link;

View File

@ -0,0 +1,65 @@
import textwrap
from collections import namedtuple
import pytest
from thefuck.types import Command
from thefuck.rules.kedro_no_such_command import match, get_new_command
USAGE_ERROR_MESSAGE = """\
Usage: kedro [OPTIONS] COMMAND [ARGS]...
Try 'kedro -h' for help.
Error: No such command '{broken_cmd}'.
"""
CommandSuggestions = namedtuple(
'CommandSuggestions', ['broken_cmd', 'new_cmds', 'args'], defaults=([],)
)
@pytest.fixture
def command(request):
script = ' '.join(['kedro', request.param.broken_cmd, *request.param.args])
output = USAGE_ERROR_MESSAGE.format(broken_cmd=request.param.broken_cmd)
if not request.param.new_cmds:
return Command(script, output)
if len(request.param.new_cmds) == 1:
suggestion = '\n\nDid you mean this?'
else:
suggestion = '\n\nDid you mean one of these?\n'
suggestion += textwrap.indent('\n'.join(request.param.new_cmds), ' ' * 4)
return Command(script, output + suggestion)
@pytest.mark.parametrize('command', [
CommandSuggestions('ne', ['new'], ['--starter', 'spaceflights']),
CommandSuggestions('build', ['build-reqs', 'build-docs']),
CommandSuggestions('lin', ['lint', 'info', 'pipeline']),
CommandSuggestions('pipline', ['pipeline', 'lint'], ['create', 'data_processing']),
], indirect=True)
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
CommandSuggestions('create', []),
], indirect=True)
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, result', [
(CommandSuggestions('ne', ['new'], ['--starter', 'spaceflights']),
['kedro new --starter spaceflights']),
(CommandSuggestions('build', ['build-reqs', 'build-docs']),
['kedro build-reqs', 'kedro build-docs']),
(CommandSuggestions('lin', ['lint', 'info', 'pipeline']),
['kedro lint', 'kedro info', 'kedro pipeline']),
(CommandSuggestions('pipline', ['pipeline', 'lint'], ['create', 'data_processing']),
['kedro pipeline create data_processing', 'kedro lint create data_processing']),
], indirect=['command'])
def test_get_new_command(command, result):
assert get_new_command(command) == result

View File

@ -6,25 +6,25 @@ from thefuck.rules.tsuru_not_command import match, get_new_command
@pytest.mark.parametrize('command', [
Command('tsuru log', (
'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n'
'tsuru: "log" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n'
'\tapp-log\n'
'\tlogin\n'
'\tlogout\n'
)),
Command('tsuru app-l', (
'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n'
'tsuru: "app-l" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n'
'\tapp-list\n'
'\tapp-log\n'
)),
Command('tsuru user-list', (
'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n'
'tsuru: "user-list" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n'
'\tteam-user-list\n'
)),
Command('tsuru targetlist', (
'tsuru: "tchururu" is not a tsuru command. See "tsuru help".\n'
'tsuru: "targetlist" is not a tsuru command. See "tsuru help".\n'
'\nDid you mean?\n'
'\ttarget-list\n'
)),

View File

@ -6,7 +6,7 @@ def match(command):
return 'Warning: Command(s) not found:' in command.output
# We need different behavior then in get_all_matched_commands.
# We need different behavior than in get_all_matched_commands.
@eager
def _get_between(content, start, end=None):
should_yield = False

View File

@ -0,0 +1,29 @@
import re
from thefuck.utils import for_app, get_all_matched_commands, replace_argument
@for_app('kedro')
def match(command):
return 'No such command ' in command.output and 'Did you mean ' in command.output
def _get_single_matched_command(stderr):
"""Matches one suggestion found on the same line as 'Did you mean '.
If Kedro only finds one match, it prints it on the same line instead
of on a new line. This won't work with ``get_all_matched_commands``.
"""
return re.findall(r'Did you mean this\?\s*(\w+)', stderr)
def get_new_command(command):
broken_cmd = re.findall(r"No such command '([^']*)'.", command.output)[0]
new_cmds = (_get_single_matched_command(command.output)
or get_all_matched_commands(command.output))
# Kedro already uses `difflib.get_close_matches` when suggesting CLI
# commands, so we don't want `replace_command` to do so differently.
return [replace_argument(command.script, broken_cmd, new_cmd)
for new_cmd in new_cmds]

View File

@ -98,7 +98,7 @@ def get_closest(word, possibilities, cutoff=0.6, fallback_to_first=True):
def get_close_matches(word, possibilities, n=None, cutoff=0.6):
"""Overrides `difflib.get_close_match` to control argument `n`."""
"""Overrides `difflib.get_close_matches` to control argument `n`."""
if n is None:
n = settings.num_close_matches
return difflib_get_close_matches(word, possibilities, n, cutoff)