eeprom-programmer/client/helpers/click.py

70 lines
2.5 KiB
Python

import click
import collections
class CategorizedGroup(click.Group):
"""
Click command group that categorizes subcommands in the help text by the additional 'category' attribute.
Commands that don't have a 'category' attribute are grouped under the default category "Commands" as usual.
Example usage:
`@categorized_group.command('foobar', category='Debug commands')`
"""
default_category: str
def __init__(self, name=None, commands=None, default_category: str = 'Commands', **attrs):
super().__init__(name, commands, **attrs)
self.commands = commands or collections.OrderedDict()
self.default_category = default_category
def list_commands(self, ctx):
""" List commands in the order they were added to the group. """
return self.commands
def command(self, *args, **kwargs):
""" Extends the command decorator by setting a category attribute on the command. """
category = kwargs.pop('category', None)
orig_decorator = super().command(*args, **kwargs)
def decorator(f):
cmd = orig_decorator(f)
if category:
cmd.category = category
return cmd
return decorator
def format_commands(self, ctx, formatter):
"""
Prints commands in help messages.
This version groups them into categories and is based on the original Group.format_commands method.
"""
categorized_commands = {self.default_category: []}
# Collect subcommands grouped by category
for subcommand in self.list_commands(ctx):
cmd = self.get_command(ctx, subcommand)
if cmd is None or cmd.hidden:
continue
category = getattr(cmd, 'category', self.default_category)
if categorized_commands.get(category) is None:
categorized_commands[category] = []
categorized_commands[category].append((subcommand, cmd))
# Print help sections for each subcommand category
for category, subcommands in categorized_commands.items():
if not len(subcommands):
continue
limit = formatter.width - 6 - max(len(cmd[0]) for cmd in subcommands)
rows = []
for subcommand, cmd in subcommands:
help_str = cmd.get_short_help_str(limit)
rows.append((subcommand, help_str))
with formatter.section(category):
formatter.write_dl(rows)