Skip to content

nested_commands

wrknv.cli.nested_commands

Enhanced command registration with nested group support.

This module extends the Foundation Hub to support nested command groups, allowing natural CLI structures like wrknv container status instead of wrknv container-status.

Classes

CommandGroup dataclass

CommandGroup(
    name: str,
    description: str | None = None,
    commands: dict[
        str, CommandInfo | CommandGroup
    ] = dict(),
    parent: CommandGroup | None = None,
    hidden: bool = False,
)

Represents a command group that can contain subcommands.

Functions
add_command
add_command(
    name: str, info: CommandInfo | CommandGroup
) -> None

Add a subcommand to this group.

Source code in wrknv/cli/nested_commands.py
def add_command(self, name: str, info: CommandInfo | CommandGroup) -> None:
    """Add a subcommand to this group."""
    self.commands[name] = info
    if isinstance(info, CommandGroup):
        info.parent = self
get_command
get_command(
    path: list[str],
) -> CommandInfo | CommandGroup | None

Get a command by path (e.g., ['container', 'status']).

Source code in wrknv/cli/nested_commands.py
def get_command(self, path: list[str]) -> CommandInfo | CommandGroup | None:
    """Get a command by path (e.g., ['container', 'status'])."""
    if not path:
        return self

    name = path[0]
    if name not in self.commands:
        return None

    cmd = self.commands[name]
    if len(path) == 1:
        return cmd

    if isinstance(cmd, CommandGroup):
        return cmd.get_command(path[1:])

    return None
to_click_group
to_click_group() -> click.Group

Convert this command group to a Click group.

Source code in wrknv/cli/nested_commands.py
def to_click_group(self) -> click.Group:
    """Convert this command group to a Click group."""
    group = click.Group(
        name=self.name,
        help=self.description,
        hidden=self.hidden,
    )

    for _cmd_name, cmd_info in self.commands.items():
        if isinstance(cmd_info, CommandGroup):
            # Add subgroup
            subgroup = cmd_info.to_click_group()
            group.add_command(subgroup)
        else:
            # Add command
            click_cmd = self._build_click_command(cmd_info)
            if click_cmd:
                group.add_command(click_cmd)

    return group

NestedCommandRegistry

NestedCommandRegistry()

Registry that supports nested command groups.

Source code in wrknv/cli/nested_commands.py
def __init__(self) -> None:
    self.root = CommandGroup(name="cli", description="CLI root")
    self._flat_registry: dict[str, CommandInfo | CommandGroup] = {}
Functions
get_command
get_command(name: str) -> CommandInfo | CommandGroup | None

Get a command by name (space-separated path).

Source code in wrknv/cli/nested_commands.py
def get_command(self, name: str) -> CommandInfo | CommandGroup | None:
    """Get a command by name (space-separated path)."""
    return self._flat_registry.get(name)
register_command
register_command(
    name: str,
    func: Callable[..., Any] | None = None,
    description: str | None = None,
    group: bool = False,
    parent: str | None = None,
    hidden: bool = False,
    aliases: list[str] | None = None,
) -> None

Register a command or command group.

Parameters:

Name Type Description Default
name str

Command name (can include spaces for nested commands)

required
func Callable[..., Any] | None

Function to execute (None for groups)

None
description str | None

Command/group description

None
group bool

Whether this is a command group

False
parent str | None

Parent group name (alternative to space-separated name)

None
hidden bool

Whether to hide from help

False
aliases list[str] | None

Command aliases

None
Source code in wrknv/cli/nested_commands.py
def register_command(
    self,
    name: str,
    func: Callable[..., Any] | None = None,
    description: str | None = None,
    group: bool = False,
    parent: str | None = None,
    hidden: bool = False,
    aliases: list[str] | None = None,
) -> None:
    """
    Register a command or command group.

    Args:
        name: Command name (can include spaces for nested commands)
        func: Function to execute (None for groups)
        description: Command/group description
        group: Whether this is a command group
        parent: Parent group name (alternative to space-separated name)
        hidden: Whether to hide from help
        aliases: Command aliases
    """
    # Parse the command path
    path = [*parent.split(), name] if parent else name.split()

    # Get or create parent groups
    current = self.root
    for i, part in enumerate(path[:-1]):
        if part not in current.commands:
            # Create intermediate group
            intermediate = CommandGroup(
                name=part,
                description=f"{part} commands",
            )
            current.add_command(part, intermediate)
            logger.debug(f"Created intermediate group: {part}")

        cmd = current.commands[part]
        if isinstance(cmd, CommandGroup):
            current = cmd
        else:
            raise ValueError(f"Cannot nest under non-group command: {' '.join(path[: i + 1])}")

    # Register the final command or group
    final_name = path[-1]

    if group or func is None:
        # Register as a group
        cmd_group = CommandGroup(
            name=final_name,
            description=description or f"{final_name} commands",
            hidden=hidden,
        )
        current.add_command(final_name, cmd_group)
        self._flat_registry[" ".join(path)] = cmd_group
        logger.info(f"Registered command group: {' '.join(path)}")
    else:
        # Register as a command
        info = CommandInfo(
            name=final_name,
            func=func,
            description=description or (func.__doc__ if func else None),
            aliases=aliases or [],
            hidden=hidden,
            category=" ".join(path[:-1]) if len(path) > 1 else None,
        )
        current.add_command(final_name, info)
        self._flat_registry[" ".join(path)] = info
        logger.info(f"Registered command: {' '.join(path)}")
