4

Is it possible to do something like this with Python Click? I want to use different names for the same click.Group.

import click class CustomMultiGroup(click.Group): def group(self, *args, **kwargs): """Behaves the same as `click.Group.group()` except if passed a list of names, all after the first will be aliases for the first. """ def decorator(f): if isinstance(args[0], list): _args = [args[0][0]] + list(args[1:]) for alias in args[0][1:]: cmd = super(CustomMultiCommand, self).group( alias, *args[1:], **kwargs)(f) cmd.short_help = "Alias for '{}'".format(_args[0]) else: _args = args cmd = super(CustomMultiCommand, self).group( *_args, **kwargs)(f) return cmd return decorator @click.group(cls=CustomMultiGroup) def mycli(): pass @cli.group(['my-group', 'my-grp']) def my_group(): pass @my_group.command() def my_command(): pass 

I want my command lines to be something like:

mycli my-group my-command 

and

mycli my-grp my-command 

but reference the same function.

This post is a reference to Python Click multiple command names

6
  • Click has the concept of alises? Commented Oct 16, 2017 at 8:19
  • 1
    Take a look at Command Aliases Commented Oct 16, 2017 at 8:25
  • It's more something like this stackoverflow.com/questions/46641928/… Commented Oct 16, 2017 at 12:10
  • The group itself is not addressed from the command line. You would generally only address a group if it was itself inside of a group. So for your first line to be useful it would need to be a member of another group. So it would not be @click.group() it would need to be @my_outer_group.group(), where my_outer_group was a previously declared group. Can you confirm this is the case? Commented Oct 16, 2017 at 14:43
  • It's not the case but it can be. I'll test it soon Commented Oct 16, 2017 at 15:15

2 Answers 2

2

click.Group and click.Command behave differently so you need to modify the example to allow the aliasing group to access the aliased group's commands:

Custom Class

This class overides the click.Group.group() method which is used to decorate group functions. It adds the ability to pass a list of group aliases. This class also adds a short help which references the aliased group.

import click class CustomMultiGroup(click.Group): def group(self, *args, **kwargs): """Behaves the same as `click.Group.group()` except if passed a list of names, all after the first will be aliases for the first. """ def decorator(f): aliased_group = [] if isinstance(args[0], list): # we have a list so create group aliases _args = [args[0][0]] + list(args[1:]) for alias in args[0][1:]: grp = super(CustomMultiGroup, self).group( alias, *args[1:], **kwargs)(f) grp.short_help = "Alias for '{}'".format(_args[0]) aliased_group.append(grp) else: _args = args # create the main group grp = super(CustomMultiGroup, self).group(*_args, **kwargs)(f) # for all of the aliased groups, share the main group commands for aliased in aliased_group: aliased.commands = grp.commands return grp return decorator 

Test Code:

@click.group(cls=CustomMultiGroup) def cli(): pass @cli.group(['my-group', 'my-grp']) def my_group(): """ My Sub Command """ pass @my_group.command('my-command') def my_command(): click.echo("My Command") cli('--help'.split()) cli('my-grp --help'.split()) cli('my-group --help'.split()) cli('my-grp my-command'.split()) cli('my-group my-command'.split()) 

Test Results:

Usage: my_cli [OPTIONS] COMMAND [ARGS]... Options: --help Show this message and exit. Commands: my-group My Sub Command my-grp Alias for 'my-group' Process finished with exit code 0 
Sign up to request clarification or add additional context in comments.

Comments

2

The easiest way to have command aliases in Click is using one of the following packages:

Disclaimer: I'm the author of Cloup.

The two implementations are slightly different.

  • Cloup stores aliases of a command in the command itself. This allows Cloup to document aliases of a command (also) in the --help of the command itself.

  • click-aliases always shows aliases of (sub)commands in the "Commands" section of a group. In Cloup, you can enable/disable this behavior according to your preference (by default, aliases are not shown).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.