Coverage for / home / runner / work / bijux-cli / bijux-cli / src / bijux_cli / services / __init__.py: 98%
63 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"""Registers the default services for the Bijux CLI application.
6This module serves as the primary composition root for the application's
7service layer. It provides a single function, `register_default_services`,
8which is responsible for binding all core service protocols to their
9concrete implementations within the Dependency Injection (DI) container.
11This centralized registration is a key part of the application's Inversion of
12Control (IoC) architecture, allowing components to be easily swapped or mocked
13for testing.
14"""
16from __future__ import annotations
18import os
19from typing import TYPE_CHECKING, cast
21from bijux_cli.core.contracts import ExecutionContext
22from bijux_cli.core.enums import OutputFormat
23from bijux_cli.infra.contracts import Emitter, ProcessRunner, RetryPolicy, Serializer
24from bijux_cli.services.config.contracts import ConfigProtocol
25from bijux_cli.services.contracts import ObservabilityProtocol, TelemetryProtocol
26from bijux_cli.services.diagnostics.contracts import (
27 AuditProtocol,
28 DiagnosticsConfig,
29 DocsProtocol,
30 DoctorProtocol,
31 MemoryProtocol,
32)
33from bijux_cli.services.history.contracts import HistoryProtocol
34from bijux_cli.services.logging.contracts import LoggingConfig
36if TYPE_CHECKING:
37 from bijux_cli.core.di import DIContainer
38 from bijux_cli.core.enums import OutputFormat
41def register_default_services(
42 di: DIContainer,
43 *,
44 logging_config: LoggingConfig,
45 output_format: OutputFormat,
46 diagnostics_config: DiagnosticsConfig | None = None,
47) -> None:
48 """Registers all default service implementations with the DI container.
50 This function populates the container with lazy-loading factories for each
51 core service the application requires, from configuration and logging to
52 plugin management and command history.
54 Args:
55 di (DIContainer): The dependency injection container instance.
56 logging_config (LoggingConfig): Logging configuration for services.
57 output_format (OutputFormat): The default output format for services
58 like the emitter and serializer.
60 Returns:
61 None:
62 """
63 import bijux_cli.core.context
64 import bijux_cli.infra.emitter
65 import bijux_cli.infra.process
66 import bijux_cli.infra.retry
67 import bijux_cli.infra.serializer
68 import bijux_cli.infra.telemetry
69 import bijux_cli.services.config
70 import bijux_cli.services.diagnostics.audit
71 import bijux_cli.services.diagnostics.docs
72 import bijux_cli.services.diagnostics.doctor
73 import bijux_cli.services.diagnostics.memory
74 import bijux_cli.services.diagnostics.telemetry
75 import bijux_cli.services.history
76 import bijux_cli.services.logging.observability
78 if diagnostics_config is None: 78 ↛ 81line 78 didn't jump to line 81 because the condition on line 78 was always true
79 diagnostics_config = DiagnosticsConfig(enabled=True, telemetry_enabled=True)
81 di.register(DiagnosticsConfig, lambda: diagnostics_config)
83 noop_telemetry = bijux_cli.infra.telemetry.NoopTelemetry()
84 obs_service = bijux_cli.services.logging.observability.Observability(
85 log_level=logging_config.log_level,
86 telemetry=noop_telemetry,
87 )
89 di.register(
90 bijux_cli.services.logging.observability.Observability, lambda: obs_service
91 )
92 di.register(
93 ObservabilityProtocol,
94 lambda: di.resolve(bijux_cli.services.logging.observability.Observability),
95 )
97 di.register(
98 bijux_cli.infra.telemetry.LoggingTelemetry,
99 lambda: bijux_cli.infra.telemetry.LoggingTelemetry(
100 observability=di.resolve(
101 bijux_cli.services.logging.observability.Observability
102 )
103 ),
104 )
105 di.register(bijux_cli.infra.telemetry.NoopTelemetry, lambda: noop_telemetry)
106 di.register(
107 TelemetryProtocol,
108 lambda: bijux_cli.services.diagnostics.telemetry.resolve_telemetry(di),
109 )
111 di.register(
112 bijux_cli.infra.emitter.ConsoleEmitter,
113 lambda: bijux_cli.infra.emitter.ConsoleEmitter(
114 telemetry=di.resolve(TelemetryProtocol),
115 output_format=output_format,
116 ),
117 )
118 di.register(Emitter, lambda: di.resolve(bijux_cli.infra.emitter.ConsoleEmitter))
120 di.register(
121 bijux_cli.infra.serializer.OrjsonSerializer,
122 lambda: bijux_cli.infra.serializer.OrjsonSerializer(
123 telemetry=di.resolve(TelemetryProtocol)
124 ),
125 )
126 di.register(
127 bijux_cli.infra.serializer.PyYAMLSerializer,
128 lambda: bijux_cli.infra.serializer.PyYAMLSerializer(
129 telemetry=di.resolve(TelemetryProtocol)
130 ),
131 )
132 di.register(
133 Serializer,
134 lambda: (
135 di.resolve(bijux_cli.infra.serializer.OrjsonSerializer)
136 if output_format is OutputFormat.JSON
137 else di.resolve(bijux_cli.infra.serializer.PyYAMLSerializer)
138 ),
139 )
141 di.register(
142 bijux_cli.infra.process.ProcessPool,
143 lambda: bijux_cli.infra.process.ProcessPool(
144 observability=di.resolve(
145 bijux_cli.services.logging.observability.Observability
146 ),
147 telemetry=di.resolve(TelemetryProtocol),
148 max_workers=int(os.getenv("BIJUXCLI_MAX_WORKERS", "4")),
149 allowed_commands=os.getenv(
150 "BIJUXCLI_ALLOWED_COMMANDS", "echo,ls,cat,grep"
151 ).split(","),
152 ),
153 )
154 di.register(ProcessRunner, lambda: di.resolve(bijux_cli.infra.process.ProcessPool))
156 di.register(
157 bijux_cli.infra.retry.TimeoutRetryPolicy,
158 lambda: bijux_cli.infra.retry.TimeoutRetryPolicy(
159 telemetry=di.resolve(TelemetryProtocol)
160 ),
161 )
162 di.register(
163 bijux_cli.infra.retry.ExponentialBackoffRetryPolicy,
164 lambda: bijux_cli.infra.retry.ExponentialBackoffRetryPolicy(
165 telemetry=di.resolve(TelemetryProtocol)
166 ),
167 )
168 di.register(
169 RetryPolicy,
170 lambda: cast(
171 RetryPolicy,
172 di.resolve(bijux_cli.infra.retry.TimeoutRetryPolicy),
173 ),
174 )
176 di.register(LoggingConfig, lambda: logging_config)
178 di.register(
179 bijux_cli.core.context.Context,
180 lambda: bijux_cli.core.context.Context(di),
181 )
182 di.register(ExecutionContext, lambda: di.resolve(bijux_cli.core.context.Context))
184 di.register(
185 bijux_cli.services.config.Config,
186 lambda: bijux_cli.services.config.Config(di),
187 )
188 di.register(ConfigProtocol, lambda: di.resolve(bijux_cli.services.config.Config))
190 di.register(
191 bijux_cli.services.diagnostics.audit.DryRunAudit,
192 lambda: bijux_cli.services.diagnostics.audit.DryRunAudit(
193 di.resolve(bijux_cli.services.logging.observability.Observability),
194 di.resolve(TelemetryProtocol),
195 ),
196 )
197 di.register(
198 bijux_cli.services.diagnostics.audit.RealAudit,
199 lambda: bijux_cli.services.diagnostics.audit.RealAudit(
200 di.resolve(bijux_cli.services.logging.observability.Observability),
201 di.resolve(TelemetryProtocol),
202 allowed_commands=os.getenv(
203 "BIJUXCLI_ALLOWED_COMMANDS", "echo,ls,cat,grep"
204 ).split(","),
205 ),
206 )
207 di.register(
208 AuditProtocol,
209 lambda: bijux_cli.services.diagnostics.audit.get_audit_service(
210 observability=di.resolve(
211 bijux_cli.services.logging.observability.Observability
212 ),
213 telemetry=di.resolve(TelemetryProtocol),
214 dry_run=False,
215 ),
216 )
218 di.register(
219 bijux_cli.services.diagnostics.docs.Docs,
220 lambda: bijux_cli.services.diagnostics.docs.Docs(
221 observability=di.resolve(
222 bijux_cli.services.logging.observability.Observability
223 ),
224 serializer=di.resolve(Serializer),
225 telemetry=di.resolve(TelemetryProtocol),
226 ),
227 )
228 di.register(
229 DocsProtocol, lambda: di.resolve(bijux_cli.services.diagnostics.docs.Docs)
230 )
232 di.register(
233 bijux_cli.services.diagnostics.doctor.Doctor,
234 lambda: bijux_cli.services.diagnostics.doctor.Doctor(),
235 )
236 di.register(
237 DoctorProtocol, lambda: di.resolve(bijux_cli.services.diagnostics.doctor.Doctor)
238 )
240 di.register(
241 bijux_cli.services.history.History,
242 lambda: bijux_cli.services.history.History(
243 telemetry=di.resolve(TelemetryProtocol),
244 observability=di.resolve(
245 bijux_cli.services.logging.observability.Observability
246 ),
247 ),
248 )
249 di.register(HistoryProtocol, lambda: di.resolve(bijux_cli.services.history.History))
251 di.register(
252 bijux_cli.services.diagnostics.memory.Memory,
253 lambda: bijux_cli.services.diagnostics.memory.Memory(),
254 )
255 di.register(
256 MemoryProtocol, lambda: di.resolve(bijux_cli.services.diagnostics.memory.Memory)
257 )
260__all__ = ["register_default_services"]