diff --git a/cli/cli.py b/cli/cli.py index 6c979b41..f0a5e2a7 100644 --- a/cli/cli.py +++ b/cli/cli.py @@ -2,11 +2,33 @@ CLI entry point for the 101 Linux Commands application. """ +from typing import List + +import click import typer +from typer.main import TyperGroup from commands import hello, list, search, show, version -app = typer.Typer(help="101 Linux Commands CLI 🚀") + +class CustomTyper(TyperGroup): + def resolve_command(self, ctx: click.Context, args: List[str]): + try: + return super().resolve_command(ctx, args) + except click.exceptions.UsageError as e: + original = e.format_message() + + if "No such command" in original: + script_name = ctx.find_root().info_name or "cli" + hint = f"💡 Hint: Run '{script_name} --help' to see available commands." + + new_message = f"{original}\n{hint}" + raise click.exceptions.UsageError(new_message, ctx=ctx) from e + + raise + + +app = typer.Typer(help="101 Linux Commands CLI 🚀", cls=CustomTyper) app.add_typer(hello.app, name="hello") app.add_typer(list.app, name="list") app.add_typer(version.app, name="version") diff --git a/cli/test_cli.py b/cli/test_cli.py index 946f7690..979c5cb6 100644 --- a/cli/test_cli.py +++ b/cli/test_cli.py @@ -2,6 +2,7 @@ """Basic tests for the CLI module.""" import os +import re import subprocess import sys @@ -70,6 +71,26 @@ def test_version_show_command(): assert "101-linux v0.1.0" in result.stdout +ANSI_ESCAPE = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]") +EMOJI = re.compile("[\U0001f300-\U0001faff]", flags=re.UNICODE) + + +def clean_output(text: str) -> str: + """Remove ANSI colors and emojis.""" + text = ANSI_ESCAPE.sub("", text) + text = EMOJI.sub("", text) + return text + + +def test_unknown_command(): + result = run_cli(["unknowncmd"]) + combined_output = result.stdout + result.stderr + clean = clean_output(combined_output) + + assert "No such command" in clean + assert "Hint: Run 'cli.py --help' to see available commands." in clean + + # ---------------------------- # Tests for `show` subcommand # ---------------------------- @@ -138,4 +159,5 @@ def test_search_no_match(): test_show_invalid() test_search_match() test_search_no_match() + test_unknown_command() print("✅ All tests passed!")