Coverage for  / home / runner / work / bijux-cli / bijux-cli / src / bijux_cli / cli / commands / dev / list_plugins.py: 95%

19 statements  

« prev     ^ index     » next       coverage.py v7.13.2, created at 2026-01-26 17:59 +0000

1# SPDX-License-Identifier: Apache-2.0 

2# Copyright © 2025 Bijan Mousavi 

3 

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

5 

6This module provides a developer-focused command to list all installed CLI 

7plugins. It delegates its core logic to the shared `handle_list_plugins` 

8utility, which scans the filesystem and returns a structured list. 

9 

10Output Contract: 

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

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

13 

14Exit Codes: 

15 * `0`: Success. 

16 * `1`: An error occurred while accessing the plugins directory. 

17 * `2`: An invalid flag was provided (e.g., bad format). 

18 * `3`: An ASCII or encoding error was detected in the environment. 

19""" 

20 

21from __future__ import annotations 

22 

23import platform 

24 

25import typer 

26 

27from bijux_cli.cli.core.command import new_run_command, validate_common_flags 

28from bijux_cli.cli.core.constants import ( 

29 OPT_FORMAT, 

30 OPT_LOG_LEVEL, 

31 OPT_PRETTY, 

32 OPT_QUIET, 

33) 

34from bijux_cli.cli.core.help_text import ( 

35 HELP_FORMAT, 

36 HELP_LOG_LEVEL, 

37 HELP_NO_PRETTY, 

38 HELP_QUIET, 

39) 

40from bijux_cli.core.precedence import current_execution_policy 

41from bijux_cli.plugins.catalog import list_installed_plugins 

42 

43 

44def dev_list_plugins( 

45 quiet: bool = typer.Option(False, *OPT_QUIET, help=HELP_QUIET), 

46 fmt: str = typer.Option("json", *OPT_FORMAT, help=HELP_FORMAT), 

47 pretty: bool = typer.Option(True, OPT_PRETTY, help=HELP_NO_PRETTY), 

48 log_level: str = typer.Option("info", *OPT_LOG_LEVEL, help=HELP_LOG_LEVEL), 

49) -> None: 

50 """Lists all installed CLI plugins. 

51 

52 This command acts as a wrapper around the shared `handle_list_plugins` 

53 utility to provide a consistent interface for developers. 

54 

55 Args: 

56 quiet (bool): If True, suppresses all output except for errors. 

57 fmt (str): The output format, "json" or "yaml". 

58 pretty (bool): If True, pretty-prints the output. 

59 log_level (str): The requested logging level. 

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 = "dev list-plugins" 

69 

70 effective = current_execution_policy() 

71 validate_common_flags( 

72 fmt, 

73 command, 

74 effective.quiet, 

75 include_runtime=effective.include_runtime, 

76 log_level=effective.log_level, 

77 ) 

78 plugins = list_installed_plugins() 

79 

80 def payload_builder(include_runtime: bool) -> dict[str, object]: 

81 """Build the list-plugins payload with optional runtime metadata.""" 

82 payload: dict[str, object] = {"plugins": plugins} 

83 if include_runtime: 83 ↛ 90line 83 didn't jump to line 90 because the condition on line 83 was always true

84 payload.update( 

85 { 

86 "python": platform.python_version(), 

87 "platform": platform.platform(), 

88 } 

89 ) 

90 return payload 

91 

92 new_run_command( 

93 command_name=command, 

94 payload_builder=payload_builder, 

95 quiet=effective.quiet, 

96 fmt=effective.output_format, 

97 pretty=effective.pretty, 

98 log_level=effective.log_level, 

99 )