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

33 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 `history clear` subcommand for the Bijux CLI. 

5 

6This module contains the logic for permanently erasing all entries from the 

7command history store. This action is irreversible. A structured confirmation 

8is emitted upon success. 

9 

10Output Contract: 

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

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

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

14 

15Exit Codes: 

16 * `0`: Success. 

17 * `1`: An unexpected error occurred, such as the history service being 

18 unavailable or a failure during the clear operation. 

19""" 

20 

21from __future__ import annotations 

22 

23from collections.abc import Mapping 

24import platform 

25from typing import Any 

26 

27import typer 

28 

29from bijux_cli.commands.utilities import ( 

30 ascii_safe, 

31 emit_error_and_exit, 

32 new_run_command, 

33 validate_common_flags, 

34) 

35from bijux_cli.contracts import HistoryProtocol 

36from bijux_cli.core.constants import ( 

37 HELP_DEBUG, 

38 HELP_FORMAT, 

39 HELP_NO_PRETTY, 

40 HELP_QUIET, 

41 HELP_VERBOSE, 

42) 

43from bijux_cli.core.di import DIContainer 

44 

45 

46def resolve_history_service( 

47 command: str, fmt_lower: str, quiet: bool, include_runtime: bool, debug: bool 

48) -> HistoryProtocol: 

49 """Resolves the HistoryProtocol implementation from the DI container. 

50 

51 Args: 

52 command (str): The full command name (e.g., "history clear"). 

53 fmt_lower (str): The chosen output format, lowercased. 

54 quiet (bool): If True, suppresses non-error output. 

55 include_runtime (bool): If True, includes runtime metadata in errors. 

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

57 

58 Returns: 

59 HistoryProtocol: An instance of the history service. 

60 

61 Raises: 

62 SystemExit: Exits with a structured error if the service cannot be 

63 resolved from the container. 

64 """ 

65 try: 

66 return DIContainer.current().resolve(HistoryProtocol) 

67 except Exception as exc: 

68 emit_error_and_exit( 

69 f"History service unavailable: {exc}", 

70 code=1, 

71 failure="service_unavailable", 

72 command=command, 

73 fmt=fmt_lower, 

74 quiet=quiet, 

75 include_runtime=include_runtime, 

76 debug=debug, 

77 ) 

78 

79 

80def clear_history( 

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

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

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

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

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

86) -> None: 

87 """Erases all stored command history. 

88 

89 This command permanently removes all entries from the history store and 

90 emits a structured payload to confirm the operation. 

91 

92 Args: 

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

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

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

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

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

98 

99 Returns: 

100 None: 

101 

102 Raises: 

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

104 payload, indicating success or detailing an error. 

105 """ 

106 command = "history clear" 

107 if debug: 

108 verbose = True 

109 pretty = True 

110 include_runtime = verbose 

111 

112 fmt_lower = validate_common_flags( 

113 fmt, 

114 command, 

115 quiet, 

116 include_runtime=include_runtime, 

117 ) 

118 

119 history_svc = resolve_history_service( 

120 command, fmt_lower, quiet, include_runtime, debug 

121 ) 

122 

123 try: 

124 history_svc.clear() 

125 except Exception as exc: 

126 emit_error_and_exit( 

127 f"Failed to clear history: {exc}", 

128 code=1, 

129 failure="clear_failed", 

130 command=command, 

131 fmt=fmt_lower, 

132 quiet=quiet, 

133 include_runtime=include_runtime, 

134 debug=debug, 

135 ) 

136 

137 def payload_builder(include_runtime: bool) -> Mapping[str, Any]: 

138 """Builds the payload confirming the history was cleared. 

139 

140 Args: 

141 include_runtime (bool): If True, includes Python and platform info. 

142 

143 Returns: 

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

145 """ 

146 payload: dict[str, Any] = {"status": "cleared"} 

147 if include_runtime: 

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

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

150 return payload 

151 

152 new_run_command( 

153 command_name=command, 

154 payload_builder=payload_builder, 

155 quiet=quiet, 

156 verbose=verbose, 

157 fmt=fmt_lower, 

158 pretty=pretty, 

159 debug=debug, 

160 )