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
« 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
4"""Implements the `history clear` subcommand for the Bijux CLI.
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.
10Output Contract:
11 * Success: `{"status": "cleared"}`
12 * Verbose: Adds `{"python": str, "platform": str}` to the payload.
13 * Error: `{"error": str, "code": int}`
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"""
21from __future__ import annotations
23from collections.abc import Mapping
24import platform
25from typing import Any
27import typer
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
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.
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.
58 Returns:
59 HistoryProtocol: An instance of the history service.
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 )
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.
89 This command permanently removes all entries from the history store and
90 emits a structured payload to confirm the operation.
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.
99 Returns:
100 None:
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
112 fmt_lower = validate_common_flags(
113 fmt,
114 command,
115 quiet,
116 include_runtime=include_runtime,
117 )
119 history_svc = resolve_history_service(
120 command, fmt_lower, quiet, include_runtime, debug
121 )
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 )
137 def payload_builder(include_runtime: bool) -> Mapping[str, Any]:
138 """Builds the payload confirming the history was cleared.
140 Args:
141 include_runtime (bool): If True, includes Python and platform info.
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
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 )