Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions litestar/cli/_suggestions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from typing import Final, NoReturn

try:
import rich_click as click
except ImportError:
import click # type: ignore[no-redef]

_SUGGEST_OPTION_POSSIBILITIES: Final = {
"-V": ["command `version`"],
"--version": ["command `version`"],
}


def suggest_option(error: click.NoSuchOption) -> NoReturn:
if error.possibilities:
raise error

new_possibilities = _SUGGEST_OPTION_POSSIBILITIES.get(error.option_name)
if new_possibilities is None:
raise error

new_error = click.NoSuchOption(
option_name=error.option_name,
possibilities=new_possibilities,
message=error.message,
ctx=error.ctx,
)
raise new_error from error
11 changes: 10 additions & 1 deletion litestar/cli/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, TypeVar, cast

from litestar.cli._suggestions import suggest_option

try:
from rich_click import NoSuchOption
from rich_click import RichCommand as Command
from rich_click import RichGroup as Group
except ImportError:
from click import Command, Group # type: ignore[assignment]
from click import Command, Group, NoSuchOption # type: ignore[assignment]

from typing import get_type_hints

Expand Down Expand Up @@ -183,6 +186,12 @@ def decorator(f: AnyCallable) -> Command:

return decorator

def parse_args(self, *args: Any, **kwargs: Any) -> list[str]:
try:
return super().parse_args(*args, **kwargs)
except NoSuchOption as e:
suggest_option(e)


class LitestarExtensionGroup(LitestarGroup):
"""``LitestarGroup`` subclass that will load Litestar-CLI extensions from the `litestar.commands` entry_point.
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/test_cli/test_suggestions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import pytest
from click.testing import CliRunner

from litestar.cli.main import litestar_group as cli_command


@pytest.mark.parametrize("option", ["--version", "-V"])
def test_suggest_version(option: str, runner: CliRunner) -> None:
result = runner.invoke(cli_command, option)

assert "Did you mean command `version`?" in result.output
Loading