crackerjack 0.18.2__py3-none-any.whl → 0.45.2__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.
- crackerjack/README.md +19 -0
- crackerjack/__init__.py +96 -2
- crackerjack/__main__.py +637 -138
- crackerjack/adapters/README.md +18 -0
- crackerjack/adapters/__init__.py +39 -0
- crackerjack/adapters/_output_paths.py +167 -0
- crackerjack/adapters/_qa_adapter_base.py +309 -0
- crackerjack/adapters/_tool_adapter_base.py +706 -0
- crackerjack/adapters/ai/README.md +65 -0
- crackerjack/adapters/ai/__init__.py +5 -0
- crackerjack/adapters/ai/claude.py +853 -0
- crackerjack/adapters/complexity/README.md +53 -0
- crackerjack/adapters/complexity/__init__.py +10 -0
- crackerjack/adapters/complexity/complexipy.py +641 -0
- crackerjack/adapters/dependency/__init__.py +22 -0
- crackerjack/adapters/dependency/pip_audit.py +418 -0
- crackerjack/adapters/format/README.md +72 -0
- crackerjack/adapters/format/__init__.py +11 -0
- crackerjack/adapters/format/mdformat.py +313 -0
- crackerjack/adapters/format/ruff.py +516 -0
- crackerjack/adapters/lint/README.md +47 -0
- crackerjack/adapters/lint/__init__.py +11 -0
- crackerjack/adapters/lint/codespell.py +273 -0
- crackerjack/adapters/lsp/README.md +49 -0
- crackerjack/adapters/lsp/__init__.py +27 -0
- crackerjack/adapters/lsp/_base.py +194 -0
- crackerjack/adapters/lsp/_client.py +358 -0
- crackerjack/adapters/lsp/_manager.py +193 -0
- crackerjack/adapters/lsp/skylos.py +283 -0
- crackerjack/adapters/lsp/zuban.py +557 -0
- crackerjack/adapters/refactor/README.md +59 -0
- crackerjack/adapters/refactor/__init__.py +12 -0
- crackerjack/adapters/refactor/creosote.py +318 -0
- crackerjack/adapters/refactor/refurb.py +406 -0
- crackerjack/adapters/refactor/skylos.py +494 -0
- crackerjack/adapters/sast/README.md +132 -0
- crackerjack/adapters/sast/__init__.py +32 -0
- crackerjack/adapters/sast/_base.py +201 -0
- crackerjack/adapters/sast/bandit.py +423 -0
- crackerjack/adapters/sast/pyscn.py +405 -0
- crackerjack/adapters/sast/semgrep.py +241 -0
- crackerjack/adapters/security/README.md +111 -0
- crackerjack/adapters/security/__init__.py +17 -0
- crackerjack/adapters/security/gitleaks.py +339 -0
- crackerjack/adapters/type/README.md +52 -0
- crackerjack/adapters/type/__init__.py +12 -0
- crackerjack/adapters/type/pyrefly.py +402 -0
- crackerjack/adapters/type/ty.py +402 -0
- crackerjack/adapters/type/zuban.py +522 -0
- crackerjack/adapters/utility/README.md +51 -0
- crackerjack/adapters/utility/__init__.py +10 -0
- crackerjack/adapters/utility/checks.py +884 -0
- crackerjack/agents/README.md +264 -0
- crackerjack/agents/__init__.py +66 -0
- crackerjack/agents/architect_agent.py +238 -0
- crackerjack/agents/base.py +167 -0
- crackerjack/agents/claude_code_bridge.py +641 -0
- crackerjack/agents/coordinator.py +600 -0
- crackerjack/agents/documentation_agent.py +520 -0
- crackerjack/agents/dry_agent.py +585 -0
- crackerjack/agents/enhanced_coordinator.py +279 -0
- crackerjack/agents/enhanced_proactive_agent.py +185 -0
- crackerjack/agents/error_middleware.py +53 -0
- crackerjack/agents/formatting_agent.py +230 -0
- crackerjack/agents/helpers/__init__.py +9 -0
- crackerjack/agents/helpers/performance/__init__.py +22 -0
- crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
- crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
- crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
- crackerjack/agents/helpers/refactoring/__init__.py +22 -0
- crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
- crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
- crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
- crackerjack/agents/helpers/test_creation/__init__.py +19 -0
- crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
- crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
- crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
- crackerjack/agents/import_optimization_agent.py +1181 -0
- crackerjack/agents/performance_agent.py +325 -0
- crackerjack/agents/performance_helpers.py +205 -0
- crackerjack/agents/proactive_agent.py +55 -0
- crackerjack/agents/refactoring_agent.py +511 -0
- crackerjack/agents/refactoring_helpers.py +247 -0
- crackerjack/agents/security_agent.py +793 -0
- crackerjack/agents/semantic_agent.py +479 -0
- crackerjack/agents/semantic_helpers.py +356 -0
- crackerjack/agents/test_creation_agent.py +570 -0
- crackerjack/agents/test_specialist_agent.py +526 -0
- crackerjack/agents/tracker.py +110 -0
- crackerjack/api.py +647 -0
- crackerjack/cli/README.md +394 -0
- crackerjack/cli/__init__.py +24 -0
- crackerjack/cli/cache_handlers.py +209 -0
- crackerjack/cli/cache_handlers_enhanced.py +680 -0
- crackerjack/cli/facade.py +162 -0
- crackerjack/cli/formatting.py +13 -0
- crackerjack/cli/handlers/__init__.py +85 -0
- crackerjack/cli/handlers/advanced.py +103 -0
- crackerjack/cli/handlers/ai_features.py +62 -0
- crackerjack/cli/handlers/analytics.py +479 -0
- crackerjack/cli/handlers/changelog.py +271 -0
- crackerjack/cli/handlers/config_handlers.py +16 -0
- crackerjack/cli/handlers/coverage.py +84 -0
- crackerjack/cli/handlers/documentation.py +280 -0
- crackerjack/cli/handlers/main_handlers.py +497 -0
- crackerjack/cli/handlers/monitoring.py +371 -0
- crackerjack/cli/handlers.py +700 -0
- crackerjack/cli/interactive.py +488 -0
- crackerjack/cli/options.py +1216 -0
- crackerjack/cli/semantic_handlers.py +292 -0
- crackerjack/cli/utils.py +19 -0
- crackerjack/cli/version.py +19 -0
- crackerjack/code_cleaner.py +1307 -0
- crackerjack/config/README.md +472 -0
- crackerjack/config/__init__.py +275 -0
- crackerjack/config/global_lock_config.py +207 -0
- crackerjack/config/hooks.py +390 -0
- crackerjack/config/loader.py +239 -0
- crackerjack/config/settings.py +141 -0
- crackerjack/config/tool_commands.py +331 -0
- crackerjack/core/README.md +393 -0
- crackerjack/core/__init__.py +0 -0
- crackerjack/core/async_workflow_orchestrator.py +738 -0
- crackerjack/core/autofix_coordinator.py +282 -0
- crackerjack/core/container.py +105 -0
- crackerjack/core/enhanced_container.py +583 -0
- crackerjack/core/file_lifecycle.py +472 -0
- crackerjack/core/performance.py +244 -0
- crackerjack/core/performance_monitor.py +357 -0
- crackerjack/core/phase_coordinator.py +1227 -0
- crackerjack/core/proactive_workflow.py +267 -0
- crackerjack/core/resource_manager.py +425 -0
- crackerjack/core/retry.py +275 -0
- crackerjack/core/service_watchdog.py +601 -0
- crackerjack/core/session_coordinator.py +239 -0
- crackerjack/core/timeout_manager.py +563 -0
- crackerjack/core/websocket_lifecycle.py +410 -0
- crackerjack/core/workflow/__init__.py +21 -0
- crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
- crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
- crackerjack/core/workflow/workflow_issue_parser.py +714 -0
- crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
- crackerjack/core/workflow/workflow_security_gates.py +400 -0
- crackerjack/core/workflow_orchestrator.py +2243 -0
- crackerjack/data/README.md +11 -0
- crackerjack/data/__init__.py +8 -0
- crackerjack/data/models.py +79 -0
- crackerjack/data/repository.py +210 -0
- crackerjack/decorators/README.md +180 -0
- crackerjack/decorators/__init__.py +35 -0
- crackerjack/decorators/error_handling.py +649 -0
- crackerjack/decorators/error_handling_decorators.py +334 -0
- crackerjack/decorators/helpers.py +58 -0
- crackerjack/decorators/patterns.py +281 -0
- crackerjack/decorators/utils.py +58 -0
- crackerjack/docs/INDEX.md +11 -0
- crackerjack/docs/README.md +11 -0
- crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
- crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
- crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
- crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
- crackerjack/docs/generated/api/SERVICES.md +1252 -0
- crackerjack/documentation/README.md +11 -0
- crackerjack/documentation/__init__.py +31 -0
- crackerjack/documentation/ai_templates.py +756 -0
- crackerjack/documentation/dual_output_generator.py +767 -0
- crackerjack/documentation/mkdocs_integration.py +518 -0
- crackerjack/documentation/reference_generator.py +1065 -0
- crackerjack/dynamic_config.py +678 -0
- crackerjack/errors.py +378 -0
- crackerjack/events/README.md +11 -0
- crackerjack/events/__init__.py +16 -0
- crackerjack/events/telemetry.py +175 -0
- crackerjack/events/workflow_bus.py +346 -0
- crackerjack/exceptions/README.md +301 -0
- crackerjack/exceptions/__init__.py +5 -0
- crackerjack/exceptions/config.py +4 -0
- crackerjack/exceptions/tool_execution_error.py +245 -0
- crackerjack/executors/README.md +591 -0
- crackerjack/executors/__init__.py +13 -0
- crackerjack/executors/async_hook_executor.py +938 -0
- crackerjack/executors/cached_hook_executor.py +316 -0
- crackerjack/executors/hook_executor.py +1295 -0
- crackerjack/executors/hook_lock_manager.py +708 -0
- crackerjack/executors/individual_hook_executor.py +739 -0
- crackerjack/executors/lsp_aware_hook_executor.py +349 -0
- crackerjack/executors/progress_hook_executor.py +282 -0
- crackerjack/executors/tool_proxy.py +433 -0
- crackerjack/hooks/README.md +485 -0
- crackerjack/hooks/lsp_hook.py +93 -0
- crackerjack/intelligence/README.md +557 -0
- crackerjack/intelligence/__init__.py +37 -0
- crackerjack/intelligence/adaptive_learning.py +693 -0
- crackerjack/intelligence/agent_orchestrator.py +485 -0
- crackerjack/intelligence/agent_registry.py +377 -0
- crackerjack/intelligence/agent_selector.py +439 -0
- crackerjack/intelligence/integration.py +250 -0
- crackerjack/interactive.py +719 -0
- crackerjack/managers/README.md +369 -0
- crackerjack/managers/__init__.py +11 -0
- crackerjack/managers/async_hook_manager.py +135 -0
- crackerjack/managers/hook_manager.py +585 -0
- crackerjack/managers/publish_manager.py +631 -0
- crackerjack/managers/test_command_builder.py +391 -0
- crackerjack/managers/test_executor.py +474 -0
- crackerjack/managers/test_manager.py +1357 -0
- crackerjack/managers/test_progress.py +187 -0
- crackerjack/mcp/README.md +374 -0
- crackerjack/mcp/__init__.py +0 -0
- crackerjack/mcp/cache.py +352 -0
- crackerjack/mcp/client_runner.py +121 -0
- crackerjack/mcp/context.py +802 -0
- crackerjack/mcp/dashboard.py +657 -0
- crackerjack/mcp/enhanced_progress_monitor.py +493 -0
- crackerjack/mcp/file_monitor.py +394 -0
- crackerjack/mcp/progress_components.py +607 -0
- crackerjack/mcp/progress_monitor.py +1016 -0
- crackerjack/mcp/rate_limiter.py +336 -0
- crackerjack/mcp/server.py +24 -0
- crackerjack/mcp/server_core.py +526 -0
- crackerjack/mcp/service_watchdog.py +505 -0
- crackerjack/mcp/state.py +407 -0
- crackerjack/mcp/task_manager.py +259 -0
- crackerjack/mcp/tools/README.md +27 -0
- crackerjack/mcp/tools/__init__.py +19 -0
- crackerjack/mcp/tools/core_tools.py +469 -0
- crackerjack/mcp/tools/error_analyzer.py +283 -0
- crackerjack/mcp/tools/execution_tools.py +384 -0
- crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
- crackerjack/mcp/tools/intelligence_tools.py +264 -0
- crackerjack/mcp/tools/monitoring_tools.py +628 -0
- crackerjack/mcp/tools/proactive_tools.py +367 -0
- crackerjack/mcp/tools/progress_tools.py +222 -0
- crackerjack/mcp/tools/semantic_tools.py +584 -0
- crackerjack/mcp/tools/utility_tools.py +358 -0
- crackerjack/mcp/tools/workflow_executor.py +699 -0
- crackerjack/mcp/websocket/README.md +31 -0
- crackerjack/mcp/websocket/__init__.py +14 -0
- crackerjack/mcp/websocket/app.py +54 -0
- crackerjack/mcp/websocket/endpoints.py +492 -0
- crackerjack/mcp/websocket/event_bridge.py +188 -0
- crackerjack/mcp/websocket/jobs.py +406 -0
- crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
- crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
- crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
- crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
- crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
- crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
- crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
- crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
- crackerjack/mcp/websocket/monitoring/factory.py +109 -0
- crackerjack/mcp/websocket/monitoring/filters.py +10 -0
- crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
- crackerjack/mcp/websocket/monitoring/models.py +90 -0
- crackerjack/mcp/websocket/monitoring/utils.py +171 -0
- crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
- crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
- crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
- crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
- crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
- crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
- crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
- crackerjack/mcp/websocket/server.py +174 -0
- crackerjack/mcp/websocket/websocket_handler.py +276 -0
- crackerjack/mcp/websocket_server.py +10 -0
- crackerjack/models/README.md +308 -0
- crackerjack/models/__init__.py +40 -0
- crackerjack/models/config.py +730 -0
- crackerjack/models/config_adapter.py +265 -0
- crackerjack/models/protocols.py +1535 -0
- crackerjack/models/pydantic_models.py +320 -0
- crackerjack/models/qa_config.py +145 -0
- crackerjack/models/qa_results.py +134 -0
- crackerjack/models/resource_protocols.py +299 -0
- crackerjack/models/results.py +35 -0
- crackerjack/models/semantic_models.py +258 -0
- crackerjack/models/task.py +173 -0
- crackerjack/models/test_models.py +60 -0
- crackerjack/monitoring/README.md +11 -0
- crackerjack/monitoring/__init__.py +0 -0
- crackerjack/monitoring/ai_agent_watchdog.py +405 -0
- crackerjack/monitoring/metrics_collector.py +427 -0
- crackerjack/monitoring/regression_prevention.py +580 -0
- crackerjack/monitoring/websocket_server.py +406 -0
- crackerjack/orchestration/README.md +340 -0
- crackerjack/orchestration/__init__.py +43 -0
- crackerjack/orchestration/advanced_orchestrator.py +894 -0
- crackerjack/orchestration/cache/README.md +312 -0
- crackerjack/orchestration/cache/__init__.py +37 -0
- crackerjack/orchestration/cache/memory_cache.py +338 -0
- crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
- crackerjack/orchestration/config.py +297 -0
- crackerjack/orchestration/coverage_improvement.py +180 -0
- crackerjack/orchestration/execution_strategies.py +361 -0
- crackerjack/orchestration/hook_orchestrator.py +1398 -0
- crackerjack/orchestration/strategies/README.md +401 -0
- crackerjack/orchestration/strategies/__init__.py +39 -0
- crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
- crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
- crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
- crackerjack/orchestration/test_progress_streamer.py +647 -0
- crackerjack/plugins/README.md +11 -0
- crackerjack/plugins/__init__.py +15 -0
- crackerjack/plugins/base.py +200 -0
- crackerjack/plugins/hooks.py +254 -0
- crackerjack/plugins/loader.py +335 -0
- crackerjack/plugins/managers.py +264 -0
- crackerjack/py313.py +191 -0
- crackerjack/security/README.md +11 -0
- crackerjack/security/__init__.py +0 -0
- crackerjack/security/audit.py +197 -0
- crackerjack/services/README.md +374 -0
- crackerjack/services/__init__.py +9 -0
- crackerjack/services/ai/README.md +295 -0
- crackerjack/services/ai/__init__.py +7 -0
- crackerjack/services/ai/advanced_optimizer.py +878 -0
- crackerjack/services/ai/contextual_ai_assistant.py +542 -0
- crackerjack/services/ai/embeddings.py +444 -0
- crackerjack/services/ai/intelligent_commit.py +328 -0
- crackerjack/services/ai/predictive_analytics.py +510 -0
- crackerjack/services/anomaly_detector.py +392 -0
- crackerjack/services/api_extractor.py +617 -0
- crackerjack/services/backup_service.py +467 -0
- crackerjack/services/bounded_status_operations.py +530 -0
- crackerjack/services/cache.py +369 -0
- crackerjack/services/changelog_automation.py +399 -0
- crackerjack/services/command_execution_service.py +305 -0
- crackerjack/services/config_integrity.py +132 -0
- crackerjack/services/config_merge.py +546 -0
- crackerjack/services/config_service.py +198 -0
- crackerjack/services/config_template.py +493 -0
- crackerjack/services/coverage_badge_service.py +173 -0
- crackerjack/services/coverage_ratchet.py +381 -0
- crackerjack/services/debug.py +733 -0
- crackerjack/services/dependency_analyzer.py +460 -0
- crackerjack/services/dependency_monitor.py +622 -0
- crackerjack/services/documentation_generator.py +493 -0
- crackerjack/services/documentation_service.py +704 -0
- crackerjack/services/enhanced_filesystem.py +497 -0
- crackerjack/services/enterprise_optimizer.py +865 -0
- crackerjack/services/error_pattern_analyzer.py +676 -0
- crackerjack/services/file_filter.py +221 -0
- crackerjack/services/file_hasher.py +149 -0
- crackerjack/services/file_io_service.py +361 -0
- crackerjack/services/file_modifier.py +615 -0
- crackerjack/services/filesystem.py +381 -0
- crackerjack/services/git.py +422 -0
- crackerjack/services/health_metrics.py +615 -0
- crackerjack/services/heatmap_generator.py +744 -0
- crackerjack/services/incremental_executor.py +380 -0
- crackerjack/services/initialization.py +823 -0
- crackerjack/services/input_validator.py +668 -0
- crackerjack/services/intelligent_commit.py +327 -0
- crackerjack/services/log_manager.py +289 -0
- crackerjack/services/logging.py +228 -0
- crackerjack/services/lsp_client.py +628 -0
- crackerjack/services/memory_optimizer.py +414 -0
- crackerjack/services/metrics.py +587 -0
- crackerjack/services/monitoring/README.md +30 -0
- crackerjack/services/monitoring/__init__.py +9 -0
- crackerjack/services/monitoring/dependency_monitor.py +678 -0
- crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
- crackerjack/services/monitoring/health_metrics.py +716 -0
- crackerjack/services/monitoring/metrics.py +587 -0
- crackerjack/services/monitoring/performance_benchmarks.py +410 -0
- crackerjack/services/monitoring/performance_cache.py +388 -0
- crackerjack/services/monitoring/performance_monitor.py +569 -0
- crackerjack/services/parallel_executor.py +527 -0
- crackerjack/services/pattern_cache.py +333 -0
- crackerjack/services/pattern_detector.py +478 -0
- crackerjack/services/patterns/__init__.py +142 -0
- crackerjack/services/patterns/agents.py +107 -0
- crackerjack/services/patterns/code/__init__.py +15 -0
- crackerjack/services/patterns/code/detection.py +118 -0
- crackerjack/services/patterns/code/imports.py +107 -0
- crackerjack/services/patterns/code/paths.py +159 -0
- crackerjack/services/patterns/code/performance.py +119 -0
- crackerjack/services/patterns/code/replacement.py +36 -0
- crackerjack/services/patterns/core.py +212 -0
- crackerjack/services/patterns/documentation/__init__.py +14 -0
- crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
- crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
- crackerjack/services/patterns/documentation/docstrings.py +89 -0
- crackerjack/services/patterns/formatting.py +226 -0
- crackerjack/services/patterns/operations.py +339 -0
- crackerjack/services/patterns/security/__init__.py +23 -0
- crackerjack/services/patterns/security/code_injection.py +122 -0
- crackerjack/services/patterns/security/credentials.py +190 -0
- crackerjack/services/patterns/security/path_traversal.py +221 -0
- crackerjack/services/patterns/security/unsafe_operations.py +216 -0
- crackerjack/services/patterns/templates.py +62 -0
- crackerjack/services/patterns/testing/__init__.py +18 -0
- crackerjack/services/patterns/testing/error_patterns.py +107 -0
- crackerjack/services/patterns/testing/pytest_output.py +126 -0
- crackerjack/services/patterns/tool_output/__init__.py +16 -0
- crackerjack/services/patterns/tool_output/bandit.py +72 -0
- crackerjack/services/patterns/tool_output/other.py +97 -0
- crackerjack/services/patterns/tool_output/pyright.py +67 -0
- crackerjack/services/patterns/tool_output/ruff.py +44 -0
- crackerjack/services/patterns/url_sanitization.py +114 -0
- crackerjack/services/patterns/utilities.py +42 -0
- crackerjack/services/patterns/utils.py +339 -0
- crackerjack/services/patterns/validation.py +46 -0
- crackerjack/services/patterns/versioning.py +62 -0
- crackerjack/services/predictive_analytics.py +523 -0
- crackerjack/services/profiler.py +280 -0
- crackerjack/services/quality/README.md +415 -0
- crackerjack/services/quality/__init__.py +11 -0
- crackerjack/services/quality/anomaly_detector.py +392 -0
- crackerjack/services/quality/pattern_cache.py +333 -0
- crackerjack/services/quality/pattern_detector.py +479 -0
- crackerjack/services/quality/qa_orchestrator.py +491 -0
- crackerjack/services/quality/quality_baseline.py +395 -0
- crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
- crackerjack/services/quality/quality_intelligence.py +949 -0
- crackerjack/services/regex_patterns.py +58 -0
- crackerjack/services/regex_utils.py +483 -0
- crackerjack/services/secure_path_utils.py +524 -0
- crackerjack/services/secure_status_formatter.py +450 -0
- crackerjack/services/secure_subprocess.py +635 -0
- crackerjack/services/security.py +239 -0
- crackerjack/services/security_logger.py +495 -0
- crackerjack/services/server_manager.py +411 -0
- crackerjack/services/smart_scheduling.py +167 -0
- crackerjack/services/status_authentication.py +460 -0
- crackerjack/services/status_security_manager.py +315 -0
- crackerjack/services/terminal_utils.py +0 -0
- crackerjack/services/thread_safe_status_collector.py +441 -0
- crackerjack/services/tool_filter.py +368 -0
- crackerjack/services/tool_version_service.py +43 -0
- crackerjack/services/unified_config.py +115 -0
- crackerjack/services/validation_rate_limiter.py +220 -0
- crackerjack/services/vector_store.py +689 -0
- crackerjack/services/version_analyzer.py +461 -0
- crackerjack/services/version_checker.py +223 -0
- crackerjack/services/websocket_resource_limiter.py +438 -0
- crackerjack/services/zuban_lsp_service.py +391 -0
- crackerjack/slash_commands/README.md +11 -0
- crackerjack/slash_commands/__init__.py +59 -0
- crackerjack/slash_commands/init.md +112 -0
- crackerjack/slash_commands/run.md +197 -0
- crackerjack/slash_commands/status.md +127 -0
- crackerjack/tools/README.md +11 -0
- crackerjack/tools/__init__.py +30 -0
- crackerjack/tools/_git_utils.py +105 -0
- crackerjack/tools/check_added_large_files.py +139 -0
- crackerjack/tools/check_ast.py +105 -0
- crackerjack/tools/check_json.py +103 -0
- crackerjack/tools/check_jsonschema.py +297 -0
- crackerjack/tools/check_toml.py +103 -0
- crackerjack/tools/check_yaml.py +110 -0
- crackerjack/tools/codespell_wrapper.py +72 -0
- crackerjack/tools/end_of_file_fixer.py +202 -0
- crackerjack/tools/format_json.py +128 -0
- crackerjack/tools/mdformat_wrapper.py +114 -0
- crackerjack/tools/trailing_whitespace.py +198 -0
- crackerjack/tools/validate_input_validator_patterns.py +236 -0
- crackerjack/tools/validate_regex_patterns.py +188 -0
- crackerjack/ui/README.md +11 -0
- crackerjack/ui/__init__.py +1 -0
- crackerjack/ui/dashboard_renderer.py +28 -0
- crackerjack/ui/templates/README.md +11 -0
- crackerjack/utils/console_utils.py +13 -0
- crackerjack/utils/dependency_guard.py +230 -0
- crackerjack/utils/retry_utils.py +275 -0
- crackerjack/workflows/README.md +590 -0
- crackerjack/workflows/__init__.py +46 -0
- crackerjack/workflows/actions.py +811 -0
- crackerjack/workflows/auto_fix.py +444 -0
- crackerjack/workflows/container_builder.py +499 -0
- crackerjack/workflows/definitions.py +443 -0
- crackerjack/workflows/engine.py +177 -0
- crackerjack/workflows/event_bridge.py +242 -0
- crackerjack-0.45.2.dist-info/METADATA +1678 -0
- crackerjack-0.45.2.dist-info/RECORD +478 -0
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
- crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
- crackerjack/.gitignore +0 -14
- crackerjack/.libcst.codemod.yaml +0 -18
- crackerjack/.pdm.toml +0 -1
- crackerjack/.pre-commit-config.yaml +0 -91
- crackerjack/.pytest_cache/.gitignore +0 -2
- crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
- crackerjack/.pytest_cache/README.md +0 -8
- crackerjack/.pytest_cache/v/cache/nodeids +0 -1
- crackerjack/.pytest_cache/v/cache/stepwise +0 -1
- crackerjack/.ruff_cache/.gitignore +0 -1
- crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
- crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
- crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
- crackerjack/crackerjack.py +0 -855
- crackerjack/pyproject.toml +0 -214
- crackerjack-0.18.2.dist-info/METADATA +0 -420
- crackerjack-0.18.2.dist-info/RECORD +0 -59
- crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from acb.console import Console
|
|
5
|
+
from acb.depends import depends
|
|
6
|
+
from acb.logger import Logger
|
|
7
|
+
|
|
8
|
+
# Import protocols for service registration
|
|
9
|
+
from crackerjack.models.protocols import (
|
|
10
|
+
ChangelogGeneratorProtocol,
|
|
11
|
+
CoverageBadgeServiceProtocol,
|
|
12
|
+
CoverageRatchetProtocol,
|
|
13
|
+
DebugServiceProtocol,
|
|
14
|
+
GitServiceProtocol,
|
|
15
|
+
LoggerProtocol,
|
|
16
|
+
MemoryOptimizerProtocol,
|
|
17
|
+
PerformanceBenchmarkProtocol,
|
|
18
|
+
PerformanceCacheProtocol,
|
|
19
|
+
PerformanceMonitorProtocol,
|
|
20
|
+
QualityBaselineProtocol,
|
|
21
|
+
QualityIntelligenceProtocol,
|
|
22
|
+
VersionAnalyzerProtocol,
|
|
23
|
+
)
|
|
24
|
+
from crackerjack.services.changelog_automation import ChangelogGenerator
|
|
25
|
+
from crackerjack.services.coverage_badge_service import CoverageBadgeService
|
|
26
|
+
from crackerjack.services.coverage_ratchet import CoverageRatchetService
|
|
27
|
+
|
|
28
|
+
# Import service implementations
|
|
29
|
+
from crackerjack.services.debug import get_ai_agent_debugger
|
|
30
|
+
from crackerjack.services.git import GitService
|
|
31
|
+
from crackerjack.services.lsp_client import LSPClient
|
|
32
|
+
from crackerjack.services.memory_optimizer import MemoryOptimizer
|
|
33
|
+
from crackerjack.services.monitoring.performance_benchmarks import (
|
|
34
|
+
PerformanceBenchmarkService,
|
|
35
|
+
)
|
|
36
|
+
from crackerjack.services.monitoring.performance_cache import (
|
|
37
|
+
FileSystemCache,
|
|
38
|
+
GitOperationCache,
|
|
39
|
+
get_filesystem_cache,
|
|
40
|
+
get_git_cache,
|
|
41
|
+
get_performance_cache,
|
|
42
|
+
)
|
|
43
|
+
from crackerjack.services.monitoring.performance_monitor import get_performance_monitor
|
|
44
|
+
from crackerjack.services.parallel_executor import (
|
|
45
|
+
AsyncCommandExecutor,
|
|
46
|
+
ParallelHookExecutor,
|
|
47
|
+
get_async_executor,
|
|
48
|
+
get_parallel_executor,
|
|
49
|
+
)
|
|
50
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
51
|
+
EnhancedQualityBaselineService,
|
|
52
|
+
)
|
|
53
|
+
from crackerjack.services.quality.quality_intelligence import (
|
|
54
|
+
QualityIntelligenceService,
|
|
55
|
+
)
|
|
56
|
+
from crackerjack.services.version_analyzer import VersionAnalyzer
|
|
57
|
+
|
|
58
|
+
from .hooks import (
|
|
59
|
+
COMPREHENSIVE_STRATEGY,
|
|
60
|
+
FAST_STRATEGY,
|
|
61
|
+
HookConfigLoader,
|
|
62
|
+
HookDefinition,
|
|
63
|
+
HookStage,
|
|
64
|
+
HookStrategy,
|
|
65
|
+
RetryPolicy,
|
|
66
|
+
)
|
|
67
|
+
from .loader import load_settings, load_settings_async
|
|
68
|
+
from .settings import CrackerjackSettings
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_console_width() -> int:
|
|
72
|
+
"""Return the preferred console width from settings or pyproject.
|
|
73
|
+
|
|
74
|
+
Priority:
|
|
75
|
+
1) ACB settings (CrackerjackSettings.console.width)
|
|
76
|
+
2) pyproject.toml [tool.crackerjack].terminal_width
|
|
77
|
+
3) Default: 70
|
|
78
|
+
"""
|
|
79
|
+
# 1) Try ACB settings via DI
|
|
80
|
+
with suppress(Exception):
|
|
81
|
+
settings = depends.get_sync(CrackerjackSettings)
|
|
82
|
+
width = getattr(getattr(settings, "console", None), "width", None)
|
|
83
|
+
if isinstance(width, int) and width > 0:
|
|
84
|
+
return width
|
|
85
|
+
|
|
86
|
+
# 2) Try pyproject.toml
|
|
87
|
+
with suppress(Exception):
|
|
88
|
+
from pathlib import Path as _P
|
|
89
|
+
|
|
90
|
+
import tomli
|
|
91
|
+
|
|
92
|
+
pyproj = _P("pyproject.toml")
|
|
93
|
+
if pyproj.exists():
|
|
94
|
+
with pyproj.open("rb") as f:
|
|
95
|
+
data = tomli.load(f)
|
|
96
|
+
width = (
|
|
97
|
+
data.get("tool", {}).get("crackerjack", {}).get("terminal_width", None)
|
|
98
|
+
)
|
|
99
|
+
if isinstance(width, int) and width > 0:
|
|
100
|
+
return width
|
|
101
|
+
|
|
102
|
+
# 3) Default
|
|
103
|
+
return 70
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# Load settings from YAML files using layered configuration
|
|
107
|
+
settings_instance = load_settings(CrackerjackSettings)
|
|
108
|
+
depends.set(CrackerjackSettings, settings_instance)
|
|
109
|
+
|
|
110
|
+
# Register ACB Logger (auto-registers itself, but set explicitly for clarity)
|
|
111
|
+
# But first, ensure we don't have an empty tuple registered for Logger
|
|
112
|
+
from crackerjack.utils.dependency_guard import (
|
|
113
|
+
ensure_logger_dependency,
|
|
114
|
+
validate_dependency_registration,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
ensure_logger_dependency()
|
|
118
|
+
|
|
119
|
+
# Explicitly set logger instances if not already set properly
|
|
120
|
+
try:
|
|
121
|
+
current_logger = depends.get_sync(Logger)
|
|
122
|
+
if isinstance(current_logger, tuple) and len(current_logger) == 0:
|
|
123
|
+
logger_instance = Logger()
|
|
124
|
+
depends.set(Logger, logger_instance)
|
|
125
|
+
depends.set(LoggerProtocol, logger_instance) # Also register as LoggerProtocol
|
|
126
|
+
else:
|
|
127
|
+
# Logger is already properly registered, just ensure LoggerProtocol is too
|
|
128
|
+
depends.set(LoggerProtocol, current_logger)
|
|
129
|
+
except Exception:
|
|
130
|
+
# Logger not registered at all, so register it
|
|
131
|
+
logger_instance = Logger()
|
|
132
|
+
depends.set(Logger, logger_instance)
|
|
133
|
+
depends.set(LoggerProtocol, logger_instance) # Also register as LoggerProtocol
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def register_services() -> None:
|
|
137
|
+
"""Register all service instances with ACB dependency injection system.
|
|
138
|
+
|
|
139
|
+
Services are registered at application initialization to ensure proper
|
|
140
|
+
dependency ordering and lifecycle management. This follows ACB's pattern
|
|
141
|
+
of centralizing service registration rather than having services register
|
|
142
|
+
themselves or be instantiated in consumers.
|
|
143
|
+
|
|
144
|
+
The order of registration is important to ensure that dependencies are met:
|
|
145
|
+
1. Core utility services (Debug, Performance Monitoring, Memory, Caching)
|
|
146
|
+
2. Specialized cache services (Git, Filesystem)
|
|
147
|
+
3. Quality-related services (Baseline, Intelligence)
|
|
148
|
+
4. Manager-layer services (Coverage, Git, Versioning, Changelog, LSP)
|
|
149
|
+
"""
|
|
150
|
+
# 1. Register Debug Service
|
|
151
|
+
# Uses factory function to handle environment detection
|
|
152
|
+
debugger = get_ai_agent_debugger()
|
|
153
|
+
depends.set(DebugServiceProtocol, debugger)
|
|
154
|
+
|
|
155
|
+
# 2. Register Performance Monitor
|
|
156
|
+
# Core performance tracking service
|
|
157
|
+
performance_monitor = get_performance_monitor()
|
|
158
|
+
depends.set(PerformanceMonitorProtocol, performance_monitor)
|
|
159
|
+
|
|
160
|
+
# 3. Register Memory Optimizer
|
|
161
|
+
# Memory management and optimization
|
|
162
|
+
memory_optimizer = MemoryOptimizer.get_instance()
|
|
163
|
+
depends.set(MemoryOptimizerProtocol, memory_optimizer)
|
|
164
|
+
|
|
165
|
+
# 4. Register Performance Cache
|
|
166
|
+
# Caching layer for performance optimization
|
|
167
|
+
performance_cache = get_performance_cache()
|
|
168
|
+
depends.set(PerformanceCacheProtocol, performance_cache)
|
|
169
|
+
|
|
170
|
+
# 5. Register Performance Benchmark Service
|
|
171
|
+
# The service should be registered automatically via @depends.inject
|
|
172
|
+
# in the service implementation, but if not let's create and register it manually
|
|
173
|
+
try:
|
|
174
|
+
# First, try to get the already registered instance
|
|
175
|
+
try:
|
|
176
|
+
performance_benchmarks = depends.get_sync(PerformanceBenchmarkProtocol)
|
|
177
|
+
except Exception:
|
|
178
|
+
# If not registered, create it using proper DI
|
|
179
|
+
console = depends.get_sync(Console)
|
|
180
|
+
logger = depends.get_sync(
|
|
181
|
+
Logger
|
|
182
|
+
) # Get the logger instead of LoggerProtocol
|
|
183
|
+
pkg_path = Path.cwd() # Use current directory as fallback
|
|
184
|
+
performance_benchmarks = PerformanceBenchmarkService(
|
|
185
|
+
console=console, logger=logger, pkg_path=pkg_path
|
|
186
|
+
)
|
|
187
|
+
# Register the newly created instance
|
|
188
|
+
depends.set(PerformanceBenchmarkProtocol, performance_benchmarks)
|
|
189
|
+
except Exception as e:
|
|
190
|
+
# Log the error to help with debugging
|
|
191
|
+
print(f"WARNING: Failed to register PerformanceBenchmarkService: {e}")
|
|
192
|
+
# Performance benchmarking will be disabled
|
|
193
|
+
pass
|
|
194
|
+
|
|
195
|
+
# 6. Register Parallel Executor Services
|
|
196
|
+
# For parallel and async hook execution
|
|
197
|
+
parallel_executor = get_parallel_executor()
|
|
198
|
+
depends.set(ParallelHookExecutor, parallel_executor)
|
|
199
|
+
|
|
200
|
+
async_executor = get_async_executor()
|
|
201
|
+
depends.set(AsyncCommandExecutor, async_executor)
|
|
202
|
+
|
|
203
|
+
# 7. Register Specialized Cache Services
|
|
204
|
+
# Git and filesystem caching
|
|
205
|
+
git_cache = get_git_cache()
|
|
206
|
+
depends.set(GitOperationCache, git_cache)
|
|
207
|
+
|
|
208
|
+
filesystem_cache = get_filesystem_cache()
|
|
209
|
+
depends.set(FileSystemCache, filesystem_cache)
|
|
210
|
+
|
|
211
|
+
# 8. Register Quality Baseline Service
|
|
212
|
+
# Foundation for quality tracking and intelligence
|
|
213
|
+
with suppress(Exception):
|
|
214
|
+
quality_baseline = EnhancedQualityBaselineService()
|
|
215
|
+
depends.set(QualityBaselineProtocol, quality_baseline)
|
|
216
|
+
|
|
217
|
+
# 9. Register Quality Intelligence Service
|
|
218
|
+
# Depends on quality baseline service
|
|
219
|
+
quality_intelligence = QualityIntelligenceService(quality_baseline)
|
|
220
|
+
depends.set(QualityIntelligenceProtocol, quality_intelligence)
|
|
221
|
+
|
|
222
|
+
# 10. Register Manager Layer Services
|
|
223
|
+
# Services used by test_manager.py and publish_manager.py
|
|
224
|
+
|
|
225
|
+
# Get console and pkg_path for service initialization
|
|
226
|
+
with suppress(Exception):
|
|
227
|
+
console = depends.get_sync(Console)
|
|
228
|
+
pkg_path = depends.get_sync(Path)
|
|
229
|
+
|
|
230
|
+
# 10a. Coverage Ratchet Service (protocol-based)
|
|
231
|
+
coverage_ratchet = CoverageRatchetService(pkg_path)
|
|
232
|
+
depends.set(CoverageRatchetProtocol, coverage_ratchet)
|
|
233
|
+
|
|
234
|
+
# 10b. Coverage Badge Service (protocol-based)
|
|
235
|
+
coverage_badge = depends.inject_sync(
|
|
236
|
+
CoverageBadgeService, console=console, project_root=pkg_path
|
|
237
|
+
)
|
|
238
|
+
depends.set(CoverageBadgeServiceProtocol, coverage_badge)
|
|
239
|
+
|
|
240
|
+
# 10c. Git Service (protocol-based, foundation for dependent services)
|
|
241
|
+
git_service = GitService(pkg_path)
|
|
242
|
+
depends.set(GitServiceProtocol, git_service)
|
|
243
|
+
|
|
244
|
+
# 10d. Version Analyzer (protocol-based, depends on git_service)
|
|
245
|
+
version_analyzer = VersionAnalyzer(git_service)
|
|
246
|
+
depends.set(VersionAnalyzerProtocol, version_analyzer)
|
|
247
|
+
|
|
248
|
+
# 10e. Changelog Generator (protocol-based, ACB DI injects dependencies)
|
|
249
|
+
changelog_generator = ChangelogGenerator()
|
|
250
|
+
depends.set(ChangelogGeneratorProtocol, changelog_generator)
|
|
251
|
+
|
|
252
|
+
# 10f. LSP Client (concrete type - optional service with graceful fallback)
|
|
253
|
+
with suppress(Exception):
|
|
254
|
+
lsp_client = LSPClient()
|
|
255
|
+
depends.set(LSPClient, lsp_client)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
# Service registration is called explicitly by application entry point
|
|
259
|
+
# to avoid circular import issues during module initialization.
|
|
260
|
+
# Call register_services() after all modules are loaded, typically in __main__.py
|
|
261
|
+
|
|
262
|
+
__all__ = [
|
|
263
|
+
"COMPREHENSIVE_STRATEGY",
|
|
264
|
+
"FAST_STRATEGY",
|
|
265
|
+
"HookConfigLoader",
|
|
266
|
+
"HookDefinition",
|
|
267
|
+
"HookStage",
|
|
268
|
+
"HookStrategy",
|
|
269
|
+
"RetryPolicy",
|
|
270
|
+
"CrackerjackSettings",
|
|
271
|
+
"load_settings",
|
|
272
|
+
"load_settings_async",
|
|
273
|
+
"register_services",
|
|
274
|
+
"get_console_width",
|
|
275
|
+
]
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import socket
|
|
4
|
+
import typing as t
|
|
5
|
+
from contextlib import suppress
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from acb.depends import depends
|
|
9
|
+
|
|
10
|
+
from crackerjack.config.settings import CrackerjackSettings, GlobalLockSettings
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GlobalLockConfig:
|
|
14
|
+
"""Compatibility wrapper for global lock settings.
|
|
15
|
+
|
|
16
|
+
Supports both APIs:
|
|
17
|
+
- New API: GlobalLockConfig(settings=GlobalLockSettings(...))
|
|
18
|
+
- Old API: GlobalLockConfig(lock_directory=path, timeout_seconds=600, ...)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def _should_build_from_compatibility_params(
|
|
22
|
+
self,
|
|
23
|
+
enabled: bool | None,
|
|
24
|
+
timeout_seconds: float | None,
|
|
25
|
+
stale_lock_hours: float | None,
|
|
26
|
+
lock_directory: Path | None,
|
|
27
|
+
session_heartbeat_interval: float | None,
|
|
28
|
+
max_retry_attempts: int | None,
|
|
29
|
+
retry_delay_seconds: float | None,
|
|
30
|
+
enable_lock_monitoring: bool | None,
|
|
31
|
+
) -> bool:
|
|
32
|
+
"""Check if any backwards compatibility parameters are provided."""
|
|
33
|
+
return any(
|
|
34
|
+
param is not None
|
|
35
|
+
for param in (
|
|
36
|
+
enabled,
|
|
37
|
+
timeout_seconds,
|
|
38
|
+
stale_lock_hours,
|
|
39
|
+
lock_directory,
|
|
40
|
+
session_heartbeat_interval,
|
|
41
|
+
max_retry_attempts,
|
|
42
|
+
retry_delay_seconds,
|
|
43
|
+
enable_lock_monitoring,
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def _build_settings_from_compatibility_params(
|
|
48
|
+
self,
|
|
49
|
+
enabled: bool | None,
|
|
50
|
+
timeout_seconds: float | None,
|
|
51
|
+
stale_lock_hours: float | None,
|
|
52
|
+
lock_directory: Path | None,
|
|
53
|
+
session_heartbeat_interval: float | None,
|
|
54
|
+
max_retry_attempts: int | None,
|
|
55
|
+
retry_delay_seconds: float | None,
|
|
56
|
+
enable_lock_monitoring: bool | None,
|
|
57
|
+
) -> GlobalLockSettings:
|
|
58
|
+
"""Build settings from backwards compatibility parameters."""
|
|
59
|
+
# Get defaults from CrackerjackSettings
|
|
60
|
+
default_settings = depends.get_sync(CrackerjackSettings).global_lock
|
|
61
|
+
# Create a copy with overrides
|
|
62
|
+
settings_dict = {
|
|
63
|
+
"enabled": enabled if enabled is not None else default_settings.enabled,
|
|
64
|
+
"timeout_seconds": (
|
|
65
|
+
timeout_seconds
|
|
66
|
+
if timeout_seconds is not None
|
|
67
|
+
else default_settings.timeout_seconds
|
|
68
|
+
),
|
|
69
|
+
"stale_lock_hours": (
|
|
70
|
+
stale_lock_hours
|
|
71
|
+
if stale_lock_hours is not None
|
|
72
|
+
else default_settings.stale_lock_hours
|
|
73
|
+
),
|
|
74
|
+
"lock_directory": (
|
|
75
|
+
lock_directory
|
|
76
|
+
if lock_directory is not None
|
|
77
|
+
else default_settings.lock_directory
|
|
78
|
+
),
|
|
79
|
+
"session_heartbeat_interval": (
|
|
80
|
+
session_heartbeat_interval
|
|
81
|
+
if session_heartbeat_interval is not None
|
|
82
|
+
else default_settings.session_heartbeat_interval
|
|
83
|
+
),
|
|
84
|
+
"max_retry_attempts": (
|
|
85
|
+
max_retry_attempts
|
|
86
|
+
if max_retry_attempts is not None
|
|
87
|
+
else default_settings.max_retry_attempts
|
|
88
|
+
),
|
|
89
|
+
"retry_delay_seconds": (
|
|
90
|
+
retry_delay_seconds
|
|
91
|
+
if retry_delay_seconds is not None
|
|
92
|
+
else default_settings.retry_delay_seconds
|
|
93
|
+
),
|
|
94
|
+
"enable_lock_monitoring": (
|
|
95
|
+
enable_lock_monitoring
|
|
96
|
+
if enable_lock_monitoring is not None
|
|
97
|
+
else default_settings.enable_lock_monitoring
|
|
98
|
+
),
|
|
99
|
+
}
|
|
100
|
+
return GlobalLockSettings(**settings_dict)
|
|
101
|
+
|
|
102
|
+
def __init__(
|
|
103
|
+
self,
|
|
104
|
+
settings: GlobalLockSettings | None = None,
|
|
105
|
+
# Backwards compatibility parameters
|
|
106
|
+
enabled: bool | None = None,
|
|
107
|
+
timeout_seconds: float | None = None,
|
|
108
|
+
stale_lock_hours: float | None = None,
|
|
109
|
+
lock_directory: Path | None = None,
|
|
110
|
+
session_heartbeat_interval: float | None = None,
|
|
111
|
+
max_retry_attempts: int | None = None,
|
|
112
|
+
retry_delay_seconds: float | None = None,
|
|
113
|
+
enable_lock_monitoring: bool | None = None,
|
|
114
|
+
) -> None:
|
|
115
|
+
# If any backwards compatibility parameters are provided, build settings from them
|
|
116
|
+
if self._should_build_from_compatibility_params(
|
|
117
|
+
enabled,
|
|
118
|
+
timeout_seconds,
|
|
119
|
+
stale_lock_hours,
|
|
120
|
+
lock_directory,
|
|
121
|
+
session_heartbeat_interval,
|
|
122
|
+
max_retry_attempts,
|
|
123
|
+
retry_delay_seconds,
|
|
124
|
+
enable_lock_monitoring,
|
|
125
|
+
):
|
|
126
|
+
settings = self._build_settings_from_compatibility_params(
|
|
127
|
+
enabled,
|
|
128
|
+
timeout_seconds,
|
|
129
|
+
stale_lock_hours,
|
|
130
|
+
lock_directory,
|
|
131
|
+
session_heartbeat_interval,
|
|
132
|
+
max_retry_attempts,
|
|
133
|
+
retry_delay_seconds,
|
|
134
|
+
enable_lock_monitoring,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
base_settings = settings or depends.get_sync(CrackerjackSettings).global_lock
|
|
138
|
+
self._settings = base_settings.model_copy()
|
|
139
|
+
self.session_id = (
|
|
140
|
+
getattr(self._settings, "session_id", None) or self._generate_session_id()
|
|
141
|
+
)
|
|
142
|
+
self.hostname = (
|
|
143
|
+
getattr(self._settings, "hostname", None) or socket.gethostname()
|
|
144
|
+
)
|
|
145
|
+
self._ensure_lock_directory()
|
|
146
|
+
|
|
147
|
+
@staticmethod
|
|
148
|
+
def _generate_session_id() -> str:
|
|
149
|
+
import uuid
|
|
150
|
+
|
|
151
|
+
return uuid.uuid4().hex[:8]
|
|
152
|
+
|
|
153
|
+
def _ensure_lock_directory(self) -> None:
|
|
154
|
+
lock_dir = self._settings.lock_directory
|
|
155
|
+
lock_dir.mkdir(parents=True, exist_ok=True)
|
|
156
|
+
# Enforce secure permissions (owner rwx only)
|
|
157
|
+
with suppress(Exception):
|
|
158
|
+
lock_dir.chmod(0o700)
|
|
159
|
+
|
|
160
|
+
def __getattr__(self, item: str):
|
|
161
|
+
return getattr(self._settings, item)
|
|
162
|
+
|
|
163
|
+
def get_lock_path(self, hook_name: str) -> Path:
|
|
164
|
+
safe_name = hook_name.replace("/", "_")
|
|
165
|
+
return self._settings.lock_directory / f"{safe_name}.lock"
|
|
166
|
+
|
|
167
|
+
@classmethod
|
|
168
|
+
def from_options(cls, options: t.Any) -> GlobalLockConfig:
|
|
169
|
+
"""Create GlobalLockConfig from CLI options object.
|
|
170
|
+
|
|
171
|
+
Supports two formats:
|
|
172
|
+
1. Nested: options.global_lock with GlobalLockSettings-like fields
|
|
173
|
+
2. Flat: options with global_lock_* prefixed fields (from CLI)
|
|
174
|
+
|
|
175
|
+
Synchronous method - no async operations needed.
|
|
176
|
+
"""
|
|
177
|
+
base_settings = depends.get_sync(CrackerjackSettings).global_lock
|
|
178
|
+
overrides = getattr(options, "global_lock", None)
|
|
179
|
+
|
|
180
|
+
# Handle nested global_lock object
|
|
181
|
+
if overrides is not None:
|
|
182
|
+
custom = base_settings.model_copy()
|
|
183
|
+
for field in custom.model_fields:
|
|
184
|
+
if hasattr(overrides, field):
|
|
185
|
+
setattr(custom, field, getattr(overrides, field))
|
|
186
|
+
return cls(custom)
|
|
187
|
+
|
|
188
|
+
# Handle flat CLI options with global_lock_* prefix
|
|
189
|
+
params: dict[str, t.Any] = {}
|
|
190
|
+
if hasattr(options, "disable_global_locks"):
|
|
191
|
+
params["enabled"] = not options.disable_global_locks
|
|
192
|
+
if hasattr(options, "global_lock_timeout"):
|
|
193
|
+
params["timeout_seconds"] = float(options.global_lock_timeout)
|
|
194
|
+
if hasattr(options, "global_lock_dir") and options.global_lock_dir:
|
|
195
|
+
params["lock_directory"] = Path(options.global_lock_dir)
|
|
196
|
+
# Note: global_lock_cleanup is handled at runtime, not in config
|
|
197
|
+
|
|
198
|
+
# If any options were provided, create config with them
|
|
199
|
+
if params:
|
|
200
|
+
return cls(**params)
|
|
201
|
+
|
|
202
|
+
# Otherwise use defaults
|
|
203
|
+
return cls(base_settings)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def get_global_lock_config() -> GlobalLockConfig:
|
|
207
|
+
return GlobalLockConfig()
|