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

25 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 root callback for the `bijux dev` command group. 

5 

6This module defines the default action for the `bijux dev` command. This command 

7group is intended for developers of the CLI. When invoked without a subcommand, 

8it provides a simple status confirmation. 

9 

10Output Contract: 

11 * Success: `{"status": "ok"}` 

12 * With Env Var: Adds `{"mode": str}` if `BIJUXCLI_DEV_MODE` is set. 

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 internal or unexpected error occurred. 

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

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

21""" 

22 

23from __future__ import annotations 

24 

25from collections.abc import Mapping 

26import os 

27import platform 

28from typing import Any 

29 

30import typer 

31 

32from bijux_cli.commands.utilities import ( 

33 ascii_safe, 

34 new_run_command, 

35 validate_common_flags, 

36) 

37from bijux_cli.core.constants import ( 

38 HELP_DEBUG, 

39 HELP_FORMAT, 

40 HELP_NO_PRETTY, 

41 HELP_QUIET, 

42 HELP_VERBOSE, 

43) 

44 

45 

46def dev( 

47 ctx: typer.Context, 

48 quiet: bool = typer.Option(False, "-q", "--quiet", help=HELP_QUIET), 

49 verbose: bool = typer.Option(False, "-v", "--verbose", help=HELP_VERBOSE), 

50 fmt: str = typer.Option("json", "-f", "--format", help=HELP_FORMAT), 

51 pretty: bool = typer.Option(True, "--pretty/--no-pretty", help=HELP_NO_PRETTY), 

52 debug: bool = typer.Option(False, "-d", "--debug", help=HELP_DEBUG), 

53) -> None: 

54 """Defines the entrypoint for the `bijux dev` command group. 

55 

56 This function serves as the default action when `bijux dev` is run 

57 without a subcommand. It emits a simple status payload. If a subcommand 

58 is invoked, this function yields control to it. 

59 

60 Args: 

61 ctx (typer.Context): The Typer context for the CLI. 

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

63 verbose (bool): If True, includes Python/platform details in the output. 

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

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

66 debug (bool): If True, enables debug diagnostics. 

67 

68 Returns: 

69 None: 

70 

71 Raises: 

72 SystemExit: Always exits with a contract-compliant status code and 

73 payload upon completion or error. 

74 """ 

75 if ctx.invoked_subcommand: 

76 return 

77 

78 command = "dev" 

79 effective_include_runtime = (verbose or debug) and not quiet 

80 effective_pretty = True if (debug and not quiet) else pretty 

81 

82 fmt_lower = validate_common_flags( 

83 fmt, 

84 command, 

85 quiet, 

86 include_runtime=effective_include_runtime, 

87 ) 

88 

89 mode = os.environ.get("BIJUXCLI_DEV_MODE") 

90 

91 def payload_builder(_: bool) -> Mapping[str, Any]: 

92 """Builds the payload for the dev status command. 

93 

94 The payload indicates an "ok" status and includes optional mode and 

95 runtime information based on the parent function's scope. 

96 

97 Args: 

98 _ (bool): An unused parameter to match the expected signature of 

99 the `payload_builder` in `new_run_command`. 

100 

101 Returns: 

102 Mapping[str, Any]: The structured payload. 

103 """ 

104 payload: dict[str, Any] = {"status": "ok"} 

105 if mode: 

106 payload["mode"] = mode 

107 if effective_include_runtime: 

108 payload["python"] = ascii_safe(platform.python_version(), "python_version") 

109 payload["platform"] = ascii_safe(platform.platform(), "platform") 

110 return payload 

111 

112 new_run_command( 

113 command_name=command, 

114 payload_builder=payload_builder, 

115 quiet=quiet, 

116 verbose=effective_include_runtime, 

117 fmt=fmt_lower, 

118 pretty=effective_pretty, 

119 debug=(debug and not quiet), 

120 )