Coverage for src/mafw/devtools/cli/toolchain/verify_cmd.py: 100%
36 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-26 09:13 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-26 09:13 +0000
1# Copyright 2026 European Union
2# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
3# SPDX-License-Identifier: EUPL-1.2
4"""
5Verify subcommand for the toolchain command group.
7This module implements the ``devtools toolchain verify`` command, which
8iterates over all applicable tools with a Rich progress spinner, calls each
9tool's :meth:`~mafw.devtools.toolchain.base.ToolChainTool.verify` method, and
10reports any configuration inconsistencies found. Exceptions during verification
11are treated as implicit issues. The exit code reflects whether any issues were
12detected (exit 1) or all tools are consistent (exit 0).
13"""
15from __future__ import annotations
17import sys
19import click
20from rich.console import Console
21from rich.progress import MofNCompleteColumn, Progress, SpinnerColumn, TextColumn
23from mafw.devtools.cli.toolchain._group import common_options, toolchain
24from mafw.devtools.toolchain.base import Issue
25from mafw.devtools.toolchain.filtering import resolve_tools
28@toolchain.command(name='verify')
29@common_options
30@click.pass_context
31def verify(ctx: click.Context, include: tuple[str, ...], exclude: tuple[str, ...]) -> None:
32 """Verify configuration consistency of all applicable tools.
34 Iterates over the filtered tool set with a progress spinner, calling each
35 tool's ``verify()`` method. Issues are printed prefixed with the tool name.
36 Exceptions during verification are reported as errors and count towards a
37 non-zero exit code.
38 """
39 registry = ctx.obj['registry']
40 include_host: bool = ctx.obj['include_host']
41 console = Console()
43 tools = resolve_tools(registry, include=include, exclude=exclude, include_host=include_host)
45 # Collect all issues across tools.
46 all_issues: list[Issue] = []
47 had_exception = False
49 # Iterate tools with a Rich progress spinner for visual feedback.
50 with Progress(
51 SpinnerColumn(),
52 TextColumn('[progress.description]{task.description}'),
53 MofNCompleteColumn(),
54 console=console,
55 transient=True,
56 ) as progress:
57 task = progress.add_task('Verifying tools', total=len(tools))
59 for idx, tool in enumerate(tools, start=1):
60 progress.update(task, description=f'Processing tool {idx}/{len(tools)}: {tool.name}')
62 try:
63 issues = tool.verify()
64 except Exception as exc: # noqa: BLE001
65 # Treat exceptions during verify() as implicit issues.
66 had_exception = True
67 console.print(
68 f'[bold red]{tool.name}[/bold red]: error during verification — {exc}',
69 style='red',
70 )
71 progress.advance(task)
72 continue
74 # Accumulate issues and print each one.
75 for issue in issues:
76 all_issues.append(issue)
77 console.print(f'[bold]{issue.tool_name}[/bold]: {issue.description}')
79 progress.advance(task)
81 # Determine exit code and print summary.
82 if all_issues or had_exception:
83 sys.exit(1)
84 else:
85 console.print('[bold green]All tools verified — no configuration issues found.[/bold green]')