Coverage for /home/runner/work/bijux-cli/bijux-cli/src/bijux_cli/commands/plugins/list.py: 100%
12 statements
« prev ^ index » next coverage.py v7.10.4, created at 2025-08-19 23:36 +0000
« prev ^ index » next coverage.py v7.10.4, created at 2025-08-19 23:36 +0000
1# SPDX-License-Identifier: MIT
2# Copyright © 2025 Bijan Mousavi
4"""Implements the `plugins list` subcommand for the Bijux CLI.
6This module provides the primary command for listing all installed CLI plugins.
7It performs security checks on the plugins directory and then delegates its
8core logic to the shared `handle_list_plugins` utility, which scans the
9filesystem and returns a structured list.
11Output Contract:
12 * Success: `{"plugins": [str, ...]}`
13 * Verbose: Adds `{"python": str, "platform": str}` to the payload.
14 * Error: `{"error": str, "code": int}`
16Exit Codes:
17 * `0`: Success.
18 * `1`: An error occurred while accessing the plugins directory (e.g.,
19 it is a symlink or inaccessible).
20 * `2`: An invalid flag was provided (e.g., bad format).
21 * `3`: An ASCII or encoding error was detected in the environment.
22"""
24from __future__ import annotations
26import typer
28from bijux_cli.commands.plugins.utils import refuse_on_symlink
29from bijux_cli.commands.utilities import handle_list_plugins, validate_common_flags
30from bijux_cli.core.constants import (
31 HELP_DEBUG,
32 HELP_FORMAT,
33 HELP_NO_PRETTY,
34 HELP_QUIET,
35 HELP_VERBOSE,
36)
37from bijux_cli.services.plugins import get_plugins_dir
40def list_plugin(
41 quiet: bool = typer.Option(False, "-q", "--quiet", help=HELP_QUIET),
42 verbose: bool = typer.Option(False, "-v", "--verbose", help=HELP_VERBOSE),
43 fmt: str = typer.Option("json", "-f", "--format", help=HELP_FORMAT),
44 pretty: bool = typer.Option(True, "--pretty/--no-pretty", help=HELP_NO_PRETTY),
45 debug: bool = typer.Option(False, "-d", "--debug", help=HELP_DEBUG),
46) -> None:
47 """Lists all installed CLI plugins.
49 This command first performs security checks on the plugins directory, such
50 as ensuring it is not a symbolic link. It then delegates to the shared
51 `handle_list_plugins` utility to perform the filesystem scan and emit the
52 structured output.
54 Args:
55 quiet (bool): If True, suppresses all output except for errors.
56 verbose (bool): If True, includes Python/platform details in the output.
57 fmt (str): The output format, "json" or "yaml".
58 pretty (bool): If True, pretty-prints the output.
59 debug (bool): If True, enables debug diagnostics.
61 Returns:
62 None:
64 Raises:
65 SystemExit: Always exits with a contract-compliant status code and
66 payload, indicating success or detailing an error.
67 """
68 command = "plugins list"
70 fmt_lower = validate_common_flags(fmt, command, quiet)
71 plugins_dir = get_plugins_dir()
72 refuse_on_symlink(plugins_dir, command, fmt_lower, quiet, verbose, debug)
73 handle_list_plugins(command, quiet, verbose, fmt, pretty, debug)