to_click_group
to_click_group() -> click.Group

Convert the entire registry to a Click group.

Source code in wrknv/cli/nested_commands.py
def to_click_group(self) -> click.Group:
    """Convert the entire registry to a Click group."""
    return self.root.to_click_group()

Functions

create_nested_cli

create_nested_cli(
    name: str = "wrknv",
    version: str = "0.1.0",
    help: str | None = None,
) -> click.Group

Create a CLI with nested command groups.

Parameters:

Name Type Description Default
name str

CLI name

'wrknv'
version str

CLI version

'0.1.0'
help str | None

CLI help text

None

Returns:

Type Description
Group

Click Group with nested commands

Source code in wrknv/cli/nested_commands.py
def create_nested_cli(
    name: str = "wrknv",
    version: str = "0.1.0",
    help: str | None = None,
) -> click.Group:
    """
    Create a CLI with nested command groups.

    Args:
        name: CLI name
        version: CLI version
        help: CLI help text

    Returns:
        Click Group with nested commands
    """
    cli = _nested_registry.root.to_click_group()
    cli.name = name

    if help:
        cli.help = help

    # Add version option
    @cli.command(hidden=True)
    @click.option("--version", is_flag=True, help="Show version")
    def version_cmd(version: bool) -> None:
        if version:
            click.echo(f"{name} {version}")

    return cli

get_nested_registry

get_nested_registry() -> NestedCommandRegistry

Get the global nested command registry.

Source code in wrknv/cli/nested_commands.py
def get_nested_registry() -> NestedCommandRegistry:
    """Get the global nested command registry."""
    return _nested_registry

register_nested_command

register_nested_command(
    name: str,
    *,
    description: str | None = None,
    group: bool = False,
    parent: str | None = None,
    hidden: bool = False,
    aliases: list[str] | None = None
) -> Callable[[F], F]

Register a command with support for nested groups.

Examples:

Register a simple command

@register_nested_command("status") def status(): pass

Register a command group

@register_nested_command("container", group=True) def container_group(): pass

Register a subcommand (two ways)

@register_nested_command("container status") def container_status(): pass

Or using parent parameter

@register_nested_command("status", parent="container") def container_status(): pass

Parameters:

Name Type Description Default
name str

Command name (can be space-separated for nesting)

required
description str | None

Command description

None
group bool

Whether this is a command group

False
parent str | None

Parent group (alternative to space-separated name)

None
hidden bool

Hide from help

False
aliases list[str] | None

Command aliases

None

Returns:

Type Description
Callable[[F], F]

Decorator function

Source code in wrknv/cli/nested_commands.py
def register_nested_command(
    name: str,
    *,
    description: str | None = None,
    group: bool = False,
    parent: str | None = None,
    hidden: bool = False,
    aliases: list[str] | None = None,
) -> Callable[[F], F]:
    """
    Register a command with support for nested groups.

    Examples:
        # Register a simple command
        @register_nested_command("status")
        def status():
            pass

        # Register a command group
        @register_nested_command("container", group=True)
        def container_group():
            pass

        # Register a subcommand (two ways)
        @register_nested_command("container status")
        def container_status():
            pass

        # Or using parent parameter
        @register_nested_command("status", parent="container")
        def container_status():
            pass

    Args:
        name: Command name (can be space-separated for nesting)
        description: Command description
        group: Whether this is a command group
        parent: Parent group (alternative to space-separated name)
        hidden: Hide from help
        aliases: Command aliases

    Returns:
        Decorator function
    """

    def decorator(func: F) -> F:
        _nested_registry.register_command(
            name=name,
            func=func if not group else None,
            description=description,
            group=group,
            parent=parent,
            hidden=hidden,
            aliases=aliases,
        )

        # Also register in the Foundation Hub for compatibility
        hub = get_hub()
        full_name = f"{parent} {name}" if parent else name
        flat_name = full_name.replace(" ", "-")

        hub.register(
            name=flat_name,
            value=func,
            dimension="command",
            metadata={
                "nested_path": full_name,
                "is_group": group,
                "description": description,
                "hidden": hidden,
                "aliases": aliases,
            },
        )

        return func

    return decorator