import os import re from .errors import TrackerError # type: ignore[reportMissingImports] SUPPORTED_PROVIDERS = ("github", "gitlab", "gitea") def _validate_provider(value): provider = (value or "").strip().lower() if provider not in SUPPORTED_PROVIDERS: raise TrackerError( "invalid_provider", f"unsupported provider: {value}", details={"supported": list(SUPPORTED_PROVIDERS)}, ) return provider def _providers_from_remote(remote): host_match = re.search(r"(?:https?://|ssh://|git@)([^/:]+)", remote or "") host = host_match.group(1).lower() if host_match else "" found = [] if host == "github.com" or "github" in host: found.append("github") if host == "gitlab.com" or "gitlab" in host: found.append("gitlab") if "gitea" in host: found.append("gitea") return found def resolve_provider(explicit=None, *, env=None, remote=None): """Resolve provider using CLI, environment, then remote precedence.""" if explicit is not None: return _validate_provider(explicit) values = os.environ if env is None else env configured = values.get("TRACKER_PROVIDER") if configured: return _validate_provider(configured) matches = _providers_from_remote(remote or "") if len(matches) == 1: return matches[0] if not remote: raise TrackerError( "provider_detection_failed", "provider was not specified and no Git remote was available", ) if len(matches) > 1: message = "Git remote matches multiple supported providers" else: message = f"unsupported or unrecognised Git remote: {remote}" raise TrackerError("provider_detection_failed", message, details={"remote": remote})