54 lines
1.8 KiB
Python
54 lines
1.8 KiB
Python
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})
|