crackerjack 0.37.9__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 +30 -1
- crackerjack/__main__.py +342 -1263
- crackerjack/adapters/README.md +18 -0
- crackerjack/adapters/__init__.py +27 -5
- 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/{rust_tool_manager.py → lsp/_manager.py} +3 -3
- crackerjack/adapters/{skylos_adapter.py → lsp/skylos.py} +59 -7
- crackerjack/adapters/{zuban_adapter.py → lsp/zuban.py} +3 -6
- 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 +40 -12
- crackerjack/agents/base.py +1 -0
- crackerjack/agents/claude_code_bridge.py +641 -0
- crackerjack/agents/coordinator.py +49 -53
- crackerjack/agents/dry_agent.py +187 -3
- 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 +6 -8
- 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/performance_agent.py +121 -1152
- crackerjack/agents/refactoring_agent.py +156 -655
- crackerjack/agents/semantic_agent.py +479 -0
- crackerjack/agents/semantic_helpers.py +356 -0
- crackerjack/agents/test_creation_agent.py +19 -1605
- crackerjack/api.py +5 -7
- crackerjack/cli/README.md +394 -0
- crackerjack/cli/__init__.py +1 -1
- crackerjack/cli/cache_handlers.py +23 -18
- crackerjack/cli/cache_handlers_enhanced.py +1 -4
- crackerjack/cli/facade.py +70 -8
- 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 +249 -49
- crackerjack/cli/interactive.py +8 -5
- crackerjack/cli/options.py +203 -110
- crackerjack/cli/semantic_handlers.py +292 -0
- crackerjack/cli/version.py +19 -0
- crackerjack/code_cleaner.py +60 -24
- crackerjack/config/README.md +472 -0
- crackerjack/config/__init__.py +256 -0
- crackerjack/config/global_lock_config.py +191 -54
- crackerjack/config/hooks.py +188 -16
- 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/async_workflow_orchestrator.py +79 -53
- crackerjack/core/autofix_coordinator.py +22 -9
- crackerjack/core/container.py +10 -9
- crackerjack/core/enhanced_container.py +9 -9
- crackerjack/core/performance.py +1 -1
- crackerjack/core/performance_monitor.py +5 -3
- crackerjack/core/phase_coordinator.py +1018 -634
- crackerjack/core/proactive_workflow.py +3 -3
- crackerjack/core/retry.py +275 -0
- crackerjack/core/service_watchdog.py +167 -23
- crackerjack/core/session_coordinator.py +187 -382
- crackerjack/core/timeout_manager.py +161 -44
- 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 +1247 -953
- 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/README.md +11 -0
- crackerjack/docs/generated/api/CLI_REFERENCE.md +1 -1
- crackerjack/documentation/README.md +11 -0
- crackerjack/documentation/ai_templates.py +1 -1
- crackerjack/documentation/dual_output_generator.py +11 -9
- crackerjack/documentation/reference_generator.py +104 -59
- crackerjack/dynamic_config.py +52 -61
- crackerjack/errors.py +1 -1
- 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 +2 -0
- crackerjack/executors/async_hook_executor.py +539 -77
- crackerjack/executors/cached_hook_executor.py +3 -3
- crackerjack/executors/hook_executor.py +967 -102
- crackerjack/executors/hook_lock_manager.py +31 -22
- crackerjack/executors/individual_hook_executor.py +66 -32
- crackerjack/executors/lsp_aware_hook_executor.py +136 -57
- crackerjack/executors/progress_hook_executor.py +282 -0
- crackerjack/executors/tool_proxy.py +23 -7
- crackerjack/hooks/README.md +485 -0
- crackerjack/hooks/lsp_hook.py +8 -9
- crackerjack/intelligence/README.md +557 -0
- crackerjack/interactive.py +37 -10
- crackerjack/managers/README.md +369 -0
- crackerjack/managers/async_hook_manager.py +41 -57
- crackerjack/managers/hook_manager.py +449 -79
- crackerjack/managers/publish_manager.py +81 -36
- crackerjack/managers/test_command_builder.py +290 -12
- crackerjack/managers/test_executor.py +93 -8
- crackerjack/managers/test_manager.py +1082 -75
- crackerjack/managers/test_progress.py +118 -26
- crackerjack/mcp/README.md +374 -0
- crackerjack/mcp/cache.py +25 -2
- crackerjack/mcp/client_runner.py +35 -18
- crackerjack/mcp/context.py +9 -9
- crackerjack/mcp/dashboard.py +24 -8
- crackerjack/mcp/enhanced_progress_monitor.py +34 -23
- crackerjack/mcp/file_monitor.py +27 -6
- crackerjack/mcp/progress_components.py +45 -34
- crackerjack/mcp/progress_monitor.py +6 -9
- crackerjack/mcp/rate_limiter.py +11 -7
- crackerjack/mcp/server.py +2 -0
- crackerjack/mcp/server_core.py +187 -55
- crackerjack/mcp/service_watchdog.py +12 -9
- crackerjack/mcp/task_manager.py +2 -2
- crackerjack/mcp/tools/README.md +27 -0
- crackerjack/mcp/tools/__init__.py +2 -0
- crackerjack/mcp/tools/core_tools.py +75 -52
- crackerjack/mcp/tools/execution_tools.py +87 -31
- crackerjack/mcp/tools/intelligence_tools.py +2 -2
- crackerjack/mcp/tools/proactive_tools.py +1 -1
- crackerjack/mcp/tools/semantic_tools.py +584 -0
- crackerjack/mcp/tools/utility_tools.py +180 -132
- crackerjack/mcp/tools/workflow_executor.py +87 -46
- crackerjack/mcp/websocket/README.md +31 -0
- crackerjack/mcp/websocket/app.py +11 -1
- crackerjack/mcp/websocket/event_bridge.py +188 -0
- crackerjack/mcp/websocket/jobs.py +27 -4
- 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 +16 -2930
- crackerjack/mcp/websocket/server.py +1 -3
- crackerjack/mcp/websocket/websocket_handler.py +107 -6
- crackerjack/models/README.md +308 -0
- crackerjack/models/__init__.py +10 -1
- crackerjack/models/config.py +639 -22
- crackerjack/models/config_adapter.py +6 -6
- crackerjack/models/protocols.py +1167 -23
- crackerjack/models/pydantic_models.py +320 -0
- crackerjack/models/qa_config.py +145 -0
- crackerjack/models/qa_results.py +134 -0
- crackerjack/models/results.py +35 -0
- crackerjack/models/semantic_models.py +258 -0
- crackerjack/models/task.py +19 -3
- crackerjack/models/test_models.py +60 -0
- crackerjack/monitoring/README.md +11 -0
- crackerjack/monitoring/ai_agent_watchdog.py +5 -4
- crackerjack/monitoring/metrics_collector.py +4 -3
- crackerjack/monitoring/regression_prevention.py +4 -3
- crackerjack/monitoring/websocket_server.py +4 -241
- crackerjack/orchestration/README.md +340 -0
- crackerjack/orchestration/__init__.py +43 -0
- crackerjack/orchestration/advanced_orchestrator.py +20 -67
- 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 +13 -6
- crackerjack/orchestration/execution_strategies.py +6 -6
- 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 +1 -1
- crackerjack/plugins/README.md +11 -0
- crackerjack/plugins/hooks.py +3 -2
- crackerjack/plugins/loader.py +3 -3
- crackerjack/plugins/managers.py +1 -1
- crackerjack/py313.py +191 -0
- crackerjack/security/README.md +11 -0
- crackerjack/services/README.md +374 -0
- crackerjack/services/__init__.py +8 -21
- crackerjack/services/ai/README.md +295 -0
- crackerjack/services/ai/__init__.py +7 -0
- crackerjack/services/ai/advanced_optimizer.py +878 -0
- crackerjack/services/{contextual_ai_assistant.py → ai/contextual_ai_assistant.py} +5 -3
- 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/api_extractor.py +5 -3
- crackerjack/services/bounded_status_operations.py +45 -5
- crackerjack/services/cache.py +249 -318
- crackerjack/services/changelog_automation.py +7 -3
- crackerjack/services/command_execution_service.py +305 -0
- crackerjack/services/config_integrity.py +83 -39
- crackerjack/services/config_merge.py +9 -6
- crackerjack/services/config_service.py +198 -0
- crackerjack/services/config_template.py +13 -26
- crackerjack/services/coverage_badge_service.py +6 -4
- crackerjack/services/coverage_ratchet.py +53 -27
- crackerjack/services/debug.py +18 -7
- crackerjack/services/dependency_analyzer.py +4 -4
- crackerjack/services/dependency_monitor.py +13 -13
- crackerjack/services/documentation_generator.py +4 -2
- crackerjack/services/documentation_service.py +62 -33
- crackerjack/services/enhanced_filesystem.py +81 -27
- crackerjack/services/enterprise_optimizer.py +1 -1
- crackerjack/services/error_pattern_analyzer.py +10 -10
- crackerjack/services/file_filter.py +221 -0
- crackerjack/services/file_hasher.py +5 -7
- crackerjack/services/file_io_service.py +361 -0
- crackerjack/services/file_modifier.py +615 -0
- crackerjack/services/filesystem.py +80 -109
- crackerjack/services/git.py +99 -5
- crackerjack/services/health_metrics.py +4 -6
- crackerjack/services/heatmap_generator.py +12 -3
- crackerjack/services/incremental_executor.py +380 -0
- crackerjack/services/initialization.py +101 -49
- crackerjack/services/log_manager.py +2 -2
- crackerjack/services/logging.py +120 -68
- crackerjack/services/lsp_client.py +12 -12
- crackerjack/services/memory_optimizer.py +27 -22
- 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/{performance_benchmarks.py → monitoring/performance_benchmarks.py} +100 -14
- crackerjack/services/{performance_cache.py → monitoring/performance_cache.py} +21 -15
- crackerjack/services/{performance_monitor.py → monitoring/performance_monitor.py} +10 -6
- crackerjack/services/parallel_executor.py +166 -55
- 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 +21 -8
- 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_baseline.py → quality/quality_baseline.py} +163 -2
- crackerjack/services/{quality_baseline_enhanced.py → quality/quality_baseline_enhanced.py} +4 -1
- crackerjack/services/{quality_intelligence.py → quality/quality_intelligence.py} +180 -16
- crackerjack/services/regex_patterns.py +58 -2987
- crackerjack/services/regex_utils.py +55 -29
- crackerjack/services/secure_status_formatter.py +42 -15
- crackerjack/services/secure_subprocess.py +35 -2
- crackerjack/services/security.py +16 -8
- crackerjack/services/server_manager.py +40 -51
- crackerjack/services/smart_scheduling.py +46 -6
- crackerjack/services/status_authentication.py +3 -3
- crackerjack/services/thread_safe_status_collector.py +1 -0
- crackerjack/services/tool_filter.py +368 -0
- crackerjack/services/tool_version_service.py +9 -5
- crackerjack/services/unified_config.py +43 -351
- crackerjack/services/vector_store.py +689 -0
- crackerjack/services/version_analyzer.py +6 -4
- crackerjack/services/version_checker.py +14 -8
- crackerjack/services/zuban_lsp_service.py +5 -4
- crackerjack/slash_commands/README.md +11 -0
- crackerjack/slash_commands/init.md +2 -12
- crackerjack/slash_commands/run.md +84 -50
- 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_regex_patterns.py +7 -3
- crackerjack/ui/README.md +11 -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.37.9.dist-info → crackerjack-0.45.2.dist-info}/METADATA +678 -98
- crackerjack-0.45.2.dist-info/RECORD +478 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
- crackerjack/managers/test_manager_backup.py +0 -1075
- crackerjack/mcp/tools/execution_tools_backup.py +0 -1011
- crackerjack/mixins/__init__.py +0 -3
- crackerjack/mixins/error_handling.py +0 -145
- crackerjack/services/config.py +0 -358
- crackerjack/ui/server_panels.py +0 -125
- crackerjack-0.37.9.dist-info/RECORD +0 -231
- /crackerjack/adapters/{rust_tool_adapter.py → lsp/_base.py} +0 -0
- /crackerjack/adapters/{lsp_client.py → lsp/_client.py} +0 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Code pattern descriptions."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
from ..core import ValidatedPattern
|
|
6
|
+
|
|
7
|
+
PATTERNS: dict[str, ValidatedPattern] = {
|
|
8
|
+
"list_append_inefficiency_pattern": ValidatedPattern(
|
|
9
|
+
name="list_append_inefficiency_pattern",
|
|
10
|
+
pattern=r"(\s*)(\w+)\s*\+=\s*\[([^]]+)\]",
|
|
11
|
+
replacement=r"\1\2.append(\3)",
|
|
12
|
+
test_cases=[
|
|
13
|
+
(" items += [new_item]", " items.append(new_item)"),
|
|
14
|
+
("results += [result]", "results.append(result)"),
|
|
15
|
+
(" data += [value, other]", " data.append(value, other)"),
|
|
16
|
+
],
|
|
17
|
+
description="Replace inefficient list[t.Any] concatenation with append for"
|
|
18
|
+
" performance",
|
|
19
|
+
),
|
|
20
|
+
"string_concatenation_pattern": ValidatedPattern(
|
|
21
|
+
name="string_concatenation_pattern",
|
|
22
|
+
pattern=r"(\s*)(\w+)\s*\+=\s*(.+)",
|
|
23
|
+
replacement=r"\1\2_parts.append(\3)",
|
|
24
|
+
test_cases=[
|
|
25
|
+
(" text += new_text", " text_parts.append(new_text)"),
|
|
26
|
+
("result += line", "result_parts.append(line)"),
|
|
27
|
+
(" output += data", " output_parts.append(data)"),
|
|
28
|
+
],
|
|
29
|
+
description="Replace string concatenation with list[t.Any] append for performance "
|
|
30
|
+
"optimization",
|
|
31
|
+
),
|
|
32
|
+
"nested_loop_detection_pattern": ValidatedPattern(
|
|
33
|
+
name="nested_loop_detection_pattern",
|
|
34
|
+
pattern=r"(\s*)(for\s+\w+\s+in\s+.*: )",
|
|
35
|
+
replacement=r"\1# Performance: Potential nested loop - check complexity\n\1\2",
|
|
36
|
+
test_cases=[
|
|
37
|
+
(
|
|
38
|
+
" for j in other: ",
|
|
39
|
+
" # Performance: Potential nested loop - check complexity\n "
|
|
40
|
+
"for j in other: ",
|
|
41
|
+
),
|
|
42
|
+
(
|
|
43
|
+
"for i in items: ",
|
|
44
|
+
"# Performance: Potential nested loop - check complexity\nfor i"
|
|
45
|
+
" in items: ",
|
|
46
|
+
),
|
|
47
|
+
],
|
|
48
|
+
description="Detect loop patterns that might be nested creating O(n²)"
|
|
49
|
+
" complexity",
|
|
50
|
+
flags=re.MULTILINE,
|
|
51
|
+
),
|
|
52
|
+
"list_extend_optimization_pattern": ValidatedPattern(
|
|
53
|
+
name="list_extend_optimization_pattern",
|
|
54
|
+
pattern=r"(\s*)(\w+)\s*\+=\s*\[([^]]+(?: , \s*[^]]+)*)\]",
|
|
55
|
+
replacement=r"\1\2.extend([\3])",
|
|
56
|
+
test_cases=[
|
|
57
|
+
(" items += [a, b, c]", " items.extend([a, b, c])"),
|
|
58
|
+
("results += [x, y]", "results.extend([x, y])"),
|
|
59
|
+
(" data += [single_item]", " data.extend([single_item])"),
|
|
60
|
+
],
|
|
61
|
+
description="Replace list[t.Any] concatenation with extend for better performance with multiple items",
|
|
62
|
+
),
|
|
63
|
+
"inefficient_string_join_pattern": ValidatedPattern(
|
|
64
|
+
name="inefficient_string_join_pattern",
|
|
65
|
+
pattern=r"(\s*)(\w+)\s*=\s*([\"'])([\"'])\s*\.\s*join\(\s*\[\s*\]\s*\)",
|
|
66
|
+
replacement=r"\1\2 = \3\4 # Performance: Use empty string directly instead"
|
|
67
|
+
r" of join",
|
|
68
|
+
test_cases=[
|
|
69
|
+
(
|
|
70
|
+
' text = "".join([])',
|
|
71
|
+
' text = "" # Performance: Use empty string directly instead of join',
|
|
72
|
+
),
|
|
73
|
+
(
|
|
74
|
+
"result = ''.join([])",
|
|
75
|
+
"result = '' # Performance: Use empty string directly instead of join",
|
|
76
|
+
),
|
|
77
|
+
],
|
|
78
|
+
description="Replace inefficient empty list[t.Any] join with direct empty string"
|
|
79
|
+
" assignment",
|
|
80
|
+
),
|
|
81
|
+
"repeated_len_in_loop_pattern": ValidatedPattern(
|
|
82
|
+
name="repeated_len_in_loop_pattern",
|
|
83
|
+
pattern=r"(\s*)(len\(\s*(\w+)\s*\))",
|
|
84
|
+
replacement=r"\1# Performance: Consider caching len(\3) if used "
|
|
85
|
+
r"repeatedly\n\1\2",
|
|
86
|
+
test_cases=[
|
|
87
|
+
(
|
|
88
|
+
" len(items)",
|
|
89
|
+
" # Performance: Consider caching len(items) if used repeatedly\n"
|
|
90
|
+
" len(items)",
|
|
91
|
+
),
|
|
92
|
+
(
|
|
93
|
+
"len(data)",
|
|
94
|
+
"# Performance: Consider caching len(data) if used "
|
|
95
|
+
"repeatedly\nlen(data)",
|
|
96
|
+
),
|
|
97
|
+
],
|
|
98
|
+
description="Suggest caching len() calls that might be repeated",
|
|
99
|
+
),
|
|
100
|
+
"list_comprehension_optimization_pattern": ValidatedPattern(
|
|
101
|
+
name="list_comprehension_optimization_pattern",
|
|
102
|
+
pattern=r"(\s*)(\w+)\.append\(([^)]+)\)",
|
|
103
|
+
replacement=r"\1# Performance: Consider list[t.Any] comprehension if this is in a "
|
|
104
|
+
r"simple loop\n\1\2.append(\3)",
|
|
105
|
+
test_cases=[
|
|
106
|
+
(
|
|
107
|
+
" results.append(item * 2)",
|
|
108
|
+
" # Performance: Consider list[t.Any] comprehension if this is in a "
|
|
109
|
+
"simple loop\n results.append(item * 2)",
|
|
110
|
+
),
|
|
111
|
+
(
|
|
112
|
+
"data.append(value)",
|
|
113
|
+
"# Performance: Consider list[t.Any] comprehension if this is in a simple"
|
|
114
|
+
" loop\ndata.append(value)",
|
|
115
|
+
),
|
|
116
|
+
],
|
|
117
|
+
description="Suggest list[t.Any] comprehensions for simple append patterns",
|
|
118
|
+
),
|
|
119
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Code pattern descriptions."""
|
|
2
|
+
|
|
3
|
+
from ..core import ValidatedPattern
|
|
4
|
+
|
|
5
|
+
PATTERNS: dict[str, ValidatedPattern] = {
|
|
6
|
+
"replace_subprocess_popen_basic": ValidatedPattern(
|
|
7
|
+
name="replace_subprocess_popen_basic",
|
|
8
|
+
pattern=r"subprocess\.Popen\(",
|
|
9
|
+
replacement="managed_proc = resource_ctx.managed_process(subprocess.Popen(",
|
|
10
|
+
test_cases=[
|
|
11
|
+
(
|
|
12
|
+
"subprocess.Popen(cmd)",
|
|
13
|
+
"managed_proc = resource_ctx.managed_process(subprocess.Popen(cmd)",
|
|
14
|
+
),
|
|
15
|
+
(
|
|
16
|
+
"result = subprocess.Popen(['ls'])",
|
|
17
|
+
"result = managed_proc = resource_ctx.managed_process("
|
|
18
|
+
"subprocess.Popen(['ls'])",
|
|
19
|
+
),
|
|
20
|
+
],
|
|
21
|
+
description="Replace subprocess.Popen with managed version",
|
|
22
|
+
),
|
|
23
|
+
"replace_subprocess_popen_assignment": ValidatedPattern(
|
|
24
|
+
name="replace_subprocess_popen_assignment",
|
|
25
|
+
pattern=r"(\w+)\s*=\s*subprocess\.Popen\(",
|
|
26
|
+
replacement=r"process = subprocess.Popen(",
|
|
27
|
+
test_cases=[
|
|
28
|
+
("proc = subprocess.Popen(cmd)", "process = subprocess.Popen(cmd)"),
|
|
29
|
+
(
|
|
30
|
+
"my_process = subprocess.Popen(['ls'])",
|
|
31
|
+
"process = subprocess.Popen(['ls'])",
|
|
32
|
+
),
|
|
33
|
+
],
|
|
34
|
+
description="Replace subprocess.Popen assignment with standard variable name",
|
|
35
|
+
),
|
|
36
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""Core pattern validation classes and utilities.
|
|
2
|
+
|
|
3
|
+
This module contains the base classes and utilities for safely handling
|
|
4
|
+
regex patterns with validation, caching, and performance monitoring.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
import signal
|
|
9
|
+
import threading
|
|
10
|
+
import time
|
|
11
|
+
import typing as t
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from re import Pattern
|
|
14
|
+
|
|
15
|
+
MAX_INPUT_SIZE = 10 * 1024 * 1024
|
|
16
|
+
MAX_ITERATIONS = 10
|
|
17
|
+
PATTERN_CACHE_SIZE = 100
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CompiledPatternCache:
|
|
21
|
+
_lock = threading.RLock()
|
|
22
|
+
_cache: dict[str, Pattern[str]] = {}
|
|
23
|
+
_max_size = PATTERN_CACHE_SIZE
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def get_compiled_pattern(cls, pattern: str) -> Pattern[str]:
|
|
27
|
+
return cls.get_compiled_pattern_with_flags(pattern, pattern, 0)
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def get_compiled_pattern_with_flags(
|
|
31
|
+
cls, cache_key: str, pattern: str, flags: int
|
|
32
|
+
) -> Pattern[str]:
|
|
33
|
+
with cls._lock:
|
|
34
|
+
if cache_key in cls._cache:
|
|
35
|
+
return cls._cache[cache_key]
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
compiled = re.compile(pattern, flags)
|
|
39
|
+
except re.error as e:
|
|
40
|
+
raise ValueError(f"Invalid regex pattern '{pattern}': {e}")
|
|
41
|
+
|
|
42
|
+
if len(cls._cache) >= cls._max_size:
|
|
43
|
+
oldest_key = next(iter(cls._cache))
|
|
44
|
+
del cls._cache[oldest_key]
|
|
45
|
+
|
|
46
|
+
cls._cache[cache_key] = compiled
|
|
47
|
+
return compiled
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def clear_cache(cls) -> None:
|
|
51
|
+
with cls._lock:
|
|
52
|
+
cls._cache.clear()
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def get_cache_stats(cls) -> dict[str, int | list[str]]:
|
|
56
|
+
with cls._lock:
|
|
57
|
+
return {
|
|
58
|
+
"size": len(cls._cache),
|
|
59
|
+
"max_size": cls._max_size,
|
|
60
|
+
"patterns": list[t.Any](cls._cache.keys()),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def validate_pattern_safety(pattern: str) -> list[str]:
|
|
65
|
+
warnings = []
|
|
66
|
+
|
|
67
|
+
if ".*.*" in pattern:
|
|
68
|
+
warnings.append("Multiple .* constructs may cause performance issues")
|
|
69
|
+
|
|
70
|
+
if ".+.+" in pattern:
|
|
71
|
+
warnings.append("Multiple .+ constructs may cause performance issues")
|
|
72
|
+
|
|
73
|
+
nested_quantifiers = re.findall(r"[+*?]\??[+*?]", pattern)
|
|
74
|
+
if nested_quantifiers:
|
|
75
|
+
warnings.append(f"Nested quantifiers detected: {nested_quantifiers}")
|
|
76
|
+
|
|
77
|
+
if "|" in pattern and pattern.count("|") > 10:
|
|
78
|
+
warnings.append("Many alternations may cause performance issues")
|
|
79
|
+
|
|
80
|
+
return warnings
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass
|
|
84
|
+
class ValidatedPattern:
|
|
85
|
+
name: str
|
|
86
|
+
pattern: str
|
|
87
|
+
replacement: str
|
|
88
|
+
test_cases: list[tuple[str, str]]
|
|
89
|
+
description: str = ""
|
|
90
|
+
global_replace: bool = False
|
|
91
|
+
flags: int = 0
|
|
92
|
+
_compiled_pattern: Pattern[str] | None = field(default=None, init=False)
|
|
93
|
+
|
|
94
|
+
def __post_init__(self) -> None:
|
|
95
|
+
self._validate()
|
|
96
|
+
|
|
97
|
+
def _validate(self) -> None:
|
|
98
|
+
try:
|
|
99
|
+
self._get_compiled_pattern()
|
|
100
|
+
except ValueError as e:
|
|
101
|
+
if "Invalid regex pattern" in str(e):
|
|
102
|
+
error_msg = str(e).replace(f"'{self.pattern}'", f"'{self.name}'")
|
|
103
|
+
raise ValueError(error_msg) from e
|
|
104
|
+
raise
|
|
105
|
+
|
|
106
|
+
if r"\g < " in self.replacement or r" >" in self.replacement:
|
|
107
|
+
raise ValueError(
|
|
108
|
+
f"Bad replacement syntax in '{self.name}': {self.replacement}. "
|
|
109
|
+
"Use \\g<1> not \\g<1>" # REGEX OK: educational example
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
warnings = validate_pattern_safety(self.pattern)
|
|
113
|
+
if warnings:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
for input_text, expected in self.test_cases:
|
|
117
|
+
try:
|
|
118
|
+
count = 0 if self.global_replace else 1
|
|
119
|
+
result = self._apply_internal(input_text, count)
|
|
120
|
+
if result != expected:
|
|
121
|
+
raise ValueError(
|
|
122
|
+
f"Pattern '{self.name}' failed test case: "
|
|
123
|
+
f"'{input_text}' -> '{result}' != expected '{expected}'"
|
|
124
|
+
)
|
|
125
|
+
except re.error as e:
|
|
126
|
+
raise ValueError(f"Pattern '{self.name}' failed on '{input_text}': {e}")
|
|
127
|
+
|
|
128
|
+
def _get_compiled_pattern(self) -> Pattern[str]:
|
|
129
|
+
cache_key = f"{self.pattern}|flags: {self.flags}"
|
|
130
|
+
return CompiledPatternCache.get_compiled_pattern_with_flags(
|
|
131
|
+
cache_key, self.pattern, self.flags
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def _apply_internal(self, text: str, count: int = 1) -> str:
|
|
135
|
+
if len(text) > MAX_INPUT_SIZE:
|
|
136
|
+
raise ValueError(
|
|
137
|
+
f"Input text too large: {len(text)} bytes > {MAX_INPUT_SIZE}"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
return self._get_compiled_pattern().sub(self.replacement, text, count=count)
|
|
141
|
+
|
|
142
|
+
def apply(self, text: str) -> str:
|
|
143
|
+
count = 0 if self.global_replace else 1
|
|
144
|
+
return self._apply_internal(text, count)
|
|
145
|
+
|
|
146
|
+
def apply_iteratively(self, text: str, max_iterations: int = MAX_ITERATIONS) -> str:
|
|
147
|
+
if max_iterations <= 0:
|
|
148
|
+
raise ValueError("max_iterations must be positive")
|
|
149
|
+
|
|
150
|
+
result = text
|
|
151
|
+
for _ in range(max_iterations):
|
|
152
|
+
new_result = self.apply(result)
|
|
153
|
+
if new_result == result:
|
|
154
|
+
break
|
|
155
|
+
result = new_result
|
|
156
|
+
else:
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
return result
|
|
160
|
+
|
|
161
|
+
def apply_with_timeout(self, text: str, timeout_seconds: float = 1.0) -> str:
|
|
162
|
+
def timeout_handler(signum: int, frame: t.Any) -> None:
|
|
163
|
+
raise TimeoutError(
|
|
164
|
+
f"Pattern '{self.name}' timed out after {timeout_seconds}s"
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
old_handler = signal.signal(signal.SIGALRM, timeout_handler)
|
|
168
|
+
signal.alarm(int(timeout_seconds))
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
result = self.apply(text)
|
|
172
|
+
finally:
|
|
173
|
+
signal.alarm(0)
|
|
174
|
+
signal.signal(signal.SIGALRM, old_handler)
|
|
175
|
+
|
|
176
|
+
return result
|
|
177
|
+
|
|
178
|
+
def test(self, text: str) -> bool:
|
|
179
|
+
compiled = self._get_compiled_pattern()
|
|
180
|
+
return bool(compiled.search(text))
|
|
181
|
+
|
|
182
|
+
def search(self, text: str) -> re.Match[str] | None:
|
|
183
|
+
if len(text) > MAX_INPUT_SIZE:
|
|
184
|
+
raise ValueError(
|
|
185
|
+
f"Input text too large: {len(text)} bytes > {MAX_INPUT_SIZE}"
|
|
186
|
+
)
|
|
187
|
+
return self._get_compiled_pattern().search(text)
|
|
188
|
+
|
|
189
|
+
def findall(self, text: str) -> list[str]:
|
|
190
|
+
if len(text) > MAX_INPUT_SIZE:
|
|
191
|
+
raise ValueError(
|
|
192
|
+
f"Input text too large: {len(text)} bytes > {MAX_INPUT_SIZE}"
|
|
193
|
+
)
|
|
194
|
+
return self._get_compiled_pattern().findall(text)
|
|
195
|
+
|
|
196
|
+
def get_performance_stats(
|
|
197
|
+
self, text: str, iterations: int = 100
|
|
198
|
+
) -> dict[str, float]:
|
|
199
|
+
times = []
|
|
200
|
+
|
|
201
|
+
for _ in range(iterations):
|
|
202
|
+
start = time.perf_counter()
|
|
203
|
+
self.apply(text)
|
|
204
|
+
end = time.perf_counter()
|
|
205
|
+
times.append(end - start)
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
"mean_time": sum(times) / len(times),
|
|
209
|
+
"min_time": min(times),
|
|
210
|
+
"max_time": max(times),
|
|
211
|
+
"total_time": sum(times),
|
|
212
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Documentation-related regex patterns.
|
|
2
|
+
|
|
3
|
+
This package provides patterns for working with documentation elements including
|
|
4
|
+
docstrings, markdown badges, links, comments, and code blocks.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .badges_markdown import PATTERNS as BADGES_MARKDOWN_PATTERNS
|
|
8
|
+
from .comments_blocks import PATTERNS as COMMENTS_BLOCKS_PATTERNS
|
|
9
|
+
from .docstrings import PATTERNS as DOCSTRINGS_PATTERNS
|
|
10
|
+
|
|
11
|
+
# Merge all documentation patterns into a single registry
|
|
12
|
+
PATTERNS = DOCSTRINGS_PATTERNS | BADGES_MARKDOWN_PATTERNS | COMMENTS_BLOCKS_PATTERNS
|
|
13
|
+
|
|
14
|
+
__all__ = ["PATTERNS"]
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""Badge and markdown link parsing patterns.
|
|
2
|
+
|
|
3
|
+
This module provides regex patterns for working with markdown syntax,
|
|
4
|
+
particularly coverage badges and links in README files.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from ..core import ValidatedPattern
|
|
10
|
+
|
|
11
|
+
PATTERNS = {
|
|
12
|
+
"detect_coverage_badge": ValidatedPattern(
|
|
13
|
+
name="detect_coverage_badge",
|
|
14
|
+
pattern=r"!\[Coverage.*?\]\(.*?coverage.*?\)|!\[.*coverage.*?\]\(.*?shields\.io.*?coverage.*?\)|https://img\.shields\.io/badge/coverage-[\d\.]+%25-\w+",
|
|
15
|
+
replacement="",
|
|
16
|
+
description="Detect existing coverage badges in README content",
|
|
17
|
+
flags=re.IGNORECASE,
|
|
18
|
+
test_cases=[
|
|
19
|
+
("", ""),
|
|
20
|
+
(
|
|
21
|
+
"",
|
|
22
|
+
"",
|
|
23
|
+
),
|
|
24
|
+
(
|
|
25
|
+
"https://img.shields.io/badge/coverage-95.5%25-brightgreen",
|
|
26
|
+
"",
|
|
27
|
+
),
|
|
28
|
+
(
|
|
29
|
+
"",
|
|
30
|
+
"",
|
|
31
|
+
),
|
|
32
|
+
("Some text without badge", "Some text without badge"),
|
|
33
|
+
],
|
|
34
|
+
),
|
|
35
|
+
"extract_markdown_links": ValidatedPattern(
|
|
36
|
+
name="extract_markdown_links",
|
|
37
|
+
pattern=r"\[([^\]]+)\]\(([^)]+)\)",
|
|
38
|
+
replacement=r"\1 -> \2",
|
|
39
|
+
description="Extract markdown link text and URLs from [text](url) patterns",
|
|
40
|
+
test_cases=[
|
|
41
|
+
("[Click here](http://example.com)", "Click here -> http://example.com"),
|
|
42
|
+
("[GitHub](https://github.com)", "GitHub -> https://github.com"),
|
|
43
|
+
(
|
|
44
|
+
"[Documentation](./docs/README.md)",
|
|
45
|
+
"Documentation -> ./docs/README.md",
|
|
46
|
+
),
|
|
47
|
+
("No links here", "No links here"),
|
|
48
|
+
],
|
|
49
|
+
),
|
|
50
|
+
"update_coverage_badge_any": ValidatedPattern(
|
|
51
|
+
name="update_coverage_badge_any",
|
|
52
|
+
pattern=r"(!\[.*coverage.*?\]\()([^)]+)(\))",
|
|
53
|
+
replacement=r"\1NEW_BADGE_URL\3",
|
|
54
|
+
description="Update any coverage-related badge URL",
|
|
55
|
+
flags=re.IGNORECASE,
|
|
56
|
+
test_cases=[
|
|
57
|
+
("", ""),
|
|
58
|
+
("", ""),
|
|
59
|
+
("", ""),
|
|
60
|
+
("", ""),
|
|
61
|
+
],
|
|
62
|
+
),
|
|
63
|
+
"update_coverage_badge_url": ValidatedPattern(
|
|
64
|
+
name="update_coverage_badge_url",
|
|
65
|
+
pattern=r"(!\[Coverage.*?\]\()([^)]+)(\))",
|
|
66
|
+
replacement=r"\1NEW_BADGE_URL\3",
|
|
67
|
+
description="Update coverage badge URL in markdown links",
|
|
68
|
+
test_cases=[
|
|
69
|
+
("", ""),
|
|
70
|
+
("", ""),
|
|
71
|
+
("text  more", "text  more"),
|
|
72
|
+
("no badge here", "no badge here"),
|
|
73
|
+
],
|
|
74
|
+
),
|
|
75
|
+
"update_shields_coverage_url": ValidatedPattern(
|
|
76
|
+
name="update_shields_coverage_url",
|
|
77
|
+
pattern=r"(https://img\.shields\.io/badge/coverage-[\d\.]+%25-\w+)",
|
|
78
|
+
replacement="NEW_BADGE_URL",
|
|
79
|
+
description="Update shields.io coverage badge URLs directly",
|
|
80
|
+
test_cases=[
|
|
81
|
+
(
|
|
82
|
+
"https://img.shields.io/badge/coverage-95.5%25-brightgreen",
|
|
83
|
+
"NEW_BADGE_URL",
|
|
84
|
+
),
|
|
85
|
+
(
|
|
86
|
+
"https://img.shields.io/badge/coverage-100%25-success",
|
|
87
|
+
"NEW_BADGE_URL",
|
|
88
|
+
),
|
|
89
|
+
(
|
|
90
|
+
"https://img.shields.io/badge/coverage-75.0%25-yellow",
|
|
91
|
+
"NEW_BADGE_URL",
|
|
92
|
+
),
|
|
93
|
+
("https://example.com/other-badge", "https://example.com/other-badge"),
|
|
94
|
+
],
|
|
95
|
+
),
|
|
96
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Comment and code block parsing patterns.
|
|
2
|
+
|
|
3
|
+
This module provides regex patterns for working with code comments,
|
|
4
|
+
TODO markers, and bash/command code blocks in documentation.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from ..core import ValidatedPattern
|
|
10
|
+
|
|
11
|
+
PATTERNS = {
|
|
12
|
+
"enhance_command_blocks": ValidatedPattern(
|
|
13
|
+
name="enhance_command_blocks",
|
|
14
|
+
pattern=r"```(?:bash|shell|sh)?\n([^`]+)\n```",
|
|
15
|
+
replacement=r"```bash\n\1\n```",
|
|
16
|
+
description="Enhance command blocks with proper bash syntax highlighting",
|
|
17
|
+
test_cases=[
|
|
18
|
+
("```\npython -m test\n```", "```bash\npython -m test\n```"),
|
|
19
|
+
("```bash\necho hello\n```", "```bash\necho hello\n```"),
|
|
20
|
+
("```sh\nls -la\n```", "```bash\nls -la\n```"),
|
|
21
|
+
("```shell\ncd /tmp\n```", "```bash\ncd /tmp\n```"),
|
|
22
|
+
],
|
|
23
|
+
),
|
|
24
|
+
"extract_bash_command_blocks": ValidatedPattern(
|
|
25
|
+
name="extract_bash_command_blocks",
|
|
26
|
+
pattern=r"```bash\n([^`]+)\n```",
|
|
27
|
+
replacement=r"\1",
|
|
28
|
+
description="Extract content from bash command blocks",
|
|
29
|
+
test_cases=[
|
|
30
|
+
("```bash\necho hello\n```", "echo hello"),
|
|
31
|
+
("```bash\npython -m test\n```", "python -m test"),
|
|
32
|
+
("text\n```bash\nls -la\n```\nmore", "text\nls -la\nmore"),
|
|
33
|
+
("```bash\nmulti\nline\ncommand\n```", "multi\nline\ncommand"),
|
|
34
|
+
],
|
|
35
|
+
),
|
|
36
|
+
"extract_step_numbers": ValidatedPattern(
|
|
37
|
+
name="extract_step_numbers",
|
|
38
|
+
pattern=r"^(\s*)(\d+)\.\s*(.+)$",
|
|
39
|
+
replacement=r"\1**Step \2**: \3",
|
|
40
|
+
description="Extract and enhance numbered steps in documentation",
|
|
41
|
+
flags=re.MULTILINE,
|
|
42
|
+
test_cases=[
|
|
43
|
+
("1. First step", "**Step 1**: First step"),
|
|
44
|
+
(" 2. Indented step", " **Step 2**: Indented step"),
|
|
45
|
+
("10. Double digit step", "**Step 10**: Double digit step"),
|
|
46
|
+
("normal text", "normal text"),
|
|
47
|
+
],
|
|
48
|
+
),
|
|
49
|
+
"preserved_comments": ValidatedPattern(
|
|
50
|
+
name="preserved_comments",
|
|
51
|
+
pattern=r"(#.*?(?: coding: | encoding: | type: | noqa | pragma).*)",
|
|
52
|
+
replacement=r"\1",
|
|
53
|
+
description="Match preserved code comments (encoding, type hints, etc.)",
|
|
54
|
+
test_cases=[
|
|
55
|
+
("# coding: utf-8", "# coding: utf-8"),
|
|
56
|
+
("# encoding: utf-8", "# encoding: utf-8"),
|
|
57
|
+
("# type: ignore", "# type: ignore"),
|
|
58
|
+
("# noqa: F401", "# noqa: F401"),
|
|
59
|
+
(
|
|
60
|
+
"x = 1 # type: int",
|
|
61
|
+
"x = 1 # type: int",
|
|
62
|
+
),
|
|
63
|
+
(
|
|
64
|
+
"# pragma: no cover",
|
|
65
|
+
"# pragma: no cover",
|
|
66
|
+
),
|
|
67
|
+
("# regular comment", "# regular comment"),
|
|
68
|
+
],
|
|
69
|
+
),
|
|
70
|
+
"todo_pattern": ValidatedPattern(
|
|
71
|
+
name="todo_pattern",
|
|
72
|
+
pattern=r"(#.*?TODO.*)",
|
|
73
|
+
replacement=r"\1",
|
|
74
|
+
flags=re.IGNORECASE,
|
|
75
|
+
description="Match TODO comments for validation",
|
|
76
|
+
test_cases=[
|
|
77
|
+
("# TODO: Fix this", "# TODO: Fix this"),
|
|
78
|
+
("# todo: implement feature", "# todo: implement feature"),
|
|
79
|
+
("# Todo: Update docs", "# Todo: Update docs"),
|
|
80
|
+
("# FIXME: not a TODO", "# FIXME: not a TODO"),
|
|
81
|
+
],
|
|
82
|
+
),
|
|
83
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Docstring parsing and manipulation patterns.
|
|
2
|
+
|
|
3
|
+
This module provides regex patterns for working with docstrings in various formats
|
|
4
|
+
including triple-quoted strings, Google-style, and Sphinx-style documentation.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from ..core import ValidatedPattern
|
|
10
|
+
|
|
11
|
+
PATTERNS = {
|
|
12
|
+
"docstring_triple_double": ValidatedPattern(
|
|
13
|
+
name="docstring_triple_double",
|
|
14
|
+
pattern=r'^\s*""".*?"""\s*$',
|
|
15
|
+
replacement=r"",
|
|
16
|
+
flags=re.MULTILINE | re.DOTALL,
|
|
17
|
+
description="Remove triple-quoted docstrings with double quotes",
|
|
18
|
+
test_cases=[
|
|
19
|
+
(' """This is a docstring""" ', ""),
|
|
20
|
+
('"""Module docstring"""', ""),
|
|
21
|
+
(' """\n Multi-line\n docstring\n """', ""),
|
|
22
|
+
(
|
|
23
|
+
'regular_code = "not a docstring"',
|
|
24
|
+
'regular_code = "not a docstring"',
|
|
25
|
+
),
|
|
26
|
+
],
|
|
27
|
+
),
|
|
28
|
+
"docstring_triple_single": ValidatedPattern(
|
|
29
|
+
name="docstring_triple_single",
|
|
30
|
+
pattern=r"^\s*'''.*?'''\s*$",
|
|
31
|
+
replacement=r"",
|
|
32
|
+
flags=re.MULTILINE | re.DOTALL,
|
|
33
|
+
description="Remove triple-quoted docstrings with single quotes",
|
|
34
|
+
test_cases=[
|
|
35
|
+
(" '''This is a docstring''' ", ""),
|
|
36
|
+
("'''Module docstring'''", ""),
|
|
37
|
+
(" '''\n Multi-line\n docstring\n '''", ""),
|
|
38
|
+
(
|
|
39
|
+
"regular_code = 'not a docstring'",
|
|
40
|
+
"regular_code = 'not a docstring'",
|
|
41
|
+
),
|
|
42
|
+
],
|
|
43
|
+
),
|
|
44
|
+
"extract_docstring_returns": ValidatedPattern(
|
|
45
|
+
name="extract_docstring_returns",
|
|
46
|
+
pattern=r"(?:Returns?|Return):\s*(.+?)(?=\n\n|\n\w+:|\Z)",
|
|
47
|
+
replacement=r"\1",
|
|
48
|
+
description="Extract return descriptions from docstrings",
|
|
49
|
+
flags=re.MULTILINE | re.DOTALL,
|
|
50
|
+
test_cases=[
|
|
51
|
+
("Returns: Simple value", "Simple value"),
|
|
52
|
+
("Return: Another form", "Another form"),
|
|
53
|
+
("Returns: Multi-line\n description", "Multi-line\n description"),
|
|
54
|
+
("Returns: Simple value\n\nArgs:", "Simple value\n\nArgs:"),
|
|
55
|
+
],
|
|
56
|
+
),
|
|
57
|
+
"extract_google_docstring_params": ValidatedPattern(
|
|
58
|
+
name="extract_google_docstring_params",
|
|
59
|
+
pattern=r"^\s*(\w+)(?:\s*\([^)]+\))?\s*:\s*(.+)$",
|
|
60
|
+
replacement=r"\1: \2",
|
|
61
|
+
description="Extract parameter names and descriptions from Google-style docstrings",
|
|
62
|
+
flags=re.MULTILINE,
|
|
63
|
+
test_cases=[
|
|
64
|
+
("name (str): Description here", "name: Description here"),
|
|
65
|
+
("count (int): Number of items", "count: Number of items"),
|
|
66
|
+
(
|
|
67
|
+
"complex_param (Optional[Dict[str, Any]]): Complex type",
|
|
68
|
+
"complex_param: Complex type",
|
|
69
|
+
),
|
|
70
|
+
("simple: Simple desc", "simple: Simple desc"),
|
|
71
|
+
],
|
|
72
|
+
),
|
|
73
|
+
"extract_sphinx_docstring_params": ValidatedPattern(
|
|
74
|
+
name="extract_sphinx_docstring_params",
|
|
75
|
+
pattern=r":param\s+(\w+)\s*:\s*(.+)$",
|
|
76
|
+
replacement=r"\1: \2",
|
|
77
|
+
description="Extract parameter names and descriptions from Sphinx-style docstrings",
|
|
78
|
+
flags=re.MULTILINE,
|
|
79
|
+
test_cases=[
|
|
80
|
+
(":param name: Description here", "name: Description here"),
|
|
81
|
+
(":param count: Number of items", "count: Number of items"),
|
|
82
|
+
(":param my_var: Simple description", "my_var: Simple description"),
|
|
83
|
+
(
|
|
84
|
+
":param complex_var: Multi-word description here",
|
|
85
|
+
"complex_var: Multi-word description here",
|
|
86
|
+
),
|
|
87
|
+
],
|
|
88
|
+
),
|
|
89
|
+
}
|