Source code for mafw.devtools.cli.toolchain._group

#  Copyright 2026 European Union
#  Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
#  SPDX-License-Identifier: EUPL-1.2
"""
Toolchain Click group and shared decorator definitions.

This module is separated from ``__init__.py`` to avoid circular imports:
subcommand modules import the ``toolchain`` group and ``common_options``
from here, while ``__init__.py`` imports subcommand modules to trigger
their registration.
"""

from __future__ import annotations

import functools
from typing import Any

import click

from mafw.devtools.toolchain.default_registry import get_default_registry
from mafw.tools.click_extensions import AbbreviateGroup

CONTEXT_SETTINGS = {'help_option_names': ['-h', '--help']}
"""Click context settings for command line help aliases."""


@click.group(
    cls=AbbreviateGroup,
    context_settings=CONTEXT_SETTINGS,
    help='Toolchain management commands.',
)
@click.option(
    '--include-host',
    is_flag=True,
    default=False,
    help='Include host-category tools (pipx-managed) in subcommand processing.',
)
@click.option(
    '--exclude-host',
    is_flag=True,
    default=False,
    help='Exclude host-category tools from subcommand processing (default behaviour).',
)
@click.pass_context
def toolchain(ctx: click.Context, include_host: bool, exclude_host: bool) -> None:
    """Manage development toolchain tools."""
    if include_host and exclude_host:
        raise click.UsageError('--include-host and --exclude-host are mutually exclusive.')
    ctx.ensure_object(dict)
    # Default behaviour (neither flag) is to exclude host tools.
    ctx.obj['include_host'] = include_host
    ctx.obj['registry'] = get_default_registry()


[docs] def common_options(fn: Any) -> Any: """Shared decorator applying ``-i``/``--include`` and ``-e``/``--exclude`` options. These repeatable options allow subcommands to filter which tools are processed by name. They are mutually exclusive: specifying both in the same invocation triggers a :class:`~click.UsageError` at filtering time (enforced by :func:`~mafw.devtools.toolchain.filtering.resolve_tools`). The decorated function receives ``include`` and ``exclude`` keyword arguments as tuples of tool-name strings. """ @click.option( '-i', '--include', multiple=True, type=click.STRING, help='Process only the named tool(s). Repeatable.', ) @click.option( '-e', '--exclude', multiple=True, type=click.STRING, help='Skip the named tool(s). Repeatable.', ) @functools.wraps(fn) def wrapper(*args: Any, **kwargs: Any) -> Any: return fn(*args, **kwargs) return wrapper