clarkperkins / click-shell

An extension to click that easily turns your click app into a shell utility
BSD 3-Clause "New" or "Revised" License
90 stars 17 forks source link

Can this work with Typer? #49

Open cool-RR opened 1 year ago

cool-RR commented 1 year ago

I recently started using Typer, which is a layer above Click that parses variable annotations to make arguments and options. Is it possible to use click-shell with Typer commands?

FergusFettes commented 1 year ago

I'm going to make a PR with a solution for this, I will report back when I do, however if I forget, you can also look here, I'll post it there too: https://github.com/tiangolo/typer/issues/185

FergusFettes commented 1 year ago

Actually I just dumped my whole solution in there-- Q for the click-shell devs, would you be interested in integrating the typer-shell solution implemented at that link? Here is the core typer_shell.py:

from typing_extensions import Annotated
from typing import Optional, Callable

from click_shell import make_click_shell
from typer import Context, Typer, Argument

from rich import print

def make_typer_shell(
        app: Typer,
        prompt: str = ">> ",
        intro: str = "\n Welcome to typer-shell! Type help to see commands.\n",
        default: Optional[Callable] = None
) -> None:
    @app.command(hidden=True)
    def help(ctx: Context, command: Annotated[Optional[str], Argument()] = None):
        print("\n Type 'command --help' or 'help <command>' for help on a specific command.")
        if not command:
            ctx.parent.get_help()
            return
        ctx.parent.command.get_command(ctx, command).get_help(ctx)

    @app.command(hidden=True)
    def _default(args: Annotated[Optional[str], Argument()] = None):
        """Default command"""
        if default:
            default(args)
        else:
            print("Command not found. Type 'help' to see commands.")

    @app.callback(invoke_without_command=True)
    def launch(ctx: Context):
        if ctx.invoked_subcommand is None:
            shell = make_click_shell(ctx, prompt=prompt, intro=intro)
            shell.default = _default
            shell.cmdloop()

Happy to make a PR if it is something you are interested in. @clarkperkins

FergusFettes commented 1 year ago

https://github.com/FergusFettes/typer-shell

also added some nice new features to it :)