Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] rich_click.cli.patch() #53

Closed
dwreeves opened this issue Apr 7, 2022 · 2 comments
Closed

[Feature] rich_click.cli.patch() #53

dwreeves opened this issue Apr 7, 2022 · 2 comments

Comments

@dwreeves
Copy link
Collaborator

dwreeves commented Apr 7, 2022

I have the following use case: I want to take another Python library's CLI, make some slight changes, and add it to my app's CLI with click.Group.add_command().

In order to get that library using Rich-Click, I need to patch manually. This is my __main__.py:

# __main__.py
from rich_click import command as rich_command
from rich_click import group as rich_group
from rich_click import RichCommand
from rich_click import RichGroup

import click

click.group = rich_group
click.command = rich_command
click.Command = RichCommand
click.Group = RichGroup

# this is where my CLI is.
from app.cli import cli


cli()

Instead, what we could do is have a function called patch() that does this. Here is what I am thinking:

# __main__.py
from rich_click.cli import patch

patch()

# this is where my CLI is.
from app.cli import cli

cli()

This doesn't need to be a majorly advertised feature-- using it the way I want to is a bit niche-- and it can and should take a back seat to the rich-click CLI. The main use of this would be internally inside rich_click.cli.main, where the following lines of code...

    if len(args) > 1:
        if args[1] == "--":
            del args[1]
    sys.argv = [prog, *args[1:]]
    # patch click before importing the program function
    click.group = rich_group
    click.command = rich_command
    click.Group = RichGroup
    click.Command = RichCommand
    # import the program function
    module = import_module(module_path)
    function = getattr(module, function_name)
    # simply run it: it should be patched as well
    return function()

... could instead look like this ...

    if len(args) > 1:
        if args[1] == "--":
            del args[1]
    sys.argv = [prog, *args[1:]]
    # patch click before importing the program function
    patch()
    # import the program function
    module = import_module(module_path)
    function = getattr(module, function_name)
    # simply run it: it should be patched as well
    return function()

where patch() is defined as (you guessed it):

def patch() -> None:
    """Patch Click internals to use Rich-Click types."""
    click.group = rich_group
    click.command = rich_command
    click.Group = RichGroup
    click.Command = RichCommand

But I suggest separating out the patching function so that it can be exposed for niche situations like the case I'm working on.

WDYT?

@ewels
Copy link
Owner

ewels commented Apr 7, 2022

Sure - so this is essentially refactoring the code with no change to current behaviour so that it can be better accessed by other tools..? I don't see any downsides.. 🤔

Fancy putting in a PR?

@dwreeves
Copy link
Collaborator Author

dwreeves commented Apr 7, 2022

Yes, exactly! And I can do that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants