Если вы наследуете от click.Group
, вы можете добавить немного кода для группировки команд и затем показать эти группы в справке.
Пользовательский класс
class GroupedGroup(click.Group):
def command(self, *args, **kwargs):
"""Gather the command help groups"""
help_group = kwargs.pop('group', None)
decorator = super(GroupedGroup, self).command(*args, **kwargs)
def wrapper(f):
cmd = decorator(f)
cmd.help_group = help_group
return cmd
return wrapper
def format_commands(self, ctx, formatter):
# Modified fom the base class method
commands = []
for subcommand in self.list_commands(ctx):
cmd = self.get_command(ctx, subcommand)
if not (cmd is None or cmd.hidden):
commands.append((subcommand, cmd))
if commands:
longest = max(len(cmd[0]) for cmd in commands)
# allow for 3 times the default spacing
limit = formatter.width - 6 - longest
groups = {}
for subcommand, cmd in commands:
help_str = cmd.get_short_help_str(limit)
subcommand += ' ' * (longest - len(subcommand))
groups.setdefault(
cmd.help_group, []).append((subcommand, help_str))
with formatter.section('Commands'):
for group_name, rows in groups.items():
with formatter.section(group_name):
formatter.write_dl(rows)
Использование пользовательскогоКласс
Чтобы использовать пользовательский класс, используйте параметр cls
для передачи класса в декоратор click.group()
.
@click.group(cls=GroupedGroup)
def cli():
"""My awesome cli"""
Затем для каждой команды отметьте группу помощи длякоманда, которая будет включена как:
@cli.command(group='A Help Group')
def command():
"""This is a command"""
Как это работает?
Это работает, потому что click - это хорошо спроектированная OO-инфраструктура. Декоратор @click.group()
обычно создает экземпляр объекта click.Group
, но позволяет изменить это поведение с помощью параметра cls
. Так что относительно просто унаследовать от click.Group
в нашем собственном классе и переопределить нужные методы.
В этом случае мы переопределим декоратор click.Group.command()
, чтобы собрать нужную группу помощи для каждой команды. Затем мы переопределяем метод click.Group.format_commands()
, чтобы использовать эти группы при построении справки.
Код теста
import click
@click.group(cls=GroupedGroup)
def cli():
"""My awesome cli"""
@cli.command(group='Generators')
def some_generator():
"""This is Some Generator"""
@cli.command(group='Generators')
def another_generator():
"""This is Another Generator"""
@cli.command(group='Filters')
def some_filter():
"""This is Some Filter"""
@cli.command(group='Filters')
def another_filter():
"""This is Another Filter"""
cli()
Результаты
Usage: test.py [OPTIONS] COMMAND [ARGS]...
My awesome cli
Options:
--help Show this message and exit.
Commands:
Filters:
another-filter This is Another Filter
some-filter This is Some Filter
Generators:
another-generator This is Another Generator
some-generator This is Some Generator