-
Notifications
You must be signed in to change notification settings - Fork 38
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
Command Aliases? #101
Comments
Happy to take a look at a pull-request 👍🏻 🙃 |
@justquick You can use Cloup for command aliases, which works great and is actively maintained: https://github.com/janluke/cloup Now if you want to have these command aliases properly formatted and coloured in your help screen, you can use Click Extra: https://github.com/kdeldycke/click-extra#readme |
There is a more interesting discussion here to be had eventually about how rich-click should support common click extensions (one I am personally fond of being click-didyoumean). I think, ideally, you'd want rich-click to have the following two things be true:
These two objectives can be in conflict, but they don't necessarily need to be. The most blunt way to do it is something like this: def command(name=None, cls=RichCommand, **attrs) -> Callable[..., RichCommand]:
def wrapper(fn):
# some stuff goes here
if not issubclass(cls, RichBaseCommand):
class CustomCommandClass(RichBaseCommand, cls):
pass
cls = CustomCommandClass
# some stuff goes here
return wrapper
def group(name=None, cls=RichGroup, **attrs) -> Callable[..., RichCommand]:
def wrapper(fn):
# some stuff goes here
if not issubclass(cls, RichBaseCommand):
class CustomGroupClass(RichBaseCommand, cls):
pass
cls = CustomGroupClass
if issubclass(cls, Group):
class CustomCommandClass(RichBaseCommand, cls.command_class):
pass
cls.command_class = CustomCommandClass
# some stuff goes here
return wrapper This means that a user can do something like this and still get rich formatting out of it: import rich_click as click
from click_didyoumean import DYMGroup
@click.group(cls=DYMGroup)
def cli():
...
@cli.command()
def foo():
"""Run a command."""
click.echo('foo')
cli() But, it is a little magical, would require extensive testing, and would require some feedback from users on whether an approach like this would be a good idea. Also, it would not work for all extensions (see below). Another option is to just bake common click extensions into rich-click directly. This is more work, more stuff to maintain on rich-click's end, we'd need to think about what the API is for enabling extensions, and we'd probably miss a few things, and overall it extends rich-click's scope as a project quite a bit. There is an upside though, which is that chaining together multiple "extensions" becomes a little easier for users, since we would just support everything out of the box and we'd be able to test to make sure the extension behavior all plays nicely with each other. For example, right now what you would need to do to combine rich-click and click-didyoumean: import rich_click as click
from click_didyoumean import DYMGroup
class MyGroup(click.RichGroup, DYMGroup):
command_class = click.RichCommand
@click.group(cls=MyGroup)
def cli():
...
@cli.command()
def foo():
"""Run a command."""
click.echo('foo')
cli() It works fine?
But it's also pretty generically formatted, and could be more "rich." By adding click-didyoumean functionality directly into rich-click we get more control over it.
import rich_click as click
from click_aliases import ClickAliasedGroup
class MyGroup(click.RichGroup, ClickAliasedGroup):
command_class = click.RichCommand
@click.group(cls=MyGroup)
def cli():
pass
@cli.command(aliases=['bar', 'baz', 'qux'])
def foo():
"""Run a command."""
click.echo('foo')
cli() Output:
Oh no! Even if rich-click does not bake in its own aliases functionality (I'm not against it), we definitely should be trying our best to support it in the context of it being inherited! It is possible that the lack of support for Overall, there is a lot to think about here. |
that's quite a bit of gymnastics to get all the extensions implemented to play nicely with each other. I think the responsibility of managing these things is on click itself to implement something like pluggy instead of having to deal with subclass hackery which might change with any of the associated packages changes to their APIs. |
… until ewels/rich-click#101 has more information.
Would be great to have 1) a new option or 2) an option inside the
click.rich_click.COMMAND_GROUPS
dict to give commands aliases.Right now I can use click-aliases with rich-click to do this but requires me to make my own command class:
Problem is that the aliases work but do not show in the docs and breaks the formatting of the individual command help. It's far from ideal but id like the best of both worlds. Would be great and i think reasonably straightforward to incorporate this into rich-click
The text was updated successfully, but these errors were encountered: