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,516 @@
|
|
|
1
|
+
"""Ruff adapter for ACB QA framework - unified lint and format checking.
|
|
2
|
+
|
|
3
|
+
Ruff is a fast Python linter and formatter that combines the functionality
|
|
4
|
+
of multiple tools (Flake8, isort, Black, etc.) into a single executable.
|
|
5
|
+
|
|
6
|
+
This adapter handles both lint checking and formatting.
|
|
7
|
+
|
|
8
|
+
ACB Patterns:
|
|
9
|
+
- MODULE_ID and MODULE_STATUS at module level
|
|
10
|
+
- depends.set() registration after class definition
|
|
11
|
+
- Extends BaseToolAdapter for tool execution
|
|
12
|
+
- Async execution with JSON output parsing
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
import typing as t
|
|
19
|
+
from contextlib import suppress
|
|
20
|
+
from enum import StrEnum
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from uuid import UUID, uuid4
|
|
23
|
+
|
|
24
|
+
from acb.depends import depends
|
|
25
|
+
from pydantic import Field
|
|
26
|
+
|
|
27
|
+
from crackerjack.adapters._tool_adapter_base import (
|
|
28
|
+
BaseToolAdapter,
|
|
29
|
+
ToolAdapterSettings,
|
|
30
|
+
ToolExecutionResult,
|
|
31
|
+
ToolIssue,
|
|
32
|
+
)
|
|
33
|
+
from crackerjack.models.qa_results import QACheckType, QAResult, QAResultStatus
|
|
34
|
+
|
|
35
|
+
if t.TYPE_CHECKING:
|
|
36
|
+
from crackerjack.models.qa_config import QACheckConfig
|
|
37
|
+
|
|
38
|
+
# ACB Module Registration (REQUIRED)
|
|
39
|
+
MODULE_ID = uuid4()
|
|
40
|
+
MODULE_STATUS = "stable"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class RuffMode(StrEnum):
|
|
44
|
+
"""Ruff execution modes."""
|
|
45
|
+
|
|
46
|
+
CHECK = "check"
|
|
47
|
+
FORMAT = "format"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class RuffSettings(ToolAdapterSettings):
|
|
51
|
+
"""Settings for Ruff adapter.
|
|
52
|
+
|
|
53
|
+
Extends ToolAdapterSettings with Ruff-specific configuration.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
tool_name: str = "ruff"
|
|
57
|
+
mode: str = "check" # "check" or "format"
|
|
58
|
+
fix_enabled: bool = False
|
|
59
|
+
unsafe_fixes: bool = False # Enable unsafe auto-fixes for ruff check
|
|
60
|
+
select_rules: list[str] = Field(default_factory=list)
|
|
61
|
+
ignore_rules: list[str] = Field(default_factory=list)
|
|
62
|
+
line_length: int | None = None
|
|
63
|
+
use_json_output: bool = True # Ruff supports JSON output
|
|
64
|
+
respect_gitignore: bool = True
|
|
65
|
+
preview: bool = False # Enable preview rules
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class RuffAdapter(BaseToolAdapter):
|
|
69
|
+
"""Adapter for Ruff - fast Python linter and formatter.
|
|
70
|
+
|
|
71
|
+
Handles both linting and formatting operations:
|
|
72
|
+
- Lint mode: Checks code quality, style, and complexity
|
|
73
|
+
- Format mode: Reformats code to match style guidelines
|
|
74
|
+
|
|
75
|
+
Features:
|
|
76
|
+
- JSON output parsing for structured error reporting
|
|
77
|
+
- Auto-fix support for lint issues
|
|
78
|
+
- Configurable rule selection and line length
|
|
79
|
+
- Respects .gitignore by default
|
|
80
|
+
- Fast parallel execution
|
|
81
|
+
|
|
82
|
+
Example:
|
|
83
|
+
```python
|
|
84
|
+
# Lint mode with auto-fix
|
|
85
|
+
settings = RuffSettings(
|
|
86
|
+
mode="check",
|
|
87
|
+
fix_enabled=True,
|
|
88
|
+
select_rules=["E", "F", "I"],
|
|
89
|
+
ignore_rules=["E501"],
|
|
90
|
+
)
|
|
91
|
+
adapter = RuffAdapter(settings=settings)
|
|
92
|
+
await adapter.init()
|
|
93
|
+
result = await adapter.check(files=[Path("src/file.py")])
|
|
94
|
+
|
|
95
|
+
# Format mode
|
|
96
|
+
settings = RuffSettings(mode="format")
|
|
97
|
+
adapter = RuffAdapter(settings=settings)
|
|
98
|
+
await adapter.init()
|
|
99
|
+
result = await adapter.check(files=[Path("src/file.py")])
|
|
100
|
+
```
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
settings: RuffSettings | None = None
|
|
104
|
+
|
|
105
|
+
def __init__(self, settings: RuffSettings | None = None) -> None:
|
|
106
|
+
"""Initialize Ruff adapter.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
settings: Optional settings override
|
|
110
|
+
"""
|
|
111
|
+
super().__init__(settings=settings)
|
|
112
|
+
|
|
113
|
+
async def init(self) -> None:
|
|
114
|
+
"""Initialize adapter with default settings."""
|
|
115
|
+
if not self.settings:
|
|
116
|
+
self.settings = RuffSettings()
|
|
117
|
+
await super().init()
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def adapter_name(self) -> str:
|
|
121
|
+
"""Human-readable adapter name."""
|
|
122
|
+
if self.settings:
|
|
123
|
+
mode = self.settings.mode
|
|
124
|
+
return f"Ruff ({mode})"
|
|
125
|
+
return "Ruff"
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def module_id(self) -> UUID:
|
|
129
|
+
"""Reference to module-level MODULE_ID."""
|
|
130
|
+
return MODULE_ID
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def tool_name(self) -> str:
|
|
134
|
+
"""CLI tool name."""
|
|
135
|
+
return "ruff"
|
|
136
|
+
|
|
137
|
+
def build_command(
|
|
138
|
+
self,
|
|
139
|
+
files: list[Path],
|
|
140
|
+
config: QACheckConfig | None = None,
|
|
141
|
+
) -> list[str]:
|
|
142
|
+
"""Build Ruff command based on mode and settings.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
files: Files to check/format
|
|
146
|
+
config: Optional configuration override
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Command as list of strings
|
|
150
|
+
"""
|
|
151
|
+
if not self.settings:
|
|
152
|
+
raise RuntimeError("Settings not initialized")
|
|
153
|
+
|
|
154
|
+
cmd = [self.tool_name, self.settings.mode]
|
|
155
|
+
|
|
156
|
+
# Add mode-specific options
|
|
157
|
+
if self.settings.mode == "check":
|
|
158
|
+
self._add_check_mode_options(cmd)
|
|
159
|
+
elif self.settings.mode == "format":
|
|
160
|
+
self._add_format_mode_options(cmd)
|
|
161
|
+
|
|
162
|
+
# Add files
|
|
163
|
+
cmd.extend([str(f) for f in files])
|
|
164
|
+
|
|
165
|
+
# Respect gitignore
|
|
166
|
+
if self.settings.respect_gitignore:
|
|
167
|
+
cmd.append("--respect-gitignore")
|
|
168
|
+
|
|
169
|
+
return cmd
|
|
170
|
+
|
|
171
|
+
def _add_check_mode_options(self, cmd: list[str]) -> None:
|
|
172
|
+
"""Add lint mode specific options to command.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
cmd: Command list to append options to
|
|
176
|
+
"""
|
|
177
|
+
if not self.settings:
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
if self.settings.fix_enabled:
|
|
181
|
+
cmd.append("--fix")
|
|
182
|
+
|
|
183
|
+
# Add unsafe-fixes flag when enabled (requires --fix)
|
|
184
|
+
if self.settings.unsafe_fixes:
|
|
185
|
+
cmd.append("--unsafe-fixes")
|
|
186
|
+
|
|
187
|
+
if self.settings.use_json_output:
|
|
188
|
+
cmd.extend(["--output-format", "json"])
|
|
189
|
+
|
|
190
|
+
if self.settings.select_rules:
|
|
191
|
+
cmd.extend(["--select", ",".join(self.settings.select_rules)])
|
|
192
|
+
|
|
193
|
+
if self.settings.ignore_rules:
|
|
194
|
+
cmd.extend(["--ignore", ",".join(self.settings.ignore_rules)])
|
|
195
|
+
|
|
196
|
+
if self.settings.preview:
|
|
197
|
+
cmd.append("--preview")
|
|
198
|
+
|
|
199
|
+
def _add_format_mode_options(self, cmd: list[str]) -> None:
|
|
200
|
+
"""Add format mode specific options to command.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
cmd: Command list to append options to
|
|
204
|
+
"""
|
|
205
|
+
if not self.settings:
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
if self.settings.line_length:
|
|
209
|
+
cmd.extend(["--line-length", str(self.settings.line_length)])
|
|
210
|
+
|
|
211
|
+
if self.settings.preview:
|
|
212
|
+
cmd.append("--preview")
|
|
213
|
+
|
|
214
|
+
# Format mode doesn't support JSON output
|
|
215
|
+
# But we can use --check to see what would be formatted
|
|
216
|
+
if not self.settings.fix_enabled:
|
|
217
|
+
cmd.append("--check") # Only check, don't modify
|
|
218
|
+
|
|
219
|
+
async def parse_output(
|
|
220
|
+
self,
|
|
221
|
+
result: ToolExecutionResult,
|
|
222
|
+
) -> list[ToolIssue]:
|
|
223
|
+
"""Parse Ruff output into standardized issues.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
result: Raw execution result from Ruff
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
List of parsed issues
|
|
230
|
+
"""
|
|
231
|
+
if not self.settings:
|
|
232
|
+
raise RuntimeError("Settings not initialized")
|
|
233
|
+
|
|
234
|
+
issues: list[ToolIssue] = []
|
|
235
|
+
|
|
236
|
+
# Parse based on mode
|
|
237
|
+
if self.settings.mode == "check":
|
|
238
|
+
# Lint mode - parse JSON output
|
|
239
|
+
if self.settings.use_json_output and result.raw_output:
|
|
240
|
+
issues = self._parse_check_json(result.raw_output)
|
|
241
|
+
else:
|
|
242
|
+
# Fallback to text parsing if JSON not available
|
|
243
|
+
issues = self._parse_check_text(result.raw_output)
|
|
244
|
+
|
|
245
|
+
elif self.settings.mode == "format":
|
|
246
|
+
# Format mode - parse modified files from output
|
|
247
|
+
if result.exit_code != 0:
|
|
248
|
+
# Files would be modified (or were modified if fix_enabled)
|
|
249
|
+
issues = self._parse_format_output(
|
|
250
|
+
result.raw_output,
|
|
251
|
+
result.files_processed,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
return issues
|
|
255
|
+
|
|
256
|
+
def _parse_check_json(self, output: str) -> list[ToolIssue]:
|
|
257
|
+
"""Parse Ruff check JSON output.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
output: JSON output from ruff check
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
List of ToolIssue objects
|
|
264
|
+
"""
|
|
265
|
+
try:
|
|
266
|
+
data = json.loads(output)
|
|
267
|
+
except json.JSONDecodeError:
|
|
268
|
+
return []
|
|
269
|
+
|
|
270
|
+
issues = []
|
|
271
|
+
for item in data:
|
|
272
|
+
# Ruff JSON format:
|
|
273
|
+
# {
|
|
274
|
+
# "code": "F401",
|
|
275
|
+
# "message": "'os' imported but unused",
|
|
276
|
+
# "location": {
|
|
277
|
+
# "row": 1,
|
|
278
|
+
# "column": 8
|
|
279
|
+
# },
|
|
280
|
+
# "filename": "example.py",
|
|
281
|
+
# "url": "https://...",
|
|
282
|
+
# "fix": {...} (optional)
|
|
283
|
+
# }
|
|
284
|
+
|
|
285
|
+
location = item.get("location", {})
|
|
286
|
+
file_path = Path(item.get("filename", ""))
|
|
287
|
+
|
|
288
|
+
issue = ToolIssue(
|
|
289
|
+
file_path=file_path,
|
|
290
|
+
line_number=location.get("row"),
|
|
291
|
+
column_number=location.get("column"),
|
|
292
|
+
message=item.get("message", ""),
|
|
293
|
+
code=item.get("code"),
|
|
294
|
+
severity="error" if item.get("code", "").startswith("E") else "warning",
|
|
295
|
+
suggestion=item.get("fix", {}).get("message")
|
|
296
|
+
if item.get("fix")
|
|
297
|
+
else None,
|
|
298
|
+
)
|
|
299
|
+
issues.append(issue)
|
|
300
|
+
|
|
301
|
+
return issues
|
|
302
|
+
|
|
303
|
+
def _parse_check_text(self, output: str) -> list[ToolIssue]:
|
|
304
|
+
"""Parse Ruff check text output (fallback).
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
output: Text output from ruff check
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
List of ToolIssue objects
|
|
311
|
+
"""
|
|
312
|
+
issues = []
|
|
313
|
+
lines = output.strip().split("\n")
|
|
314
|
+
|
|
315
|
+
for line in lines:
|
|
316
|
+
# Ruff text format: "path/to/file.py:10:5: F401 'os' imported but unused"
|
|
317
|
+
if ":" not in line:
|
|
318
|
+
continue
|
|
319
|
+
|
|
320
|
+
issue = self._parse_check_text_line(line)
|
|
321
|
+
if issue:
|
|
322
|
+
issues.append(issue)
|
|
323
|
+
|
|
324
|
+
return issues
|
|
325
|
+
|
|
326
|
+
def _parse_check_text_line(self, line: str) -> ToolIssue | None:
|
|
327
|
+
"""Parse a single Ruff check text line.
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
line: Line of text output
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
ToolIssue if parsing successful, None otherwise
|
|
334
|
+
"""
|
|
335
|
+
parts = line.split(":", maxsplit=3)
|
|
336
|
+
if len(parts) < 4:
|
|
337
|
+
return None
|
|
338
|
+
|
|
339
|
+
try:
|
|
340
|
+
file_path = Path(parts[0].strip())
|
|
341
|
+
line_number = int(parts[1].strip())
|
|
342
|
+
column_number = (
|
|
343
|
+
int(parts[2].strip()) if parts[2].strip().isdigit() else None
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
# Parse code and message
|
|
347
|
+
message_part = parts[3].strip()
|
|
348
|
+
code, message = self._extract_check_code_and_message(message_part)
|
|
349
|
+
|
|
350
|
+
return ToolIssue(
|
|
351
|
+
file_path=file_path,
|
|
352
|
+
line_number=line_number,
|
|
353
|
+
column_number=column_number,
|
|
354
|
+
message=message,
|
|
355
|
+
code=code,
|
|
356
|
+
severity="error" if code and code.startswith("E") else "warning",
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
except (ValueError, IndexError):
|
|
360
|
+
return None
|
|
361
|
+
|
|
362
|
+
def _extract_check_code_and_message(
|
|
363
|
+
self, message_part: str
|
|
364
|
+
) -> tuple[str | None, str]:
|
|
365
|
+
"""Extract code and message from Ruff check output.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
message_part: Part containing code and message
|
|
369
|
+
|
|
370
|
+
Returns:
|
|
371
|
+
Tuple of (code, message)
|
|
372
|
+
"""
|
|
373
|
+
if " " not in message_part:
|
|
374
|
+
return None, message_part
|
|
375
|
+
|
|
376
|
+
code_candidate = message_part.split()[0]
|
|
377
|
+
if code_candidate.strip():
|
|
378
|
+
code = code_candidate
|
|
379
|
+
message = message_part[len(code) :].strip()
|
|
380
|
+
return code, message
|
|
381
|
+
|
|
382
|
+
return None, message_part
|
|
383
|
+
|
|
384
|
+
def _parse_format_output(
|
|
385
|
+
self,
|
|
386
|
+
output: str,
|
|
387
|
+
processed_files: list[Path],
|
|
388
|
+
) -> list[ToolIssue]:
|
|
389
|
+
"""Parse Ruff format output.
|
|
390
|
+
|
|
391
|
+
Args:
|
|
392
|
+
output: Text output from ruff format
|
|
393
|
+
processed_files: Files that were processed
|
|
394
|
+
|
|
395
|
+
Returns:
|
|
396
|
+
List of ToolIssue objects (files needing formatting)
|
|
397
|
+
"""
|
|
398
|
+
issues = []
|
|
399
|
+
|
|
400
|
+
# Ruff format --check outputs files that would be reformatted
|
|
401
|
+
lines = output.strip().split("\n")
|
|
402
|
+
|
|
403
|
+
for line in lines:
|
|
404
|
+
if line.startswith("Would reformat:") or line.strip().endswith(".py"):
|
|
405
|
+
# Extract file path
|
|
406
|
+
file_str = line.replace("Would reformat:", "").strip()
|
|
407
|
+
if file_str:
|
|
408
|
+
try:
|
|
409
|
+
file_path = Path(file_str)
|
|
410
|
+
issue = ToolIssue(
|
|
411
|
+
file_path=file_path,
|
|
412
|
+
message="File would be reformatted",
|
|
413
|
+
severity="warning",
|
|
414
|
+
)
|
|
415
|
+
issues.append(issue)
|
|
416
|
+
except Exception:
|
|
417
|
+
continue
|
|
418
|
+
|
|
419
|
+
# If no specific files mentioned but exit code != 0, all files need formatting
|
|
420
|
+
if not issues and processed_files:
|
|
421
|
+
for file_path in processed_files:
|
|
422
|
+
issue = ToolIssue(
|
|
423
|
+
file_path=file_path,
|
|
424
|
+
message="File needs formatting",
|
|
425
|
+
severity="warning",
|
|
426
|
+
)
|
|
427
|
+
issues.append(issue)
|
|
428
|
+
|
|
429
|
+
return issues
|
|
430
|
+
|
|
431
|
+
async def check(
|
|
432
|
+
self,
|
|
433
|
+
files: list[Path] | None = None,
|
|
434
|
+
config: QACheckConfig | None = None,
|
|
435
|
+
) -> QAResult:
|
|
436
|
+
"""Execute Ruff check/format on files.
|
|
437
|
+
|
|
438
|
+
Overrides parent to handle format mode's file modifications.
|
|
439
|
+
|
|
440
|
+
Args:
|
|
441
|
+
files: List of files to check (None = check all matching patterns)
|
|
442
|
+
config: Optional configuration override
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
QAResult with check execution results
|
|
446
|
+
"""
|
|
447
|
+
# Call parent check implementation
|
|
448
|
+
result = await super().check(files=files, config=config)
|
|
449
|
+
|
|
450
|
+
# If format mode with fix enabled, mark files as modified
|
|
451
|
+
if (
|
|
452
|
+
self.settings
|
|
453
|
+
and self.settings.mode == "format"
|
|
454
|
+
and self.settings.fix_enabled
|
|
455
|
+
and result.status in (QAResultStatus.SUCCESS, QAResultStatus.WARNING)
|
|
456
|
+
):
|
|
457
|
+
# Files were formatted - mark as modified
|
|
458
|
+
result.files_modified = result.files_checked.copy()
|
|
459
|
+
result.issues_fixed = result.issues_found
|
|
460
|
+
|
|
461
|
+
return result
|
|
462
|
+
|
|
463
|
+
def _get_check_type(self) -> QACheckType:
|
|
464
|
+
"""Determine check type based on mode.
|
|
465
|
+
|
|
466
|
+
Returns:
|
|
467
|
+
QACheckType.FORMAT for format mode, QACheckType.LINT for check mode
|
|
468
|
+
"""
|
|
469
|
+
if self.settings and self.settings.mode == "format":
|
|
470
|
+
return QACheckType.FORMAT
|
|
471
|
+
return QACheckType.LINT
|
|
472
|
+
|
|
473
|
+
def get_default_config(self) -> QACheckConfig:
|
|
474
|
+
"""Get default configuration for Ruff adapter.
|
|
475
|
+
|
|
476
|
+
Returns:
|
|
477
|
+
QACheckConfig with sensible defaults
|
|
478
|
+
"""
|
|
479
|
+
from crackerjack.models.qa_config import QACheckConfig
|
|
480
|
+
|
|
481
|
+
# Determine if this is a format mode adapter from settings or default to check mode
|
|
482
|
+
is_format_mode = False
|
|
483
|
+
if self.settings:
|
|
484
|
+
is_format_mode = self.settings.mode == "format"
|
|
485
|
+
else:
|
|
486
|
+
is_format_mode = False # Default to check mode
|
|
487
|
+
|
|
488
|
+
return QACheckConfig(
|
|
489
|
+
check_id=MODULE_ID,
|
|
490
|
+
check_name=self.adapter_name,
|
|
491
|
+
check_type=self._get_check_type(),
|
|
492
|
+
enabled=True,
|
|
493
|
+
file_patterns=["**/*.py"],
|
|
494
|
+
exclude_patterns=[
|
|
495
|
+
"**/.*",
|
|
496
|
+
"**/__pycache__/**",
|
|
497
|
+
"**/build/**",
|
|
498
|
+
"**/dist/**",
|
|
499
|
+
],
|
|
500
|
+
timeout_seconds=60,
|
|
501
|
+
is_formatter=is_format_mode,
|
|
502
|
+
parallel_safe=True,
|
|
503
|
+
stage="fast",
|
|
504
|
+
settings={
|
|
505
|
+
"mode": "check",
|
|
506
|
+
"fix_enabled": True, # Enable auto-fix by default for fast hooks
|
|
507
|
+
"select_rules": [],
|
|
508
|
+
"ignore_rules": [],
|
|
509
|
+
"preview": False,
|
|
510
|
+
},
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
# ACB Registration (REQUIRED at module level)
|
|
515
|
+
with suppress(Exception):
|
|
516
|
+
depends.set(RuffAdapter)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
> Crackerjack Docs: [Main](<../../../README.md>) | [Adapters](<../README.md>) | [Lint](<./README.md>)
|
|
2
|
+
|
|
3
|
+
# Lint Adapter
|
|
4
|
+
|
|
5
|
+
Lightweight linters focused on spelling and text quality. Ruff lint is available under the Format adapter’s “check” mode.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
- Catch common spelling mistakes in code, docs, and filenames
|
|
10
|
+
- Optional write-back for automatic typo fixes
|
|
11
|
+
- Ignore lists and skip rules for noisy terms
|
|
12
|
+
|
|
13
|
+
## Built-in Implementation
|
|
14
|
+
|
|
15
|
+
| Module | Description | Status |
|
|
16
|
+
| ------ | ----------- | ------ |
|
|
17
|
+
| `codespell.py` | Spelling and typo detection with optional auto-fix | Stable |
|
|
18
|
+
|
|
19
|
+
## Codespell Settings
|
|
20
|
+
|
|
21
|
+
Settings class: `CodespellSettings`
|
|
22
|
+
|
|
23
|
+
- `fix_enabled` (bool; write changes)
|
|
24
|
+
- `skip_hidden` (bool)
|
|
25
|
+
- `ignore_words` (list[str]) and/or `ignore_words_file` (Path)
|
|
26
|
+
- `check_filenames` (bool)
|
|
27
|
+
- `quiet_level` (int; default 2)
|
|
28
|
+
|
|
29
|
+
## Basic Usage
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
from crackerjack.adapters.lint.codespell import CodespellAdapter, CodespellSettings
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def run_codespell() -> None:
|
|
37
|
+
adapter = CodespellAdapter(
|
|
38
|
+
settings=CodespellSettings(fix_enabled=False, ignore_words=["acb", "pydantic"])
|
|
39
|
+
)
|
|
40
|
+
await adapter.init()
|
|
41
|
+
result = await adapter.check(files=[Path("src/"), Path("docs/")])
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Notes
|
|
45
|
+
|
|
46
|
+
- Use a shared `ignore_words_file` to standardize noisy tokens across repos
|
|
47
|
+
- For Ruff linting, see [Format](<../format/README.md>)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Lint adapters for code quality and style checking.
|
|
2
|
+
|
|
3
|
+
Adapters:
|
|
4
|
+
- codespell: Spell checking in code and documentation
|
|
5
|
+
- ruff (check mode): Fast Python linting
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# ACB will auto-discover these adapters via depends.set() in module files
|
|
9
|
+
# No explicit imports needed here
|
|
10
|
+
|
|
11
|
+
__all__ = []
|