如何在单击链接组中对命令列表显示进行分类?
How can command list display be categorised within a Click chained group?
我正在启动一个 CLI 管道类型的应用程序项目,该项目最终将拥有相当大的命令集合(将通过插件进一步扩展)。因此,我想将它们分类在 --help
文本中:
这是现在的样子:
Usage: my_pipe [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Options:
--help Show this message and exit.
Commands:
another_filter help about that filter
another_generator help about that generator
another_sink help about that sink
some_filter help about this filter
some_generator help about this generator
some_sink help about this sink
这或多或少是我希望的样子:
Usage: my_pipe [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Options:
--help Show this message and exit.
Commands:
Generators:
some_generator help about this generator
another_generator help about that generator
Filters:
some_filter help about this filter
another_filter help about that filter
Sinks:
some_sink help about this sink
another_sink help about that sink
如何实现?请注意,除了 --help
的外观外,我对扁平的逻辑命令组织感到满意。此外,子组不是一个选项,因为它们不允许在 chain=True
组内。
如果您继承自 click.Group
,您可以添加一些代码来对命令进行分组,然后在帮助中显示这些分组。
自定义Class
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)
使用自定义 Class
要使用自定义 class,请使用 cls
参数将 class 传递给 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
参数覆盖此行为。所以在我们自己的class中继承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
我正在启动一个 CLI 管道类型的应用程序项目,该项目最终将拥有相当大的命令集合(将通过插件进一步扩展)。因此,我想将它们分类在 --help
文本中:
这是现在的样子:
Usage: my_pipe [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Options:
--help Show this message and exit.
Commands:
another_filter help about that filter
another_generator help about that generator
another_sink help about that sink
some_filter help about this filter
some_generator help about this generator
some_sink help about this sink
这或多或少是我希望的样子:
Usage: my_pipe [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Options:
--help Show this message and exit.
Commands:
Generators:
some_generator help about this generator
another_generator help about that generator
Filters:
some_filter help about this filter
another_filter help about that filter
Sinks:
some_sink help about this sink
another_sink help about that sink
如何实现?请注意,除了 --help
的外观外,我对扁平的逻辑命令组织感到满意。此外,子组不是一个选项,因为它们不允许在 chain=True
组内。
如果您继承自 click.Group
,您可以添加一些代码来对命令进行分组,然后在帮助中显示这些分组。
自定义Class
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)
使用自定义 Class
要使用自定义 class,请使用 cls
参数将 class 传递给 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
参数覆盖此行为。所以在我们自己的class中继承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