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

29 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 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 the dev-mode env var is set. 

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

14 

15Exit Codes: 

16 * `0`: Success. 

17 * `1`: An internal or unexpected error occurred. 

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

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

20""" 

21 

22from __future__ import annotations 

23 

24import os 

25import platform 

26 

27import typer 

28 

29from bijux_cli.cli.commands.payloads import DevStatusPayload 

30from bijux_cli.cli.core.command import ( 

31 ascii_safe, 

32 new_run_command, 

33 normalize_format, 

34 validate_common_flags, 

35) 

36from bijux_cli.cli.core.constants import ( 

37 ENV_DEV_MODE, 

38 OPT_FORMAT, 

39 OPT_LOG_LEVEL, 

40 OPT_PRETTY, 

41 OPT_QUIET, 

42) 

43from bijux_cli.cli.core.help_text import ( 

44 HELP_FORMAT, 

45 HELP_LOG_LEVEL, 

46 HELP_NO_PRETTY, 

47 HELP_QUIET, 

48) 

49from bijux_cli.core.enums import OutputFormat 

50from bijux_cli.core.precedence import current_execution_policy 

51 

52 

53def dev( 

54 ctx: typer.Context, 

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

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

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

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

59) -> None: 

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

61 

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

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

64 is invoked, this function yields control to it. 

65 

66 Args: 

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

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

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

70 pretty (bool): If True, pretty-prints the output. log_level (str): Logging level for diagnostics. 

71 

72 Returns: 

73 None: 

74 

75 Raises: 

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

77 payload upon completion or error. 

78 """ 

79 if ctx.invoked_subcommand: 

80 return 

81 

82 command = "dev" 

83 policy = current_execution_policy() 

84 quiet = policy.quiet 

85 effective_include_runtime = policy.include_runtime 

86 effective_pretty = policy.pretty 

87 fmt_lower = normalize_format(fmt) or OutputFormat.JSON 

88 

89 validate_common_flags( 

90 fmt_lower, 

91 command, 

92 quiet, 

93 include_runtime=effective_include_runtime, 

94 ) 

95 

96 mode = os.environ.get(ENV_DEV_MODE) 

97 

98 def payload_builder(_: bool) -> DevStatusPayload: 

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

100 

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

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

103 

104 Args: 

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

106 the `payload_builder` in `new_run_command`. 

107 

108 Returns: 

109 DevStatusPayload: The structured payload. 

110 """ 

111 payload = DevStatusPayload(status="ok") 

112 if mode: 

113 payload = DevStatusPayload( 

114 status=payload.status, 

115 mode=mode, 

116 python=payload.python, 

117 platform=payload.platform, 

118 ) 

119 if effective_include_runtime: 

120 payload = DevStatusPayload( 

121 status=payload.status, 

122 mode=payload.mode, 

123 python=ascii_safe(platform.python_version(), "python_version"), 

124 platform=ascii_safe(platform.platform(), "platform"), 

125 ) 

126 return payload 

127 

128 new_run_command( 

129 command_name=command, 

130 payload_builder=payload_builder, 

131 quiet=quiet, 

132 fmt=fmt_lower, 

133 pretty=effective_pretty, 

134 log_level=log_level, 

135 )