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

1# SPDX-License-Identifier: MIT 

2# Copyright © 2025 Bijan Mousavi 

3 

4"""Implements the `plugins list` subcommand for the Bijux CLI. 

5 

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. 

10 

11Output Contract: 

12 * Success: `{"plugins": [str, ...]}` 

13 * Verbose: Adds `{"python": str, "platform": str}` to the payload. 

14 * Error: `{"error": str, "code": int}` 

15 

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""" 

23 

24from __future__ import annotations 

25 

26import typer 

27 

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 

38 

39 

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. 

48 

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. 

53 

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. 

60 

61 Returns: 

62 None: 

63 

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" 

69 

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)