roadmap-cli 0.1.1__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.
- roadmap/__init__.py +27 -0
- roadmap/adapters/__init__.py +1 -0
- roadmap/adapters/base_paginated_adapter.py +117 -0
- roadmap/adapters/cli/__init__.py +249 -0
- roadmap/adapters/cli/analysis/__init__.py +5 -0
- roadmap/adapters/cli/analysis/commands.py +370 -0
- roadmap/adapters/cli/analysis/presenter.py +125 -0
- roadmap/adapters/cli/archive_operations.py +86 -0
- roadmap/adapters/cli/cli_command_helpers.py +109 -0
- roadmap/adapters/cli/cli_confirmations.py +74 -0
- roadmap/adapters/cli/cli_error_handlers.py +146 -0
- roadmap/adapters/cli/cli_validators.py +39 -0
- roadmap/adapters/cli/commands/sync_status.py +308 -0
- roadmap/adapters/cli/comment/__init__.py +5 -0
- roadmap/adapters/cli/comment/commands.py +106 -0
- roadmap/adapters/cli/config/__init__.py +5 -0
- roadmap/adapters/cli/config/commands.py +198 -0
- roadmap/adapters/cli/console_exports.py +10 -0
- roadmap/adapters/cli/core.py +26 -0
- roadmap/adapters/cli/crud/__init__.py +47 -0
- roadmap/adapters/cli/crud/base_archive.py +208 -0
- roadmap/adapters/cli/crud/base_create.py +154 -0
- roadmap/adapters/cli/crud/base_delete.py +155 -0
- roadmap/adapters/cli/crud/base_restore.py +283 -0
- roadmap/adapters/cli/crud/base_update.py +193 -0
- roadmap/adapters/cli/crud/crud_helpers.py +206 -0
- roadmap/adapters/cli/crud/crud_utils.py +152 -0
- roadmap/adapters/cli/crud/entity_builders.py +374 -0
- roadmap/adapters/cli/data/__init__.py +8 -0
- roadmap/adapters/cli/data/commands.py +149 -0
- roadmap/adapters/cli/decorators.py +208 -0
- roadmap/adapters/cli/dtos/__init__.py +155 -0
- roadmap/adapters/cli/exception_handler.py +105 -0
- roadmap/adapters/cli/git/__init__.py +8 -0
- roadmap/adapters/cli/git/commands.py +475 -0
- roadmap/adapters/cli/git/handlers/__init__.py +1 -0
- roadmap/adapters/cli/git/handlers/git_authentication_handler.py +124 -0
- roadmap/adapters/cli/git/handlers/git_branch_handler.py +238 -0
- roadmap/adapters/cli/git/handlers/git_connectivity_handler.py +122 -0
- roadmap/adapters/cli/git/handlers/git_hooks_handler.py +105 -0
- roadmap/adapters/cli/git/hooks_config.py +327 -0
- roadmap/adapters/cli/git/status_display.py +158 -0
- roadmap/adapters/cli/health/__init__.py +8 -0
- roadmap/adapters/cli/health/db_integrity.py +204 -0
- roadmap/adapters/cli/health/enhancer.py +227 -0
- roadmap/adapters/cli/health/fixer.py +295 -0
- roadmap/adapters/cli/health/fixers/__init__.py +10 -0
- roadmap/adapters/cli/health/fixers/corrupted_comments_fixer.py +231 -0
- roadmap/adapters/cli/health/fixers/data_integrity_fixer.py +137 -0
- roadmap/adapters/cli/health/fixers/duplicate_issues_fixer.py +138 -0
- roadmap/adapters/cli/health/fixers/folder_structure_fixer.py +114 -0
- roadmap/adapters/cli/health/fixers/label_normalization_fixer.py +162 -0
- roadmap/adapters/cli/health/fixers/milestone_name_normalization_fixer.py +181 -0
- roadmap/adapters/cli/health/fixers/milestone_naming_compliance_fixer.py +244 -0
- roadmap/adapters/cli/health/fixers/milestone_parse_error_fixer.py +162 -0
- roadmap/adapters/cli/health/fixers/milestone_validation_fixer.py +211 -0
- roadmap/adapters/cli/health/fixers/old_backups_fixer.py +135 -0
- roadmap/adapters/cli/health/fixers/orphaned_issues_fixer.py +252 -0
- roadmap/adapters/cli/health/formatter.py +250 -0
- roadmap/adapters/cli/health/formatters.py +427 -0
- roadmap/adapters/cli/health/scan.py +293 -0
- roadmap/adapters/cli/init/__init__.py +5 -0
- roadmap/adapters/cli/init/commands.py +587 -0
- roadmap/adapters/cli/init.py +9 -0
- roadmap/adapters/cli/issues/__init__.py +70 -0
- roadmap/adapters/cli/issues/archive.py +137 -0
- roadmap/adapters/cli/issues/archive_class.py +253 -0
- roadmap/adapters/cli/issues/block.py +39 -0
- roadmap/adapters/cli/issues/close.py +216 -0
- roadmap/adapters/cli/issues/comment.py +178 -0
- roadmap/adapters/cli/issues/create.py +162 -0
- roadmap/adapters/cli/issues/delete.py +31 -0
- roadmap/adapters/cli/issues/deps.py +161 -0
- roadmap/adapters/cli/issues/issue_status_helpers.py +111 -0
- roadmap/adapters/cli/issues/link.py +308 -0
- roadmap/adapters/cli/issues/list.py +402 -0
- roadmap/adapters/cli/issues/lookup.py +96 -0
- roadmap/adapters/cli/issues/progress.py +102 -0
- roadmap/adapters/cli/issues/restore.py +96 -0
- roadmap/adapters/cli/issues/restore_class.py +57 -0
- roadmap/adapters/cli/issues/start.py +165 -0
- roadmap/adapters/cli/issues/sync_status.py +374 -0
- roadmap/adapters/cli/issues/unblock.py +43 -0
- roadmap/adapters/cli/issues/unlink.py +104 -0
- roadmap/adapters/cli/issues/update.py +120 -0
- roadmap/adapters/cli/issues/view.py +36 -0
- roadmap/adapters/cli/layout.py +220 -0
- roadmap/adapters/cli/mappers.py +200 -0
- roadmap/adapters/cli/milestones/__init__.py +52 -0
- roadmap/adapters/cli/milestones/archive.py +125 -0
- roadmap/adapters/cli/milestones/archive_class.py +236 -0
- roadmap/adapters/cli/milestones/assign.py +62 -0
- roadmap/adapters/cli/milestones/close.py +177 -0
- roadmap/adapters/cli/milestones/create.py +131 -0
- roadmap/adapters/cli/milestones/delete.py +27 -0
- roadmap/adapters/cli/milestones/kanban.py +123 -0
- roadmap/adapters/cli/milestones/list.py +87 -0
- roadmap/adapters/cli/milestones/recalculate.py +79 -0
- roadmap/adapters/cli/milestones/restore.py +87 -0
- roadmap/adapters/cli/milestones/restore_class.py +99 -0
- roadmap/adapters/cli/milestones/update.py +61 -0
- roadmap/adapters/cli/milestones/view.py +142 -0
- roadmap/adapters/cli/output_manager.py +319 -0
- roadmap/adapters/cli/presentation/base_presenter.py +121 -0
- roadmap/adapters/cli/presentation/cleanup_presenter.py +235 -0
- roadmap/adapters/cli/presentation/core_initialization_presenter.py +277 -0
- roadmap/adapters/cli/presentation/crud_presenter.py +134 -0
- roadmap/adapters/cli/presentation/daily_summary_presenter.py +266 -0
- roadmap/adapters/cli/presentation/issue_presenter.py +258 -0
- roadmap/adapters/cli/presentation/milestone_list_presenter.py +135 -0
- roadmap/adapters/cli/presentation/milestone_presenter.py +297 -0
- roadmap/adapters/cli/presentation/project_presenter.py +233 -0
- roadmap/adapters/cli/presentation/project_status_presenter.py +186 -0
- roadmap/adapters/cli/presentation/table_builders.py +95 -0
- roadmap/adapters/cli/projects/__init__.py +42 -0
- roadmap/adapters/cli/projects/archive.py +127 -0
- roadmap/adapters/cli/projects/archive_class.py +96 -0
- roadmap/adapters/cli/projects/close.py +94 -0
- roadmap/adapters/cli/projects/create.py +50 -0
- roadmap/adapters/cli/projects/delete.py +27 -0
- roadmap/adapters/cli/projects/list.py +227 -0
- roadmap/adapters/cli/projects/restore.py +87 -0
- roadmap/adapters/cli/projects/restore_class.py +56 -0
- roadmap/adapters/cli/projects/update.py +57 -0
- roadmap/adapters/cli/projects/view.py +157 -0
- roadmap/adapters/cli/services/__init__.py +1 -0
- roadmap/adapters/cli/services/daily_summary_service.py +313 -0
- roadmap/adapters/cli/services/export_manager.py +268 -0
- roadmap/adapters/cli/services/milestone_list_service.py +266 -0
- roadmap/adapters/cli/services/project_initialization_service.py +29 -0
- roadmap/adapters/cli/services/project_status_service.py +462 -0
- roadmap/adapters/cli/services/sync_service.py +62 -0
- roadmap/adapters/cli/status.py +408 -0
- roadmap/adapters/cli/styling.py +21 -0
- roadmap/adapters/cli/sync.py +1117 -0
- roadmap/adapters/cli/sync_context.py +432 -0
- roadmap/adapters/cli/sync_handlers/__init__.py +77 -0
- roadmap/adapters/cli/sync_handlers/apply_ops.py +522 -0
- roadmap/adapters/cli/sync_handlers/baseline_ops.py +366 -0
- roadmap/adapters/cli/sync_handlers/conflict_ops.py +161 -0
- roadmap/adapters/cli/sync_handlers/dry_run_display.py +237 -0
- roadmap/adapters/cli/sync_handlers/interactive_resolver.py +396 -0
- roadmap/adapters/cli/sync_handlers/progress_tracker.py +128 -0
- roadmap/adapters/cli/sync_metrics_command.py +190 -0
- roadmap/adapters/cli/sync_presenter.py +58 -0
- roadmap/adapters/cli/sync_validation.py +295 -0
- roadmap/adapters/cli/today.py +52 -0
- roadmap/adapters/cli/utils/click_options.py +38 -0
- roadmap/adapters/git/__init__.py +1 -0
- roadmap/adapters/git/git.py +208 -0
- roadmap/adapters/git/git_branch_manager.py +400 -0
- roadmap/adapters/git/git_command_executor.py +56 -0
- roadmap/adapters/git/git_commit_analyzer.py +334 -0
- roadmap/adapters/git/git_hooks.py +22 -0
- roadmap/adapters/git/git_hooks_manager.py +455 -0
- roadmap/adapters/git/git_repository_info.py +65 -0
- roadmap/adapters/git/hook_installer.py +106 -0
- roadmap/adapters/git/hook_registry.py +97 -0
- roadmap/adapters/git/hook_script_generator.py +58 -0
- roadmap/adapters/git/sync_monitor.py +409 -0
- roadmap/adapters/git/workflow_automation.py +286 -0
- roadmap/adapters/github/__init__.py +1 -0
- roadmap/adapters/github/github.py +360 -0
- roadmap/adapters/github/handlers/__init__.py +17 -0
- roadmap/adapters/github/handlers/base.py +337 -0
- roadmap/adapters/github/handlers/collaborators.py +165 -0
- roadmap/adapters/github/handlers/comments.py +118 -0
- roadmap/adapters/github/handlers/issues.py +150 -0
- roadmap/adapters/github/handlers/labels.py +164 -0
- roadmap/adapters/github/handlers/milestones.py +104 -0
- roadmap/adapters/persistence/__init__.py +35 -0
- roadmap/adapters/persistence/conflict_resolver.py +190 -0
- roadmap/adapters/persistence/database_manager.py +492 -0
- roadmap/adapters/persistence/entity_sync_coordinators.py +672 -0
- roadmap/adapters/persistence/file_locking.py +348 -0
- roadmap/adapters/persistence/file_parser.py +92 -0
- roadmap/adapters/persistence/file_synchronizer.py +107 -0
- roadmap/adapters/persistence/focused_managers.py +140 -0
- roadmap/adapters/persistence/git_history.py +330 -0
- roadmap/adapters/persistence/parser/__init__.py +20 -0
- roadmap/adapters/persistence/parser/frontmatter.py +152 -0
- roadmap/adapters/persistence/parser/issue.py +245 -0
- roadmap/adapters/persistence/parser/milestone.py +146 -0
- roadmap/adapters/persistence/parser/project.py +106 -0
- roadmap/adapters/persistence/persistence.py +288 -0
- roadmap/adapters/persistence/repositories/__init__.py +15 -0
- roadmap/adapters/persistence/repositories/issue_repository.py +223 -0
- roadmap/adapters/persistence/repositories/milestone_repository.py +140 -0
- roadmap/adapters/persistence/repositories/project_repository.py +168 -0
- roadmap/adapters/persistence/repositories/remote_link_repository.py +355 -0
- roadmap/adapters/persistence/repositories/sync_state_repository.py +66 -0
- roadmap/adapters/persistence/storage/__init__.py +36 -0
- roadmap/adapters/persistence/storage/conflicts.py +101 -0
- roadmap/adapters/persistence/storage/connection_manager.py +79 -0
- roadmap/adapters/persistence/storage/issue_storage.py +89 -0
- roadmap/adapters/persistence/storage/milestone_storage.py +80 -0
- roadmap/adapters/persistence/storage/project_storage.py +102 -0
- roadmap/adapters/persistence/storage/queries.py +227 -0
- roadmap/adapters/persistence/storage/state_manager.py +652 -0
- roadmap/adapters/persistence/storage/sync_state_storage.py +207 -0
- roadmap/adapters/persistence/sync_metrics_repository.py +342 -0
- roadmap/adapters/persistence/sync_orchestrator.py +293 -0
- roadmap/adapters/persistence/sync_state_tracker.py +86 -0
- roadmap/adapters/persistence/yaml_repositories.py +711 -0
- roadmap/adapters/sync/__init__.py +21 -0
- roadmap/adapters/sync/backend_factory.py +108 -0
- roadmap/adapters/sync/backends/__init__.py +15 -0
- roadmap/adapters/sync/backends/converters.py +209 -0
- roadmap/adapters/sync/backends/github_backend_helpers.py +380 -0
- roadmap/adapters/sync/backends/github_client.py +99 -0
- roadmap/adapters/sync/backends/github_sync_backend.py +792 -0
- roadmap/adapters/sync/backends/github_sync_ops.py +908 -0
- roadmap/adapters/sync/backends/services/__init__.py +1 -0
- roadmap/adapters/sync/backends/services/github_authentication_service.py +105 -0
- roadmap/adapters/sync/backends/services/github_issue_delete_service.py +423 -0
- roadmap/adapters/sync/backends/services/github_issue_dependency_service.py +63 -0
- roadmap/adapters/sync/backends/services/github_issue_fetch_service.py +158 -0
- roadmap/adapters/sync/backends/services/github_label_sync_service.py +126 -0
- roadmap/adapters/sync/backends/services/github_local_issue_sync_service.py +229 -0
- roadmap/adapters/sync/backends/services/github_milestone_fetch_service.py +204 -0
- roadmap/adapters/sync/backends/vanilla_git_sync_backend.py +198 -0
- roadmap/adapters/sync/services/__init__.py +11 -0
- roadmap/adapters/sync/services/baseline_state_handler.py +83 -0
- roadmap/adapters/sync/services/conflict_converter.py +85 -0
- roadmap/adapters/sync/services/issue_persistence_service.py +263 -0
- roadmap/adapters/sync/services/issue_state_service.py +243 -0
- roadmap/adapters/sync/services/local_change_filter.py +129 -0
- roadmap/adapters/sync/services/pull_result_processor.py +71 -0
- roadmap/adapters/sync/services/remote_issue_creation_service.py +112 -0
- roadmap/adapters/sync/services/sync_analysis_service.py +250 -0
- roadmap/adapters/sync/services/sync_authentication_service.py +57 -0
- roadmap/adapters/sync/services/sync_data_fetch_service.py +212 -0
- roadmap/adapters/sync/services/sync_linking_service.py +329 -0
- roadmap/adapters/sync/services/sync_report_service.py +62 -0
- roadmap/adapters/sync/services/sync_state_update_service.py +51 -0
- roadmap/adapters/sync/sync_cache_orchestrator.py +454 -0
- roadmap/adapters/sync/sync_merge_engine.py +416 -0
- roadmap/adapters/sync/sync_merge_orchestrator.py +1313 -0
- roadmap/adapters/sync/sync_retrieval_orchestrator.py +810 -0
- roadmap/application/services/__init__.py +1 -0
- roadmap/application/services/deduplicate_service.py +517 -0
- roadmap/application/use_cases/__init__.py +1 -0
- roadmap/common/__init__.py +308 -0
- roadmap/common/cache.py +209 -0
- roadmap/common/cli_errors.py +147 -0
- roadmap/common/configuration/__init__.py +33 -0
- roadmap/common/configuration/config_loader.py +264 -0
- roadmap/common/configuration/config_manager.py +164 -0
- roadmap/common/configuration/config_schema.py +145 -0
- roadmap/common/configuration/github/__init__.py +9 -0
- roadmap/common/configuration/github/config_manager.py +154 -0
- roadmap/common/configuration/github/token_resolver.py +84 -0
- roadmap/common/console.py +184 -0
- roadmap/common/constants.py +134 -0
- roadmap/common/datetime_parser.py +319 -0
- roadmap/common/error_formatter.py +84 -0
- roadmap/common/errors/__init__.py +143 -0
- roadmap/common/errors/error_base.py +73 -0
- roadmap/common/errors/error_file.py +82 -0
- roadmap/common/errors/error_git.py +67 -0
- roadmap/common/errors/error_handler.py +166 -0
- roadmap/common/errors/error_network.py +90 -0
- roadmap/common/errors/error_security.py +78 -0
- roadmap/common/errors/error_standards.py +561 -0
- roadmap/common/errors/error_validation.py +111 -0
- roadmap/common/errors/exceptions.py +432 -0
- roadmap/common/formatters/__init__.py +29 -0
- roadmap/common/formatters/base_table_formatter.py +96 -0
- roadmap/common/formatters/export/__init__.py +7 -0
- roadmap/common/formatters/export/issue_exporter.py +97 -0
- roadmap/common/formatters/helpers.py +28 -0
- roadmap/common/formatters/kanban/__init__.py +9 -0
- roadmap/common/formatters/kanban/layout.py +48 -0
- roadmap/common/formatters/kanban/organizer.py +81 -0
- roadmap/common/formatters/output/__init__.py +15 -0
- roadmap/common/formatters/tables/__init__.py +11 -0
- roadmap/common/formatters/tables/column_factory.py +312 -0
- roadmap/common/formatters/tables/issue_table.py +276 -0
- roadmap/common/formatters/tables/milestone_table.py +247 -0
- roadmap/common/formatters/tables/project_table.py +195 -0
- roadmap/common/formatters/text/__init__.py +57 -0
- roadmap/common/formatters/text/basic.py +217 -0
- roadmap/common/formatters/text/display.py +42 -0
- roadmap/common/formatters/text/duration.py +36 -0
- roadmap/common/formatters/text/operations.py +325 -0
- roadmap/common/formatters/text/status_badges.py +57 -0
- roadmap/common/initialization/github/__init__.py +11 -0
- roadmap/common/initialization/github/setup_service.py +238 -0
- roadmap/common/initialization/github/setup_validator.py +78 -0
- roadmap/common/logging/__init__.py +113 -0
- roadmap/common/logging/audit_logging.py +5 -0
- roadmap/common/logging/correlation.py +45 -0
- roadmap/common/logging/decorators.py +267 -0
- roadmap/common/logging/error_logging.py +217 -0
- roadmap/common/logging/formatters.py +124 -0
- roadmap/common/logging/loggers.py +68 -0
- roadmap/common/logging/performance_tracking.py +267 -0
- roadmap/common/logging/utils.py +335 -0
- roadmap/common/models/__init__.py +44 -0
- roadmap/common/models/cli_models.py +118 -0
- roadmap/common/models/config_models.py +199 -0
- roadmap/common/models/output_models.py +381 -0
- roadmap/common/observability/__init__.py +28 -0
- roadmap/common/observability/instrumentation.py +103 -0
- roadmap/common/observability/observability.py +76 -0
- roadmap/common/observability/otel_init.py +109 -0
- roadmap/common/output_formatter.py +393 -0
- roadmap/common/progress.py +379 -0
- roadmap/common/result.py +396 -0
- roadmap/common/security/__init__.py +48 -0
- roadmap/common/security/exceptions.py +13 -0
- roadmap/common/security/export_cleanup.py +79 -0
- roadmap/common/security/file_operations.py +104 -0
- roadmap/common/security/filename_sanitization.py +54 -0
- roadmap/common/security/logging.py +27 -0
- roadmap/common/security/path_validation.py +137 -0
- roadmap/common/security/temp_files.py +41 -0
- roadmap/common/services/__init__.py +65 -0
- roadmap/common/services/decorators.py +183 -0
- roadmap/common/services/logging_utils.py +208 -0
- roadmap/common/services/metrics.py +161 -0
- roadmap/common/services/performance.py +219 -0
- roadmap/common/services/profiling.py +288 -0
- roadmap/common/services/retry.py +288 -0
- roadmap/common/status_style_manager.py +114 -0
- roadmap/common/union_find.py +88 -0
- roadmap/common/update_constants.py +13 -0
- roadmap/common/utils/__init__.py +65 -0
- roadmap/common/utils/cli_helpers.py +381 -0
- roadmap/common/utils/file_utils.py +440 -0
- roadmap/common/utils/path_utils.py +38 -0
- roadmap/common/utils/status_utils.py +130 -0
- roadmap/common/utils/timezone_utils.py +480 -0
- roadmap/common/validation/__init__.py +37 -0
- roadmap/common/validation/field_validator.py +104 -0
- roadmap/common/validation/result.py +37 -0
- roadmap/common/validation/roadmap_validator.py +310 -0
- roadmap/common/validation/schema_validator.py +36 -0
- roadmap/common/validation/validators.py +50 -0
- roadmap/core/__init__.py +1 -0
- roadmap/core/domain/__init__.py +30 -0
- roadmap/core/domain/comment.py +24 -0
- roadmap/core/domain/health.py +15 -0
- roadmap/core/domain/issue.py +274 -0
- roadmap/core/domain/milestone.py +173 -0
- roadmap/core/domain/ports/__init__.py +1 -0
- roadmap/core/domain/ports/baseline_repository.py +24 -0
- roadmap/core/domain/ports/issue_repository.py +34 -0
- roadmap/core/domain/ports/remote_backend_port.py +31 -0
- roadmap/core/domain/project.py +130 -0
- roadmap/core/interfaces/__init__.py +109 -0
- roadmap/core/interfaces/assignee_validator.py +40 -0
- roadmap/core/interfaces/backend_factory.py +175 -0
- roadmap/core/interfaces/github.py +102 -0
- roadmap/core/interfaces/parsers.py +140 -0
- roadmap/core/interfaces/persistence.py +45 -0
- roadmap/core/interfaces/repositories.py +174 -0
- roadmap/core/interfaces/state_managers.py +111 -0
- roadmap/core/interfaces/state_storage.py +64 -0
- roadmap/core/interfaces/sync_backend.py +275 -0
- roadmap/core/interfaces/sync_services.py +119 -0
- roadmap/core/interfaces/sync_validators.py +180 -0
- roadmap/core/models/__init__.py +31 -0
- roadmap/core/models/sync_models.py +162 -0
- roadmap/core/models.py +115 -0
- roadmap/core/observability/__init__.py +17 -0
- roadmap/core/observability/sync_metrics.py +699 -0
- roadmap/core/repositories.py +200 -0
- roadmap/core/services/__init__.py +313 -0
- roadmap/core/services/baseline/__init__.py +1 -0
- roadmap/core/services/baseline/baseline_builder_progress.py +274 -0
- roadmap/core/services/baseline/baseline_retriever.py +63 -0
- roadmap/core/services/baseline/baseline_selector.py +248 -0
- roadmap/core/services/baseline/baseline_state_retriever.py +284 -0
- roadmap/core/services/baseline/optimized_baseline_builder.py +425 -0
- roadmap/core/services/comment/__init__.py +1 -0
- roadmap/core/services/comment/comment_service.py +277 -0
- roadmap/core/services/git/__init__.py +1 -0
- roadmap/core/services/git/git_hook_auto_sync_service.py +403 -0
- roadmap/core/services/github/__init__.py +1 -0
- roadmap/core/services/github/github_change_detector.py +162 -0
- roadmap/core/services/github/github_config_validator.py +148 -0
- roadmap/core/services/github/github_conflict_detector.py +179 -0
- roadmap/core/services/github/github_entity_classifier.py +51 -0
- roadmap/core/services/github/github_integration_service.py +439 -0
- roadmap/core/services/github/github_issue_client.py +346 -0
- roadmap/core/services/health/__init__.py +1 -0
- roadmap/core/services/health/backup_cleanup_service.py +202 -0
- roadmap/core/services/health/data_integrity_validator_service.py +90 -0
- roadmap/core/services/health/entity_health_scanner.py +460 -0
- roadmap/core/services/health/file_repair_service.py +193 -0
- roadmap/core/services/health/health_check_service.py +166 -0
- roadmap/core/services/health/health_models.py +80 -0
- roadmap/core/services/health/infrastructure_validator_service.py +328 -0
- roadmap/core/services/health/issue_health_scanner.py +263 -0
- roadmap/core/services/helpers/__init__.py +18 -0
- roadmap/core/services/helpers/status_change_helpers.py +88 -0
- roadmap/core/services/initialization/__init__.py +19 -0
- roadmap/core/services/initialization/utils.py +104 -0
- roadmap/core/services/initialization/validator.py +78 -0
- roadmap/core/services/initialization/workflow.py +182 -0
- roadmap/core/services/initialization_service.py +111 -0
- roadmap/core/services/issue/__init__.py +1 -0
- roadmap/core/services/issue/assignee_validation_service.py +312 -0
- roadmap/core/services/issue/issue_creation_service.py +309 -0
- roadmap/core/services/issue/issue_filter_service.py +302 -0
- roadmap/core/services/issue/issue_matching_service.py +127 -0
- roadmap/core/services/issue/issue_service.py +765 -0
- roadmap/core/services/issue/issue_update_service.py +144 -0
- roadmap/core/services/issue/start_issue_service.py +174 -0
- roadmap/core/services/issue_helpers/__init__.py +18 -0
- roadmap/core/services/issue_helpers/issue_filters.py +296 -0
- roadmap/core/services/milestone_service.py +438 -0
- roadmap/core/services/project/__init__.py +1 -0
- roadmap/core/services/project/project_service.py +434 -0
- roadmap/core/services/project/project_status_service.py +125 -0
- roadmap/core/services/project_init/__init__.py +22 -0
- roadmap/core/services/project_init/context_detection.py +146 -0
- roadmap/core/services/project_init/creation.py +76 -0
- roadmap/core/services/project_init/detection.py +51 -0
- roadmap/core/services/project_init/template.py +228 -0
- roadmap/core/services/status_change_service.py +88 -0
- roadmap/core/services/sync/__init__.py +1 -0
- roadmap/core/services/sync/batch_processor.py +290 -0
- roadmap/core/services/sync/conflict_resolver.py +154 -0
- roadmap/core/services/sync/dependency_resolver.py +367 -0
- roadmap/core/services/sync/duplicate_detector.py +771 -0
- roadmap/core/services/sync/duplicate_resolver.py +315 -0
- roadmap/core/services/sync/error_classification.py +470 -0
- roadmap/core/services/sync/performance.py +263 -0
- roadmap/core/services/sync/sync_change_computer.py +211 -0
- roadmap/core/services/sync/sync_checkpoint.py +348 -0
- roadmap/core/services/sync/sync_conflict_detector.py +147 -0
- roadmap/core/services/sync/sync_conflict_resolver.py +448 -0
- roadmap/core/services/sync/sync_errors.py +383 -0
- roadmap/core/services/sync/sync_key_normalizer.py +222 -0
- roadmap/core/services/sync/sync_metadata_service.py +361 -0
- roadmap/core/services/sync/sync_plan.py +171 -0
- roadmap/core/services/sync/sync_plan_executor.py +447 -0
- roadmap/core/services/sync/sync_report.py +296 -0
- roadmap/core/services/sync/sync_state.py +173 -0
- roadmap/core/services/sync/sync_state_comparator.py +690 -0
- roadmap/core/services/sync/sync_state_manager.py +431 -0
- roadmap/core/services/sync/sync_state_normalizer.py +98 -0
- roadmap/core/services/sync/sync_three_way.py +78 -0
- roadmap/core/services/sync/three_way_merger.py +178 -0
- roadmap/core/services/utils/__init__.py +1 -0
- roadmap/core/services/utils/configuration_service.py +113 -0
- roadmap/core/services/utils/critical_path_calculator.py +418 -0
- roadmap/core/services/utils/dependency_analyzer.py +360 -0
- roadmap/core/services/utils/field_conflict_detector.py +126 -0
- roadmap/core/services/utils/remote_fetcher.py +202 -0
- roadmap/core/services/utils/remote_state_normalizer.py +110 -0
- roadmap/core/services/utils/retry_policy.py +51 -0
- roadmap/core/services/validator_base.py +130 -0
- roadmap/core/services/validators/__init__.py +28 -0
- roadmap/core/services/validators/_utils.py +20 -0
- roadmap/core/services/validators/archivable_issues_validator.py +71 -0
- roadmap/core/services/validators/archivable_milestones_validator.py +69 -0
- roadmap/core/services/validators/backup_validator.py +89 -0
- roadmap/core/services/validators/data_integrity_validator.py +84 -0
- roadmap/core/services/validators/duplicate_issues_validator.py +75 -0
- roadmap/core/services/validators/duplicate_milestones_validator.py +141 -0
- roadmap/core/services/validators/folder_structure_validator.py +165 -0
- roadmap/core/services/validators/health_status_utils.py +28 -0
- roadmap/core/services/validators/milestone_naming_validator.py +146 -0
- roadmap/core/services/validators/missing_headlines_validator.py +97 -0
- roadmap/core/services/validators/orphaned_issues_validator.py +142 -0
- roadmap/core/services/validators/orphaned_milestones_validator.py +85 -0
- roadmap/core/utils/git_remote_parser.py +83 -0
- roadmap/core/utils/github_urls.py +66 -0
- roadmap/domain/validation.py +30 -0
- roadmap/infrastructure/__init__.py +55 -0
- roadmap/infrastructure/coordination/__init__.py +8 -0
- roadmap/infrastructure/coordination/coordinator_params.py +82 -0
- roadmap/infrastructure/coordination/core.py +446 -0
- roadmap/infrastructure/coordination/git_coordinator.py +160 -0
- roadmap/infrastructure/coordination/initialization.py +348 -0
- roadmap/infrastructure/coordination/issue_coordinator.py +154 -0
- roadmap/infrastructure/coordination/issue_operations.py +456 -0
- roadmap/infrastructure/coordination/milestone_coordinator.py +135 -0
- roadmap/infrastructure/coordination/milestone_operations.py +201 -0
- roadmap/infrastructure/coordination/project_coordinator.py +113 -0
- roadmap/infrastructure/coordination/project_operations.py +144 -0
- roadmap/infrastructure/coordination/team_coordinator.py +107 -0
- roadmap/infrastructure/coordination/user_operations.py +150 -0
- roadmap/infrastructure/coordination/validation_coordinator.py +249 -0
- roadmap/infrastructure/coordination_gateway.py +152 -0
- roadmap/infrastructure/git/__init__.py +6 -0
- roadmap/infrastructure/git/git_integration_ops.py +234 -0
- roadmap/infrastructure/git_gateway.py +35 -0
- roadmap/infrastructure/github_gateway.py +52 -0
- roadmap/infrastructure/maintenance/__init__.py +5 -0
- roadmap/infrastructure/maintenance/cleanup.py +483 -0
- roadmap/infrastructure/observability/__init__.py +7 -0
- roadmap/infrastructure/observability/health.py +196 -0
- roadmap/infrastructure/observability/health_formatter.py +73 -0
- roadmap/infrastructure/observability/specialized_health_checkers.py +188 -0
- roadmap/infrastructure/persistence_gateway.py +164 -0
- roadmap/infrastructure/security/__init__.py +1 -0
- roadmap/infrastructure/security/credentials.py +489 -0
- roadmap/infrastructure/sync_gateway.py +94 -0
- roadmap/infrastructure/validation/__init__.py +7 -0
- roadmap/infrastructure/validation/file_enumeration.py +219 -0
- roadmap/infrastructure/validation/github_assignee_validator.py +47 -0
- roadmap/infrastructure/validation/github_validator.py +101 -0
- roadmap/infrastructure/validation/milestone_consistency_validator.py +96 -0
- roadmap/infrastructure/validation/vanilla_assignee_validator.py +37 -0
- roadmap/infrastructure/validation_gateway.py +96 -0
- roadmap/presentation/formatters/sync_metrics_formatter.py +355 -0
- roadmap/settings.py +345 -0
- roadmap/templates/github_workflows/ci-cd-roadmap.yml +241 -0
- roadmap/templates/github_workflows/issue-lifecycle.yml +236 -0
- roadmap/templates/github_workflows/roadmap-integration.yml +137 -0
- roadmap/templates/github_workflows/roadmap-starter.yml +59 -0
- roadmap/version.py +381 -0
- roadmap_cli-0.1.1.dist-info/METADATA +448 -0
- roadmap_cli-0.1.1.dist-info/RECORD +521 -0
- roadmap_cli-0.1.1.dist-info/WHEEL +4 -0
- roadmap_cli-0.1.1.dist-info/entry_points.txt +2 -0
- roadmap_cli-0.1.1.dist-info/licenses/LICENSE.md +21 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Protocol definitions for dependency injection and service abstraction."""
|
|
2
|
+
|
|
3
|
+
from typing import Protocol
|
|
4
|
+
|
|
5
|
+
from .assignee_validator import AssigneeValidator # type: ignore[assignment]
|
|
6
|
+
from .backend_factory import SyncBackendFactoryInterface, SyncBackendInterface
|
|
7
|
+
from .github import GitHubBackendInterface
|
|
8
|
+
from .parsers import (
|
|
9
|
+
FrontmatterParserInterface,
|
|
10
|
+
IssueParserInterface,
|
|
11
|
+
MilestoneParserInterface,
|
|
12
|
+
ProjectParserInterface,
|
|
13
|
+
)
|
|
14
|
+
from .persistence import (
|
|
15
|
+
FileNotFound,
|
|
16
|
+
GitHistoryError,
|
|
17
|
+
PersistenceInterface,
|
|
18
|
+
)
|
|
19
|
+
from .repositories import (
|
|
20
|
+
IssueRepository,
|
|
21
|
+
MilestoneRepository,
|
|
22
|
+
ProjectRepository,
|
|
23
|
+
)
|
|
24
|
+
from .state_managers import (
|
|
25
|
+
IssueStateManager,
|
|
26
|
+
MilestoneStateManager,
|
|
27
|
+
ProjectStateManager,
|
|
28
|
+
QueryStateManager,
|
|
29
|
+
SyncStateManager,
|
|
30
|
+
)
|
|
31
|
+
from .state_storage import SyncStateStorageInterface
|
|
32
|
+
from .sync_backend import (
|
|
33
|
+
SyncConflict,
|
|
34
|
+
SyncReport,
|
|
35
|
+
)
|
|
36
|
+
from .sync_services import SyncCacheServiceInterface, SyncLinkingServiceInterface
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"CredentialProvider",
|
|
40
|
+
"AssigneeValidator",
|
|
41
|
+
"ProjectStateManager",
|
|
42
|
+
"MilestoneStateManager",
|
|
43
|
+
"IssueStateManager",
|
|
44
|
+
"SyncStateManager",
|
|
45
|
+
"QueryStateManager",
|
|
46
|
+
"SyncBackendInterface",
|
|
47
|
+
"SyncBackendFactoryInterface",
|
|
48
|
+
"SyncConflict",
|
|
49
|
+
"SyncReport",
|
|
50
|
+
"PersistenceInterface",
|
|
51
|
+
"IssueParserInterface",
|
|
52
|
+
"FrontmatterParserInterface",
|
|
53
|
+
"MilestoneParserInterface",
|
|
54
|
+
"ProjectParserInterface",
|
|
55
|
+
"GitHubBackendInterface",
|
|
56
|
+
"SyncStateStorageInterface",
|
|
57
|
+
"SyncLinkingServiceInterface",
|
|
58
|
+
"SyncCacheServiceInterface",
|
|
59
|
+
"IssueRepository",
|
|
60
|
+
"MilestoneRepository",
|
|
61
|
+
"ProjectRepository",
|
|
62
|
+
"FileNotFound",
|
|
63
|
+
"GitHistoryError",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CredentialProvider(Protocol):
|
|
68
|
+
"""Abstract interface for credential management.
|
|
69
|
+
|
|
70
|
+
Defines the contract that any credential provider must implement.
|
|
71
|
+
Allows services to work with different credential backends without
|
|
72
|
+
depending on concrete implementations.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def get_token(self) -> str | None:
|
|
76
|
+
"""Retrieve a stored token.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Token string if found, None otherwise
|
|
80
|
+
"""
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
def store_token(self, token: str, repo_info: dict[str, str] | None = None) -> bool: # noqa: F841
|
|
84
|
+
"""Store a token securely.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
token: Token to store
|
|
88
|
+
repo_info: Optional repository information (owner, repo)
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
True if stored successfully, False otherwise
|
|
92
|
+
"""
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
def delete_token(self) -> bool:
|
|
96
|
+
"""Delete a stored token.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
True if deleted successfully, False otherwise
|
|
100
|
+
"""
|
|
101
|
+
...
|
|
102
|
+
|
|
103
|
+
def is_available(self) -> bool:
|
|
104
|
+
"""Check if the credential provider is available on this system.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
True if available, False otherwise
|
|
108
|
+
"""
|
|
109
|
+
...
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Assignee validator interface.
|
|
2
|
+
|
|
3
|
+
Defines the contract for assignee validation implementations that can be
|
|
4
|
+
swapped based on the configured sync backend.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Protocol
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AssigneeValidator(Protocol):
|
|
11
|
+
"""Protocol for assignee validation.
|
|
12
|
+
|
|
13
|
+
Implementations validate assignees according to their backend's rules.
|
|
14
|
+
For example, GitHub validator checks against repository collaborators,
|
|
15
|
+
while a no-op validator always accepts any assignee.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def validate(self, assignee: str) -> tuple[bool, str]:
|
|
19
|
+
"""Validate an assignee.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
assignee: Username to validate
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Tuple of (is_valid, error_message)
|
|
26
|
+
- (True, "") if valid
|
|
27
|
+
- (False, error_message) if invalid
|
|
28
|
+
"""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
def get_canonical_assignee(self, assignee: str) -> str:
|
|
32
|
+
"""Get the canonical form of an assignee name.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
assignee: Input assignee name
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Canonical assignee name (may be same as input if no mapping exists)
|
|
39
|
+
"""
|
|
40
|
+
...
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""Backend factory interface for creating sync backends.
|
|
2
|
+
|
|
3
|
+
Defines contract for backend instantiation without importing adapter implementations.
|
|
4
|
+
Allows dynamic backend selection without layer violations.
|
|
5
|
+
|
|
6
|
+
Updated to use Result<T, SyncError> pattern for explicit error handling.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from typing import TYPE_CHECKING, Any
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from roadmap.common.result import Result
|
|
14
|
+
from roadmap.core.services.sync.sync_errors import SyncError
|
|
15
|
+
|
|
16
|
+
from .sync_backend import SyncReport
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SyncBackendFactoryInterface(ABC):
|
|
20
|
+
"""Contract for creating sync backends."""
|
|
21
|
+
|
|
22
|
+
@abstractmethod
|
|
23
|
+
def create_backend(
|
|
24
|
+
self,
|
|
25
|
+
backend_type: str, # noqa: F841
|
|
26
|
+
config: dict[str, Any], # noqa: F841
|
|
27
|
+
) -> "SyncBackendInterface":
|
|
28
|
+
"""Create a sync backend instance.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
backend_type: Type of backend to create (e.g., 'github', 'gitlab')
|
|
32
|
+
config: Configuration dictionary for the backend
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
SyncBackendInterface implementation
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
ValueError: If backend_type is not supported
|
|
39
|
+
"""
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def list_supported_backends(self) -> list[str]:
|
|
44
|
+
"""List all supported backend types.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
List of backend type identifiers
|
|
48
|
+
"""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def get_default_backend(self) -> str:
|
|
53
|
+
"""Get the default backend type.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Backend type identifier
|
|
57
|
+
"""
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class SyncBackendInterface(ABC):
|
|
62
|
+
"""Contract for sync backend implementations.
|
|
63
|
+
|
|
64
|
+
Updated to use Result<T, SyncError> for explicit error handling.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
@abstractmethod
|
|
68
|
+
def authenticate(self) -> "Result[bool, SyncError]":
|
|
69
|
+
"""Authenticate with the backend service.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Ok(True) if authentication successful
|
|
73
|
+
Err(SyncError) with error details
|
|
74
|
+
"""
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
@abstractmethod
|
|
78
|
+
def get_backend_name(self) -> str:
|
|
79
|
+
"""Get the backend name.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Backend identifier string
|
|
83
|
+
"""
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
@abstractmethod
|
|
87
|
+
def get_issues(self) -> "Result[dict[str, Any], SyncError]":
|
|
88
|
+
"""Get issues from backend.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Ok(dict) of issues on success
|
|
92
|
+
Err(SyncError) with error details
|
|
93
|
+
"""
|
|
94
|
+
pass
|
|
95
|
+
|
|
96
|
+
@abstractmethod
|
|
97
|
+
def push_issues(self, issues: dict[str, Any]) -> "Result[SyncReport, SyncError]": # noqa: F841
|
|
98
|
+
"""Push issues to backend.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
issues: Dictionary of issues to push
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Ok(SyncReport) with results on success
|
|
105
|
+
Err(SyncError) with fatal error details
|
|
106
|
+
"""
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
@abstractmethod
|
|
110
|
+
def push_issue(self, local_issue: Any) -> "Result[bool, SyncError]": # noqa: F841
|
|
111
|
+
"""Push a single issue to backend.
|
|
112
|
+
|
|
113
|
+
Delegates to push_issues by default but can be overridden.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
local_issue: Issue object to push
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
Ok(True) if successful
|
|
120
|
+
Err(SyncError) with error details
|
|
121
|
+
"""
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
@abstractmethod
|
|
125
|
+
def pull_issues(self, issue_ids: list[str]) -> "Result[SyncReport, SyncError]":
|
|
126
|
+
"""Pull issues from backend.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
issue_ids: List of issue IDs to pull
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
Ok(SyncReport) with results on success
|
|
133
|
+
Err(SyncError) with fatal error details
|
|
134
|
+
"""
|
|
135
|
+
pass
|
|
136
|
+
|
|
137
|
+
@abstractmethod
|
|
138
|
+
def pull_issue(self, issue_id: str) -> "Result[bool, SyncError]":
|
|
139
|
+
"""Pull a single issue from backend.
|
|
140
|
+
|
|
141
|
+
Delegates to pull_issues by default but can be overridden.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
issue_id: Issue ID to pull
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
Ok(True) if successful
|
|
148
|
+
Err(SyncError) with error details
|
|
149
|
+
"""
|
|
150
|
+
pass
|
|
151
|
+
|
|
152
|
+
@abstractmethod
|
|
153
|
+
def get_conflict_resolution_options(self, conflict: Any) -> list[str]: # noqa: F841
|
|
154
|
+
"""Get conflict resolution options.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
conflict: Conflict object
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
List of resolution options
|
|
161
|
+
"""
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
@abstractmethod
|
|
165
|
+
def resolve_conflict(self, conflict: Any, resolution: str) -> bool: # noqa: F841
|
|
166
|
+
"""Resolve a conflict.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
conflict: Conflict object
|
|
170
|
+
resolution: Resolution option selected
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
True if resolved successfully
|
|
174
|
+
"""
|
|
175
|
+
pass
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""GitHub backend interface for core services.
|
|
2
|
+
|
|
3
|
+
Defines contract for GitHub operations without importing adapter implementations.
|
|
4
|
+
Allows core services to work with GitHub without layer violations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from roadmap.core.domain import Issue
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GitHubBackendInterface(ABC):
|
|
14
|
+
"""Contract for GitHub backend operations."""
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def authenticate(self) -> bool:
|
|
18
|
+
"""Authenticate with GitHub.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
True if authentication successful, False otherwise
|
|
22
|
+
"""
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
@abstractmethod
|
|
26
|
+
def get_issues(self) -> dict[str, Any]:
|
|
27
|
+
"""Get all issues from GitHub repository.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
Dictionary mapping issue IDs to issue data
|
|
31
|
+
"""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def get_issue(self, issue_id: str) -> Any:
|
|
36
|
+
"""Get a specific issue from GitHub.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
issue_id: The GitHub issue ID
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Issue data or None if not found
|
|
43
|
+
"""
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
@abstractmethod
|
|
47
|
+
def create_issue(self, issue: Issue) -> str:
|
|
48
|
+
"""Create an issue on GitHub.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
issue: Issue domain object to create
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
GitHub issue ID of created issue
|
|
55
|
+
"""
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def update_issue(self, issue_id: str, issue: Issue) -> bool:
|
|
60
|
+
"""Update an issue on GitHub.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
issue_id: GitHub issue ID
|
|
64
|
+
issue: Updated issue data
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
True if successful, False otherwise
|
|
68
|
+
"""
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
@abstractmethod
|
|
72
|
+
def close_issue(self, issue_id: str) -> bool:
|
|
73
|
+
"""Close an issue on GitHub.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
issue_id: GitHub issue ID
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
True if successful, False otherwise
|
|
80
|
+
"""
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
@abstractmethod
|
|
84
|
+
def list_repositories(self) -> list[str]:
|
|
85
|
+
"""List accessible repositories.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
List of repository identifiers
|
|
89
|
+
"""
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
@abstractmethod
|
|
93
|
+
def validate_credentials(self, token: str) -> bool:
|
|
94
|
+
"""Validate GitHub API credentials.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
token: GitHub API token
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
True if credentials are valid
|
|
101
|
+
"""
|
|
102
|
+
pass
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Parser interfaces for domain object deserialization.
|
|
2
|
+
|
|
3
|
+
These interfaces define contracts for parsing files and content into domain objects.
|
|
4
|
+
Implementations should be in the infrastructure/adapters layer.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from roadmap.core.domain import Issue, Milestone, Project
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class IssueParserInterface(ABC):
|
|
16
|
+
"""Contract for parsing issue markdown files."""
|
|
17
|
+
|
|
18
|
+
@abstractmethod
|
|
19
|
+
def parse_issue_file(self, file_path: Path) -> "Issue":
|
|
20
|
+
"""Parse an issue markdown file and return an Issue domain object.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
file_path: Path to issue markdown file
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Issue domain object
|
|
27
|
+
|
|
28
|
+
Raises:
|
|
29
|
+
FileNotFoundError: If file doesn't exist
|
|
30
|
+
ValueError: If file cannot be parsed
|
|
31
|
+
"""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def parse_issue_content(self, content: str) -> dict[str, Any]:
|
|
36
|
+
"""Parse issue content string and return frontmatter as dict.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
content: File content as string
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Parsed frontmatter as dictionary
|
|
43
|
+
"""
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class MilestoneParserInterface(ABC):
|
|
48
|
+
"""Contract for parsing milestone markdown files."""
|
|
49
|
+
|
|
50
|
+
@abstractmethod
|
|
51
|
+
def parse_milestone_file(self, file_path: Path) -> "Milestone":
|
|
52
|
+
"""Parse a milestone markdown file and return a Milestone domain object.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
file_path: Path to milestone markdown file
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Milestone domain object
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
FileNotFoundError: If file doesn't exist
|
|
62
|
+
ValueError: If file cannot be parsed
|
|
63
|
+
"""
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
@abstractmethod
|
|
67
|
+
def parse_milestone_content(self, content: str) -> dict[str, Any]:
|
|
68
|
+
"""Parse milestone content string and return frontmatter as dict.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
content: File content as string
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Parsed frontmatter as dictionary
|
|
75
|
+
"""
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class ProjectParserInterface(ABC):
|
|
80
|
+
"""Contract for parsing project markdown files."""
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def parse_project_file(self, file_path: Path) -> "Project":
|
|
84
|
+
"""Parse a project markdown file and return a Project domain object.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
file_path: Path to project markdown file
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Project domain object
|
|
91
|
+
|
|
92
|
+
Raises:
|
|
93
|
+
FileNotFoundError: If file doesn't exist
|
|
94
|
+
ValueError: If file cannot be parsed
|
|
95
|
+
"""
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
@abstractmethod
|
|
99
|
+
def parse_project_content(self, content: str) -> dict[str, Any]:
|
|
100
|
+
"""Parse project content string and return frontmatter as dict.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
content: File content as string
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Parsed frontmatter as dictionary
|
|
107
|
+
"""
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class FrontmatterParserInterface(ABC):
|
|
112
|
+
"""Contract for parsing YAML frontmatter from markdown files."""
|
|
113
|
+
|
|
114
|
+
@abstractmethod
|
|
115
|
+
def parse_file(self, file_path: Path) -> tuple[dict[str, Any], str]:
|
|
116
|
+
"""Parse a markdown file and extract frontmatter and content.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
file_path: Path to markdown file
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
Tuple of (frontmatter dict, content string)
|
|
123
|
+
|
|
124
|
+
Raises:
|
|
125
|
+
FileNotFoundError: If file doesn't exist
|
|
126
|
+
ValueError: If file cannot be parsed
|
|
127
|
+
"""
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
@abstractmethod
|
|
131
|
+
def parse_content(self, content: str) -> tuple[dict[str, Any], str]:
|
|
132
|
+
"""Parse markdown content and extract frontmatter and text.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
content: File content as string
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Tuple of (frontmatter dict, content string)
|
|
139
|
+
"""
|
|
140
|
+
pass
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Persistence interface for core services.
|
|
2
|
+
|
|
3
|
+
Defines contract for file persistence and git history operations.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FileNotFound(Exception):
|
|
11
|
+
"""Raised when a file is not found in history."""
|
|
12
|
+
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GitHistoryError(Exception):
|
|
17
|
+
"""Raised when git history operations fail."""
|
|
18
|
+
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PersistenceInterface(ABC):
|
|
23
|
+
"""Interface for file persistence operations."""
|
|
24
|
+
|
|
25
|
+
@abstractmethod
|
|
26
|
+
def get_file_at_timestamp(self, file_path: str, timestamp: datetime) -> str:
|
|
27
|
+
"""Get file content at a specific git timestamp.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
file_path: Path to file relative to repo root
|
|
31
|
+
timestamp: Datetime to retrieve file at
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
File content as string
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
FileNotFound: If file doesn't exist at timestamp
|
|
38
|
+
GitHistoryError: If git operation fails
|
|
39
|
+
"""
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def list_files_in_directory(self, directory: str) -> list[str]:
|
|
44
|
+
"""List all files in a directory at HEAD."""
|
|
45
|
+
pass
|