Skip to content

Commit c514ca6

Browse files
committed
Added group and command decorators with their classes
1 parent 367a67d commit c514ca6

File tree

5 files changed

+159
-0
lines changed

5 files changed

+159
-0
lines changed

click_with_alias/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
""" This module is the entry point for the package. """
2+
3+
from .command import command
4+
from .group import group
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
""" AliasedCommand class for Click commands with alias support. """
2+
3+
import click
4+
5+
6+
class AliasedCommand(click.Command):
7+
"""A Click command that supports aliasing."""
8+
9+
def __init__(self, *args, **kwargs):
10+
self.aliases = kwargs.pop("aliases", [])
11+
super().__init__(*args, **kwargs)

click_with_alias/_aliased_group.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
""" AliasedGroup class for click_with_alias. """
2+
3+
import click
4+
5+
6+
class AliasedGroup(click.Group):
7+
"""A Click group that supports aliasing."""
8+
9+
def add_command(self, cmd: click.Command, name=None) -> None:
10+
"""
11+
Add a command to the group.
12+
13+
Args:
14+
cmd: click.Command - The command to add.
15+
name: str - The name of the command.
16+
Returns:
17+
None
18+
Raises:
19+
ValueError: If the command name is already taken.
20+
"""
21+
aliases = getattr(cmd, "aliases", [])
22+
super().add_command(cmd, name)
23+
for alias in aliases:
24+
super().add_command(cmd, alias)
25+
26+
def format_commands(
27+
self, ctx: click.Context, formatter: click.HelpFormatter
28+
) -> None:
29+
"""
30+
Format the commands for the group.
31+
32+
Args:
33+
ctx: click.Context - The click context.
34+
formatter: click.HelpFormatter - The help formatter.
35+
Returns:
36+
None
37+
Raises:
38+
None
39+
"""
40+
commands = {}
41+
for name, cmd in self.commands.items():
42+
if name == cmd.name:
43+
aliases = getattr(cmd, "aliases", [])
44+
if aliases:
45+
name = f"{name} ({', '.join(aliases)})"
46+
commands[name] = cmd
47+
48+
rows = [
49+
(name, cmd.get_short_help_str()) for name, cmd in commands.items()
50+
]
51+
52+
if rows:
53+
with formatter.section("Commands"):
54+
formatter.write_dl(rows)

click_with_alias/command.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
""" The command decorator with alias support. """
2+
3+
from typing import Callable
4+
5+
import click
6+
7+
from ._aliased_command import AliasedCommand
8+
9+
10+
def command(
11+
name: str, *args, aliases: list[str] = None, **kwargs
12+
) -> click.Command:
13+
"""
14+
The command decorator with aliasing support which replaces the default Click command decorator.
15+
16+
Usage:
17+
@command(name="my_command)
18+
19+
@command(name="my_command), aliases=["mc])
20+
Args:
21+
name: str - The name of the command.
22+
aliases: list[str] - The list of aliases for the command.
23+
*args: Any - Additional arguments.
24+
**kwargs: Any - Additional keyword arguments.
25+
Returns:
26+
click.Command - The Click command decorator.
27+
Raises:
28+
None
29+
"""
30+
31+
command_decorator = click.command(
32+
name=name, cls=AliasedCommand, *args, **kwargs
33+
)
34+
35+
def decorator(fn: Callable) -> click.Command:
36+
"""
37+
Decorator for creating a command.
38+
39+
Args:
40+
fn: Callable - The function to decorate.
41+
Returns:
42+
click.Command - The Click command.
43+
Raises:
44+
None
45+
"""
46+
cmd = command_decorator(fn)
47+
cmd.aliases = aliases or []
48+
return cmd
49+
50+
return decorator

click_with_alias/group.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
""" The group decorator with alias support. """
2+
3+
import click
4+
5+
from ._aliased_group import AliasedGroup
6+
7+
8+
def group(
9+
*args, name: str = None, aliases: list[str] = None, **kwargs
10+
) -> click.Group:
11+
"""
12+
The group decorator with aliasing support
13+
which replaces the default Click group decorator.
14+
15+
Usage:
16+
@group(name="my_group)
17+
18+
@group(name="my_group", aliases=["mg"])
19+
Args:
20+
name: str - The name of the group.
21+
aliases: list[str] - The list of aliases for the group.
22+
*args: Any - Additional arguments.
23+
**kwargs: Any - Additional keyword arguments.
24+
Returns:
25+
click.Group - The Click group decorator.
26+
Raises:
27+
None
28+
"""
29+
30+
def decorator(func) -> click.Group:
31+
"""Decorator for creating a group."""
32+
inferred_name = name or func.__name__
33+
group_decorator = click.group(
34+
name=inferred_name, cls=AliasedGroup, *args, **kwargs
35+
)
36+
cmd = group_decorator(func)
37+
cmd.aliases = aliases or []
38+
return cmd
39+
40+
return decorator

0 commit comments

Comments
 (0)