crackerjack 0.31.10__py3-none-any.whl → 0.31.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of crackerjack might be problematic. Click here for more details.
- crackerjack/CLAUDE.md +288 -705
- crackerjack/__main__.py +22 -8
- crackerjack/agents/__init__.py +0 -3
- crackerjack/agents/architect_agent.py +0 -43
- crackerjack/agents/base.py +1 -9
- crackerjack/agents/coordinator.py +2 -148
- crackerjack/agents/documentation_agent.py +109 -81
- crackerjack/agents/dry_agent.py +122 -97
- crackerjack/agents/formatting_agent.py +3 -16
- crackerjack/agents/import_optimization_agent.py +1174 -130
- crackerjack/agents/performance_agent.py +956 -188
- crackerjack/agents/performance_helpers.py +229 -0
- crackerjack/agents/proactive_agent.py +1 -48
- crackerjack/agents/refactoring_agent.py +516 -246
- crackerjack/agents/refactoring_helpers.py +282 -0
- crackerjack/agents/security_agent.py +393 -90
- crackerjack/agents/test_creation_agent.py +1776 -120
- crackerjack/agents/test_specialist_agent.py +59 -15
- crackerjack/agents/tracker.py +0 -102
- crackerjack/api.py +145 -37
- crackerjack/cli/handlers.py +48 -30
- crackerjack/cli/interactive.py +11 -11
- crackerjack/cli/options.py +66 -4
- crackerjack/code_cleaner.py +808 -148
- crackerjack/config/global_lock_config.py +110 -0
- crackerjack/config/hooks.py +43 -64
- crackerjack/core/async_workflow_orchestrator.py +247 -97
- crackerjack/core/autofix_coordinator.py +192 -109
- crackerjack/core/enhanced_container.py +46 -63
- crackerjack/core/file_lifecycle.py +549 -0
- crackerjack/core/performance.py +9 -8
- crackerjack/core/performance_monitor.py +395 -0
- crackerjack/core/phase_coordinator.py +281 -94
- crackerjack/core/proactive_workflow.py +9 -58
- crackerjack/core/resource_manager.py +501 -0
- crackerjack/core/service_watchdog.py +490 -0
- crackerjack/core/session_coordinator.py +4 -8
- crackerjack/core/timeout_manager.py +504 -0
- crackerjack/core/websocket_lifecycle.py +475 -0
- crackerjack/core/workflow_orchestrator.py +343 -209
- crackerjack/dynamic_config.py +47 -6
- crackerjack/errors.py +3 -4
- crackerjack/executors/async_hook_executor.py +63 -13
- crackerjack/executors/cached_hook_executor.py +14 -14
- crackerjack/executors/hook_executor.py +100 -37
- crackerjack/executors/hook_lock_manager.py +856 -0
- crackerjack/executors/individual_hook_executor.py +120 -86
- crackerjack/intelligence/__init__.py +0 -7
- crackerjack/intelligence/adaptive_learning.py +13 -86
- crackerjack/intelligence/agent_orchestrator.py +15 -78
- crackerjack/intelligence/agent_registry.py +12 -59
- crackerjack/intelligence/agent_selector.py +31 -92
- crackerjack/intelligence/integration.py +1 -41
- crackerjack/interactive.py +9 -9
- crackerjack/managers/async_hook_manager.py +25 -8
- crackerjack/managers/hook_manager.py +9 -9
- crackerjack/managers/publish_manager.py +57 -59
- crackerjack/managers/test_command_builder.py +6 -36
- crackerjack/managers/test_executor.py +9 -61
- crackerjack/managers/test_manager.py +17 -63
- crackerjack/managers/test_manager_backup.py +77 -127
- crackerjack/managers/test_progress.py +4 -23
- crackerjack/mcp/cache.py +5 -12
- crackerjack/mcp/client_runner.py +10 -10
- crackerjack/mcp/context.py +64 -6
- crackerjack/mcp/dashboard.py +14 -11
- crackerjack/mcp/enhanced_progress_monitor.py +55 -55
- crackerjack/mcp/file_monitor.py +72 -42
- crackerjack/mcp/progress_components.py +103 -84
- crackerjack/mcp/progress_monitor.py +122 -49
- crackerjack/mcp/rate_limiter.py +12 -12
- crackerjack/mcp/server_core.py +16 -22
- crackerjack/mcp/service_watchdog.py +26 -26
- crackerjack/mcp/state.py +15 -0
- crackerjack/mcp/tools/core_tools.py +95 -39
- crackerjack/mcp/tools/error_analyzer.py +6 -32
- crackerjack/mcp/tools/execution_tools.py +1 -56
- crackerjack/mcp/tools/execution_tools_backup.py +35 -131
- crackerjack/mcp/tools/intelligence_tool_registry.py +0 -36
- crackerjack/mcp/tools/intelligence_tools.py +2 -55
- crackerjack/mcp/tools/monitoring_tools.py +308 -145
- crackerjack/mcp/tools/proactive_tools.py +12 -42
- crackerjack/mcp/tools/progress_tools.py +23 -15
- crackerjack/mcp/tools/utility_tools.py +3 -40
- crackerjack/mcp/tools/workflow_executor.py +40 -60
- crackerjack/mcp/websocket/app.py +0 -3
- crackerjack/mcp/websocket/endpoints.py +206 -268
- crackerjack/mcp/websocket/jobs.py +213 -66
- crackerjack/mcp/websocket/server.py +84 -6
- crackerjack/mcp/websocket/websocket_handler.py +137 -29
- crackerjack/models/config_adapter.py +3 -16
- crackerjack/models/protocols.py +162 -3
- crackerjack/models/resource_protocols.py +454 -0
- crackerjack/models/task.py +3 -3
- crackerjack/monitoring/__init__.py +0 -0
- crackerjack/monitoring/ai_agent_watchdog.py +25 -71
- crackerjack/monitoring/regression_prevention.py +28 -87
- crackerjack/orchestration/advanced_orchestrator.py +44 -78
- crackerjack/orchestration/coverage_improvement.py +10 -60
- crackerjack/orchestration/execution_strategies.py +16 -16
- crackerjack/orchestration/test_progress_streamer.py +61 -53
- crackerjack/plugins/base.py +1 -1
- crackerjack/plugins/managers.py +22 -20
- crackerjack/py313.py +65 -21
- crackerjack/services/backup_service.py +467 -0
- crackerjack/services/bounded_status_operations.py +627 -0
- crackerjack/services/cache.py +7 -9
- crackerjack/services/config.py +35 -52
- crackerjack/services/config_integrity.py +5 -16
- crackerjack/services/config_merge.py +542 -0
- crackerjack/services/contextual_ai_assistant.py +17 -19
- crackerjack/services/coverage_ratchet.py +44 -73
- crackerjack/services/debug.py +25 -39
- crackerjack/services/dependency_monitor.py +52 -50
- crackerjack/services/enhanced_filesystem.py +14 -11
- crackerjack/services/file_hasher.py +1 -1
- crackerjack/services/filesystem.py +1 -12
- crackerjack/services/git.py +71 -47
- crackerjack/services/health_metrics.py +31 -27
- crackerjack/services/initialization.py +276 -428
- crackerjack/services/input_validator.py +760 -0
- crackerjack/services/log_manager.py +16 -16
- crackerjack/services/logging.py +7 -6
- crackerjack/services/metrics.py +43 -43
- crackerjack/services/pattern_cache.py +2 -31
- crackerjack/services/pattern_detector.py +26 -63
- crackerjack/services/performance_benchmarks.py +20 -45
- crackerjack/services/regex_patterns.py +2887 -0
- crackerjack/services/regex_utils.py +537 -0
- crackerjack/services/secure_path_utils.py +683 -0
- crackerjack/services/secure_status_formatter.py +534 -0
- crackerjack/services/secure_subprocess.py +605 -0
- crackerjack/services/security.py +47 -10
- crackerjack/services/security_logger.py +492 -0
- crackerjack/services/server_manager.py +109 -50
- crackerjack/services/smart_scheduling.py +8 -25
- crackerjack/services/status_authentication.py +603 -0
- crackerjack/services/status_security_manager.py +442 -0
- crackerjack/services/thread_safe_status_collector.py +546 -0
- crackerjack/services/tool_version_service.py +1 -23
- crackerjack/services/unified_config.py +36 -58
- crackerjack/services/validation_rate_limiter.py +269 -0
- crackerjack/services/version_checker.py +9 -40
- crackerjack/services/websocket_resource_limiter.py +572 -0
- crackerjack/slash_commands/__init__.py +52 -2
- crackerjack/tools/__init__.py +0 -0
- crackerjack/tools/validate_input_validator_patterns.py +262 -0
- crackerjack/tools/validate_regex_patterns.py +198 -0
- {crackerjack-0.31.10.dist-info → crackerjack-0.31.12.dist-info}/METADATA +197 -12
- crackerjack-0.31.12.dist-info/RECORD +178 -0
- crackerjack/cli/facade.py +0 -104
- crackerjack-0.31.10.dist-info/RECORD +0 -149
- {crackerjack-0.31.10.dist-info → crackerjack-0.31.12.dist-info}/WHEEL +0 -0
- {crackerjack-0.31.10.dist-info → crackerjack-0.31.12.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.31.10.dist-info → crackerjack-0.31.12.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"""Enhanced dependency injection container with lifecycle management."""
|
|
2
|
-
|
|
3
1
|
import inspect
|
|
4
2
|
import threading
|
|
5
3
|
import typing as t
|
|
@@ -12,6 +10,7 @@ from typing import Any, TypeVar
|
|
|
12
10
|
from rich.console import Console
|
|
13
11
|
|
|
14
12
|
from crackerjack.models.protocols import (
|
|
13
|
+
ConfigMergeServiceProtocol,
|
|
15
14
|
FileSystemInterface,
|
|
16
15
|
GitInterface,
|
|
17
16
|
HookManager,
|
|
@@ -25,8 +24,6 @@ FactoryFunc = Callable[..., T]
|
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
class ServiceLifetime(Enum):
|
|
28
|
-
"""Service lifetime enumeration."""
|
|
29
|
-
|
|
30
27
|
SINGLETON = "singleton"
|
|
31
28
|
TRANSIENT = "transient"
|
|
32
29
|
SCOPED = "scoped"
|
|
@@ -34,8 +31,6 @@ class ServiceLifetime(Enum):
|
|
|
34
31
|
|
|
35
32
|
@dataclass
|
|
36
33
|
class ServiceDescriptor:
|
|
37
|
-
"""Describes how to create a service instance."""
|
|
38
|
-
|
|
39
34
|
interface: type
|
|
40
35
|
implementation: type | None = None
|
|
41
36
|
factory: Callable[..., Any] | None = None
|
|
@@ -51,8 +46,6 @@ class ServiceDescriptor:
|
|
|
51
46
|
|
|
52
47
|
|
|
53
48
|
class ServiceScope:
|
|
54
|
-
"""Represents a service scope for scoped services."""
|
|
55
|
-
|
|
56
49
|
def __init__(self, name: str) -> None:
|
|
57
50
|
self.name = name
|
|
58
51
|
self._instances: dict[str, Any] = {}
|
|
@@ -60,18 +53,15 @@ class ServiceScope:
|
|
|
60
53
|
self.logger = get_logger("crackerjack.container.scope")
|
|
61
54
|
|
|
62
55
|
def get_instance(self, key: str) -> Any | None:
|
|
63
|
-
"""Get scoped instance."""
|
|
64
56
|
with self._lock:
|
|
65
57
|
return self._instances.get(key)
|
|
66
58
|
|
|
67
59
|
def set_instance(self, key: str, instance: Any) -> None:
|
|
68
|
-
"""Set scoped instance."""
|
|
69
60
|
with self._lock:
|
|
70
61
|
self._instances[key] = instance
|
|
71
62
|
self.logger.debug("Scoped instance created", scope=self.name, service=key)
|
|
72
63
|
|
|
73
64
|
def dispose(self) -> None:
|
|
74
|
-
"""Dispose of all scoped instances."""
|
|
75
65
|
with self._lock:
|
|
76
66
|
for key, instance in self._instances.items():
|
|
77
67
|
if hasattr(instance, "dispose"):
|
|
@@ -89,8 +79,6 @@ class ServiceScope:
|
|
|
89
79
|
|
|
90
80
|
|
|
91
81
|
class DependencyResolver:
|
|
92
|
-
"""Resolves service dependencies through constructor injection."""
|
|
93
|
-
|
|
94
82
|
def __init__(self, container: "EnhancedDependencyContainer") -> None:
|
|
95
83
|
self.container = container
|
|
96
84
|
self.logger = get_logger("crackerjack.container.resolver")
|
|
@@ -100,7 +88,6 @@ class DependencyResolver:
|
|
|
100
88
|
descriptor: ServiceDescriptor,
|
|
101
89
|
scope: ServiceScope | None = None,
|
|
102
90
|
) -> Any:
|
|
103
|
-
"""Create service instance with dependency injection."""
|
|
104
91
|
if descriptor.instance is not None:
|
|
105
92
|
return descriptor.instance
|
|
106
93
|
|
|
@@ -114,7 +101,6 @@ class DependencyResolver:
|
|
|
114
101
|
raise ValueError(msg)
|
|
115
102
|
|
|
116
103
|
def _create_from_factory(self, factory: Callable[..., Any]) -> Any:
|
|
117
|
-
"""Create instance using factory function."""
|
|
118
104
|
sig = inspect.signature(factory)
|
|
119
105
|
kwargs = {}
|
|
120
106
|
|
|
@@ -124,17 +110,25 @@ class DependencyResolver:
|
|
|
124
110
|
dependency = self.container.get(param.annotation)
|
|
125
111
|
kwargs[param_name] = dependency
|
|
126
112
|
except Exception as e:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
113
|
+
# Only log as warning for required parameters, debug for optional ones with defaults
|
|
114
|
+
if param.default == inspect.Parameter.empty:
|
|
115
|
+
self.logger.warning(
|
|
116
|
+
"Could not inject dependency",
|
|
117
|
+
parameter=param_name,
|
|
118
|
+
type=param.annotation,
|
|
119
|
+
error=str(e),
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
self.logger.debug(
|
|
123
|
+
"Could not inject optional dependency, using default",
|
|
124
|
+
parameter=param_name,
|
|
125
|
+
type=param.annotation,
|
|
126
|
+
default=param.default,
|
|
127
|
+
)
|
|
133
128
|
|
|
134
129
|
return factory(**kwargs)
|
|
135
130
|
|
|
136
131
|
def _create_from_class(self, implementation: type) -> Any:
|
|
137
|
-
"""Create instance using class constructor with dependency injection."""
|
|
138
132
|
try:
|
|
139
133
|
kwargs = self._build_constructor_kwargs(implementation)
|
|
140
134
|
return self._instantiate_with_logging(implementation, kwargs)
|
|
@@ -147,7 +141,6 @@ class DependencyResolver:
|
|
|
147
141
|
raise
|
|
148
142
|
|
|
149
143
|
def _build_constructor_kwargs(self, implementation: type) -> dict[str, Any]:
|
|
150
|
-
"""Build constructor kwargs by resolving dependencies."""
|
|
151
144
|
init_sig = inspect.signature(implementation.__init__)
|
|
152
145
|
kwargs = {}
|
|
153
146
|
|
|
@@ -169,7 +162,6 @@ class DependencyResolver:
|
|
|
169
162
|
param: inspect.Parameter,
|
|
170
163
|
class_name: str,
|
|
171
164
|
) -> None:
|
|
172
|
-
"""Resolve a single parameter dependency."""
|
|
173
165
|
try:
|
|
174
166
|
dependency = self.container.get(param.annotation)
|
|
175
167
|
kwargs[param_name] = dependency
|
|
@@ -192,7 +184,6 @@ class DependencyResolver:
|
|
|
192
184
|
def _instantiate_with_logging(
|
|
193
185
|
self, implementation: type, kwargs: dict[str, Any]
|
|
194
186
|
) -> Any:
|
|
195
|
-
"""Create instance and log the creation."""
|
|
196
187
|
instance = implementation(**kwargs)
|
|
197
188
|
self.logger.debug(
|
|
198
189
|
"Instance created with DI",
|
|
@@ -202,8 +193,6 @@ class DependencyResolver:
|
|
|
202
193
|
|
|
203
194
|
|
|
204
195
|
class EnhancedDependencyContainer:
|
|
205
|
-
"""Enhanced dependency injection container with lifecycle management."""
|
|
206
|
-
|
|
207
196
|
def __init__(self, name: str = "default") -> None:
|
|
208
197
|
self.name = name
|
|
209
198
|
self._services: dict[str, ServiceDescriptor] = {}
|
|
@@ -220,7 +209,6 @@ class EnhancedDependencyContainer:
|
|
|
220
209
|
factory: Callable[..., Any] | None = None,
|
|
221
210
|
instance: Any | None = None,
|
|
222
211
|
) -> "EnhancedDependencyContainer":
|
|
223
|
-
"""Register a singleton service."""
|
|
224
212
|
key = self._get_service_key(interface)
|
|
225
213
|
|
|
226
214
|
descriptor = ServiceDescriptor(
|
|
@@ -243,7 +231,6 @@ class EnhancedDependencyContainer:
|
|
|
243
231
|
implementation: type | None = None,
|
|
244
232
|
factory: Callable[..., Any] | None = None,
|
|
245
233
|
) -> "EnhancedDependencyContainer":
|
|
246
|
-
"""Register a transient service."""
|
|
247
234
|
key = self._get_service_key(interface)
|
|
248
235
|
|
|
249
236
|
descriptor = ServiceDescriptor(
|
|
@@ -265,7 +252,6 @@ class EnhancedDependencyContainer:
|
|
|
265
252
|
implementation: type | None = None,
|
|
266
253
|
factory: Callable[..., Any] | None = None,
|
|
267
254
|
) -> "EnhancedDependencyContainer":
|
|
268
|
-
"""Register a scoped service."""
|
|
269
255
|
key = self._get_service_key(interface)
|
|
270
256
|
|
|
271
257
|
descriptor = ServiceDescriptor(
|
|
@@ -282,7 +268,6 @@ class EnhancedDependencyContainer:
|
|
|
282
268
|
return self
|
|
283
269
|
|
|
284
270
|
def get(self, interface: type, scope: ServiceScope | None = None) -> Any:
|
|
285
|
-
"""Get service instance."""
|
|
286
271
|
key = self._get_service_key(interface)
|
|
287
272
|
|
|
288
273
|
with self._lock:
|
|
@@ -295,27 +280,22 @@ class EnhancedDependencyContainer:
|
|
|
295
280
|
return self._create_service_instance(descriptor, scope or self._current_scope)
|
|
296
281
|
|
|
297
282
|
def get_optional(self, interface: type, default: Any = None) -> Any:
|
|
298
|
-
"""Get service instance or return default if not registered."""
|
|
299
283
|
try:
|
|
300
284
|
return self.get(interface)
|
|
301
285
|
except ValueError:
|
|
302
286
|
return default
|
|
303
287
|
|
|
304
288
|
def is_registered(self, interface: type) -> bool:
|
|
305
|
-
"""Check if service is registered."""
|
|
306
289
|
key = self._get_service_key(interface)
|
|
307
290
|
return key in self._services
|
|
308
291
|
|
|
309
292
|
def create_scope(self, name: str = "scope") -> ServiceScope:
|
|
310
|
-
"""Create a new service scope."""
|
|
311
293
|
return ServiceScope(name)
|
|
312
294
|
|
|
313
295
|
def set_current_scope(self, scope: ServiceScope | None) -> None:
|
|
314
|
-
"""Set the current service scope."""
|
|
315
296
|
self._current_scope = scope
|
|
316
297
|
|
|
317
298
|
def get_service_info(self) -> dict[str, Any]:
|
|
318
|
-
"""Get information about registered services."""
|
|
319
299
|
info = {}
|
|
320
300
|
|
|
321
301
|
with self._lock:
|
|
@@ -333,9 +313,7 @@ class EnhancedDependencyContainer:
|
|
|
333
313
|
return info
|
|
334
314
|
|
|
335
315
|
def dispose(self) -> None:
|
|
336
|
-
"""Dispose of container and all singletons."""
|
|
337
316
|
with self._lock:
|
|
338
|
-
# Dispose singletons
|
|
339
317
|
for key, instance in self._singletons.items():
|
|
340
318
|
if hasattr(instance, "dispose"):
|
|
341
319
|
try:
|
|
@@ -349,7 +327,6 @@ class EnhancedDependencyContainer:
|
|
|
349
327
|
|
|
350
328
|
self._singletons.clear()
|
|
351
329
|
|
|
352
|
-
# Dispose current scope
|
|
353
330
|
if self._current_scope:
|
|
354
331
|
self._current_scope.dispose()
|
|
355
332
|
self._current_scope = None
|
|
@@ -361,16 +338,14 @@ class EnhancedDependencyContainer:
|
|
|
361
338
|
descriptor: ServiceDescriptor,
|
|
362
339
|
scope: ServiceScope | None = None,
|
|
363
340
|
) -> Any:
|
|
364
|
-
"""Create service instance based on lifetime."""
|
|
365
341
|
if descriptor.lifetime == ServiceLifetime.SINGLETON:
|
|
366
342
|
return self._get_or_create_singleton(descriptor)
|
|
367
343
|
if descriptor.lifetime == ServiceLifetime.SCOPED:
|
|
368
344
|
return self._get_or_create_scoped(descriptor, scope)
|
|
369
|
-
|
|
345
|
+
|
|
370
346
|
return self._create_transient_instance(descriptor)
|
|
371
347
|
|
|
372
348
|
def _get_or_create_singleton(self, descriptor: ServiceDescriptor) -> Any:
|
|
373
|
-
"""Get or create singleton instance."""
|
|
374
349
|
key = self._get_service_key(descriptor.interface)
|
|
375
350
|
|
|
376
351
|
if key in self._singletons:
|
|
@@ -388,7 +363,6 @@ class EnhancedDependencyContainer:
|
|
|
388
363
|
descriptor: ServiceDescriptor,
|
|
389
364
|
scope: ServiceScope | None,
|
|
390
365
|
) -> Any:
|
|
391
|
-
"""Get or create scoped instance."""
|
|
392
366
|
if scope is None:
|
|
393
367
|
msg = f"Scoped service {descriptor.interface.__name__} requires an active scope"
|
|
394
368
|
raise ValueError(
|
|
@@ -406,13 +380,11 @@ class EnhancedDependencyContainer:
|
|
|
406
380
|
return instance
|
|
407
381
|
|
|
408
382
|
def _create_transient_instance(self, descriptor: ServiceDescriptor) -> Any:
|
|
409
|
-
"""Create new transient instance."""
|
|
410
383
|
instance = self.resolver.create_instance(descriptor)
|
|
411
384
|
descriptor.created_count += 1
|
|
412
385
|
return instance
|
|
413
386
|
|
|
414
387
|
def _get_service_key(self, interface: type) -> str:
|
|
415
|
-
"""Get service key from interface type."""
|
|
416
388
|
return f"{interface.__module__}.{interface.__name__}"
|
|
417
389
|
|
|
418
390
|
def __enter__(self):
|
|
@@ -428,35 +400,33 @@ class EnhancedDependencyContainer:
|
|
|
428
400
|
|
|
429
401
|
|
|
430
402
|
class ServiceCollectionBuilder:
|
|
431
|
-
"""Builder pattern for configuring services."""
|
|
432
|
-
|
|
433
403
|
def __init__(self, container: EnhancedDependencyContainer) -> None:
|
|
434
404
|
self.container = container
|
|
435
405
|
self.console: Console | None = None
|
|
436
406
|
self.pkg_path: Path | None = None
|
|
437
407
|
self.dry_run: bool = False
|
|
408
|
+
self.verbose: bool = False
|
|
438
409
|
|
|
439
410
|
def with_console(self, console: Console) -> "ServiceCollectionBuilder":
|
|
440
|
-
"""Set console for services that need it."""
|
|
441
411
|
self.console = console
|
|
442
412
|
return self
|
|
443
413
|
|
|
444
414
|
def with_package_path(self, pkg_path: Path) -> "ServiceCollectionBuilder":
|
|
445
|
-
"""Set package path for services that need it."""
|
|
446
415
|
self.pkg_path = pkg_path
|
|
447
416
|
return self
|
|
448
417
|
|
|
449
418
|
def with_dry_run(self, dry_run: bool) -> "ServiceCollectionBuilder":
|
|
450
|
-
"""Set dry run mode."""
|
|
451
419
|
self.dry_run = dry_run
|
|
452
420
|
return self
|
|
453
421
|
|
|
422
|
+
def with_verbose(self, verbose: bool) -> "ServiceCollectionBuilder":
|
|
423
|
+
self.verbose = verbose
|
|
424
|
+
return self
|
|
425
|
+
|
|
454
426
|
def add_core_services(self) -> "ServiceCollectionBuilder":
|
|
455
|
-
"""Add core Crackerjack services."""
|
|
456
427
|
console = self.console or Console(force_terminal=True)
|
|
457
428
|
pkg_path = self.pkg_path or Path.cwd()
|
|
458
429
|
|
|
459
|
-
# Enhanced filesystem service
|
|
460
430
|
from crackerjack.services.enhanced_filesystem import EnhancedFileSystemService
|
|
461
431
|
|
|
462
432
|
self.container.register_singleton(
|
|
@@ -464,7 +434,6 @@ class ServiceCollectionBuilder:
|
|
|
464
434
|
factory=EnhancedFileSystemService,
|
|
465
435
|
)
|
|
466
436
|
|
|
467
|
-
# Git service
|
|
468
437
|
from crackerjack.services.git import GitService
|
|
469
438
|
|
|
470
439
|
self.container.register_transient(
|
|
@@ -472,15 +441,15 @@ class ServiceCollectionBuilder:
|
|
|
472
441
|
factory=lambda: GitService(console=console, pkg_path=pkg_path),
|
|
473
442
|
)
|
|
474
443
|
|
|
475
|
-
|
|
476
|
-
from crackerjack.managers.async_hook_manager import AsyncHookManager
|
|
444
|
+
from crackerjack.managers.hook_manager import HookManagerImpl
|
|
477
445
|
|
|
478
|
-
self.container.
|
|
446
|
+
self.container.register_transient(
|
|
479
447
|
HookManager,
|
|
480
|
-
factory=lambda:
|
|
448
|
+
factory=lambda: HookManagerImpl(
|
|
449
|
+
console=console, pkg_path=pkg_path, verbose=self.verbose
|
|
450
|
+
),
|
|
481
451
|
)
|
|
482
452
|
|
|
483
|
-
# Test manager
|
|
484
453
|
from crackerjack.managers.test_manager import TestManagementImpl
|
|
485
454
|
|
|
486
455
|
self.container.register_transient(
|
|
@@ -488,7 +457,6 @@ class ServiceCollectionBuilder:
|
|
|
488
457
|
factory=lambda: TestManagementImpl(console=console, pkg_path=pkg_path),
|
|
489
458
|
)
|
|
490
459
|
|
|
491
|
-
# Publish manager
|
|
492
460
|
from crackerjack.managers.publish_manager import PublishManagerImpl
|
|
493
461
|
|
|
494
462
|
self.container.register_transient(
|
|
@@ -503,11 +471,9 @@ class ServiceCollectionBuilder:
|
|
|
503
471
|
return self
|
|
504
472
|
|
|
505
473
|
def add_configuration_services(self) -> "ServiceCollectionBuilder":
|
|
506
|
-
"""Add configuration services."""
|
|
507
474
|
console = self.console or Console(force_terminal=True)
|
|
508
475
|
pkg_path = self.pkg_path or Path.cwd()
|
|
509
476
|
|
|
510
|
-
# Unified configuration service
|
|
511
477
|
from crackerjack.services.unified_config import UnifiedConfigurationService
|
|
512
478
|
|
|
513
479
|
self.container.register_singleton(
|
|
@@ -515,10 +481,26 @@ class ServiceCollectionBuilder:
|
|
|
515
481
|
factory=lambda: UnifiedConfigurationService(console, pkg_path),
|
|
516
482
|
)
|
|
517
483
|
|
|
484
|
+
# Register ConfigMergeService for smart configuration merging
|
|
485
|
+
from crackerjack.services.config_merge import ConfigMergeService
|
|
486
|
+
|
|
487
|
+
def create_config_merge_service() -> ConfigMergeService:
|
|
488
|
+
filesystem = self.container.get(FileSystemInterface)
|
|
489
|
+
git_service = self.container.get(GitInterface)
|
|
490
|
+
return ConfigMergeService(
|
|
491
|
+
console=console,
|
|
492
|
+
filesystem=filesystem,
|
|
493
|
+
git_service=git_service,
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
self.container.register_transient(
|
|
497
|
+
ConfigMergeServiceProtocol,
|
|
498
|
+
factory=create_config_merge_service,
|
|
499
|
+
)
|
|
500
|
+
|
|
518
501
|
return self
|
|
519
502
|
|
|
520
503
|
def build(self) -> EnhancedDependencyContainer:
|
|
521
|
-
"""Build the configured container."""
|
|
522
504
|
return self.container
|
|
523
505
|
|
|
524
506
|
|
|
@@ -526,15 +508,16 @@ def create_enhanced_container(
|
|
|
526
508
|
console: Console | None = None,
|
|
527
509
|
pkg_path: Path | None = None,
|
|
528
510
|
dry_run: bool = False,
|
|
511
|
+
verbose: bool = False,
|
|
529
512
|
name: str = "crackerjack",
|
|
530
513
|
) -> EnhancedDependencyContainer:
|
|
531
|
-
"""Create enhanced dependency injection container with default services."""
|
|
532
514
|
container = EnhancedDependencyContainer(name)
|
|
533
515
|
|
|
534
516
|
builder = ServiceCollectionBuilder(container)
|
|
535
517
|
builder.with_console(console or Console(force_terminal=True))
|
|
536
518
|
builder.with_package_path(pkg_path or Path.cwd())
|
|
537
519
|
builder.with_dry_run(dry_run)
|
|
520
|
+
builder.with_verbose(verbose)
|
|
538
521
|
|
|
539
522
|
builder.add_core_services()
|
|
540
523
|
builder.add_configuration_services()
|