Coverage for / home / runner / work / bijux-cli / bijux-cli / src / bijux_cli / cli / commands / config / get.py: 100%
34 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-26 17:59 +0000
« 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
4"""Implements the `config get` subcommand for the Bijux CLI.
6This module contains the logic for retrieving the value of a specific key
7from the active configuration store. It provides a structured, machine-readable
8response containing the value or an error if the key is not found.
10Output Contract:
11 * Success: `{"value": str}`
12 * Error: `{"error": str, "code": int}`
14Exit Codes:
15 * `0`: Success.
16 * `1`: An unexpected error occurred while accessing the configuration.
17 * `2`: The specified key was not found in the configuration.
18"""
20from __future__ import annotations
22import platform
24import typer
26from bijux_cli.cli.core.command import (
27 ascii_safe,
28 new_run_command,
29 validate_common_flags,
30)
31from bijux_cli.cli.core.constants import (
32 OPT_FORMAT,
33 OPT_LOG_LEVEL,
34 OPT_PRETTY,
35 OPT_QUIET,
36)
37from bijux_cli.cli.core.help_text import (
38 HELP_FORMAT,
39 HELP_LOG_LEVEL,
40 HELP_NO_PRETTY,
41 HELP_QUIET,
42)
43from bijux_cli.core.di import DIContainer
44from bijux_cli.core.enums import ErrorType
45from bijux_cli.core.errors import ConfigError
46from bijux_cli.core.exit_policy import ExitIntentError
47from bijux_cli.core.precedence import current_execution_policy, resolve_exit_intent
48from bijux_cli.services.config.contracts import ConfigProtocol
51def get_config(
52 ctx: typer.Context,
53 key: str = typer.Argument(..., help="Configuration key to look up"),
54 quiet: bool = typer.Option(False, *OPT_QUIET, help=HELP_QUIET),
55 fmt: str = typer.Option("json", *OPT_FORMAT, help=HELP_FORMAT),
56 pretty: bool = typer.Option(True, OPT_PRETTY, help=HELP_NO_PRETTY),
57 log_level: str = typer.Option("info", *OPT_LOG_LEVEL, help=HELP_LOG_LEVEL),
58) -> None:
59 """Retrieves the value for a given configuration key.
61 This function fetches the value for the specified key from the configuration
62 service and uses the `new_run_command` helper to emit it in a structured
63 payload. It handles errors, such as the key not being found.
65 Args:
66 ctx (typer.Context): The Typer context for the CLI.
67 key (str): The configuration key whose value should be retrieved.
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.
72 Returns:
73 None:
75 Raises:
76 SystemExit: Always exits with a contract-compliant status code and
77 payload, indicating success or detailing the error.
78 """
79 command = "config get"
80 effective = current_execution_policy()
81 fmt_lower = validate_common_flags(
82 fmt,
83 command,
84 effective.quiet,
85 include_runtime=effective.include_runtime,
86 log_level=effective.log_level,
87 )
88 quiet = effective.quiet
89 include_runtime = effective.include_runtime
90 pretty = effective.pretty
92 config_svc = DIContainer.current().resolve(ConfigProtocol)
94 try:
95 value = config_svc.get(key)
96 except ConfigError as exc:
97 if str(exc).startswith("Config key not found"):
98 intent = resolve_exit_intent(
99 message=f"Config key not found: {key}",
100 code=2,
101 failure="not_found",
102 command=command,
103 fmt=fmt_lower,
104 quiet=quiet,
105 include_runtime=include_runtime,
106 error_type=ErrorType.USER_INPUT,
107 log_level=effective.log_level,
108 extra={"key": key},
109 )
110 raise ExitIntentError(intent) from exc
111 intent = resolve_exit_intent(
112 message=f"Failed to get config: {exc}",
113 code=1,
114 failure="get_failed",
115 command=command,
116 fmt=fmt_lower,
117 quiet=quiet,
118 include_runtime=include_runtime,
119 error_type=ErrorType.INTERNAL,
120 log_level=effective.log_level,
121 )
122 raise ExitIntentError(intent) from exc
124 def payload_builder(include_runtime: bool) -> dict[str, object]:
125 """Builds a payload containing the retrieved configuration value.
127 Args:
128 include_runtime (bool): If True, includes Python and platform info.
130 Returns:
131 dict[str, object]: A dictionary containing the key's value and
132 optional runtime metadata.
133 """
134 payload: dict[str, object] = {"value": value}
135 if include_runtime:
136 payload.update(
137 {
138 "python": ascii_safe(platform.python_version(), "python_version"),
139 "platform": ascii_safe(platform.platform(), "platform"),
140 }
141 )
142 return payload
144 new_run_command(
145 command_name=command,
146 payload_builder=payload_builder,
147 quiet=quiet,
148 fmt=fmt_lower,
149 pretty=pretty,
150 log_level=log_level,
151 )