""" Provider selection interface """ from colorama import Fore, Style from providers.factory import ProviderFactory from core.config import MigrationConfig def select_providers() -> tuple[str, str]: """ Interactive provider selection for source and destination Returns tuple (source_provider, destination_provider) """ config = MigrationConfig() # Get available providers from factory available_source_providers = ProviderFactory.get_available_source_providers() available_destination_providers = ProviderFactory.get_available_destination_providers() print(f"\n{Fore.CYAN}🔧 Provider Configuration{Style.RESET_ALL}") print(f"{Fore.YELLOW}Available providers by type:{Style.RESET_ALL}") print(f" đŸ“Ĩ Source: {', '.join(available_source_providers).upper()}") print(f" 📤 Destination: {', '.join(available_destination_providers).upper()}") # Check configured providers source_provider_configs = config.get_available_source_providers() dest_provider_configs = config.get_available_destination_providers() print(f"\n{Fore.YELLOW}Source provider configuration status:{Style.RESET_ALL}") configured_source_providers = [] for provider, is_configured in source_provider_configs.items(): if provider in available_source_providers: status = f"{Fore.GREEN}✅ Configured" if is_configured else f"{Fore.RED}❌ Not configured" print(f" {provider.upper()}: {status}{Style.RESET_ALL}") if is_configured: configured_source_providers.append(provider) print(f"\n{Fore.YELLOW}Destination provider configuration status:{Style.RESET_ALL}") configured_destination_providers = [] for provider, is_configured in dest_provider_configs.items(): if provider in available_destination_providers: status = f"{Fore.GREEN}✅ Configured" if is_configured else f"{Fore.RED}❌ Not configured" print(f" {provider.upper()}: {status}{Style.RESET_ALL}") if is_configured: configured_destination_providers.append(provider) # Validate we have at least one configured source and destination if not configured_source_providers: print(f"\n{Fore.RED}❌ No source providers configured!{Style.RESET_ALL}") print(f"{Fore.YELLOW}💡 Please configure at least one source provider in .env:{Style.RESET_ALL}") for provider in available_source_providers: if provider == 'gitea': print(f" GITEA_SOURCE_URL, GITEA_SOURCE_TOKEN, GITEA_SOURCE_USERNAME") elif provider == 'gitlab': print(f" GITLAB_SOURCE_URL, GITLAB_SOURCE_TOKEN, GITLAB_SOURCE_USERNAME") elif provider == 'github': print(f" GITHUB_TOKEN, GITHUB_USERNAME") exit(1) if not configured_destination_providers: print(f"\n{Fore.RED}❌ No destination providers configured!{Style.RESET_ALL}") print(f"{Fore.YELLOW}💡 Please configure at least one destination provider in .env:{Style.RESET_ALL}") for provider in available_destination_providers: if provider == 'gitea': print(f" GITEA_DEST_URL, GITEA_DEST_TOKEN, GITEA_DEST_USERNAME") elif provider == 'github': print(f" GITHUB_TOKEN, GITHUB_USERNAME") elif provider == 'gitlab': print(f" GITLAB_DEST_URL, GITLAB_DEST_TOKEN, GITLAB_DEST_USERNAME") exit(1) # Select source provider print(f"\n{Fore.CYAN}đŸ“Ĩ Select SOURCE provider:{Style.RESET_ALL}") source_provider = _select_provider(configured_source_providers, "source") # Select destination provider (exclude GitHub → GitHub) available_destinations = configured_destination_providers.copy() if source_provider == 'github' and 'github' in available_destinations: available_destinations.remove('github') print(f"\n{Fore.YELLOW}â„šī¸ GitHub → GitHub migration not supported (same instance){Style.RESET_ALL}") if not available_destinations: print(f"\n{Fore.RED}❌ No valid destination providers available!{Style.RESET_ALL}") if source_provider == 'github': print(f"{Fore.YELLOW}GitHub can only migrate TO other providers, not to itself.{Style.RESET_ALL}") exit(1) # Select destination provider print(f"\n{Fore.CYAN}📤 Select DESTINATION provider:{Style.RESET_ALL}") destination_provider = _select_provider(available_destinations, "destination") print(f"\n{Fore.GREEN}✅ Migration will be: {source_provider.upper()} → {destination_provider.upper()}{Style.RESET_ALL}") return source_provider, destination_provider def _select_provider(providers: list, provider_type: str) -> str: """ Select a provider from the available list """ if len(providers) == 1: print(f"{Fore.GREEN}✅ Only one {provider_type} provider available: {providers[0].upper()}{Style.RESET_ALL}") return providers[0] while True: print(f"\n{Fore.YELLOW}Available {provider_type} providers:{Style.RESET_ALL}") for i, provider in enumerate(providers, 1): print(f" {i}. {provider.upper()}") try: choice = input(f"\nEnter your choice (1-{len(providers)}): ").strip() if choice.isdigit(): index = int(choice) - 1 if 0 <= index < len(providers): selected = providers[index] print(f"{Fore.GREEN}✅ Selected {provider_type}: {selected.upper()}{Style.RESET_ALL}") return selected print(f"{Fore.RED}❌ Invalid choice. Please enter a number between 1 and {len(providers)}.{Style.RESET_ALL}") except KeyboardInterrupt: print(f"\n{Fore.YELLOW}🛑 Migration cancelled.{Style.RESET_ALL}") exit(0) except EOFError: print(f"\n{Fore.YELLOW}🛑 Migration cancelled.{Style.RESET_ALL}") exit(0)