from abc import ABC, abstractmethod from git_flow import SUPPORTED_REMOTE_APIS, GitFlowError from git_flow.git import Git class RemoteAPI(ABC): def __init__(self, repository: str, token: str) -> None: self.repository = repository self.token = token @staticmethod def parse(remote: str): url = Git("remote", "get-url", remote).firstline() invalid_url_error = GitFlowError(f"La URL del remoto {remote} es inválida: {url}") url_type = None if url.startswith("git@"): url_type = "ssh" elif url.startswith("http://") or url.startswith("https://"): url_type = "https" else: raise invalid_url_error if url_type == "ssh": # git@host:user/repo[.git] at_pos = url.index("@") colon_pos = url.index(":") host = url[at_pos+1:colon_pos] repository = url[colon_pos+1:] else: # https://host/user/repo[.git] host_start = url.index("://") + 3 uri_start = url.index("/", host_start) host = url[host_start:uri_start] repository = url[uri_start+1:] # Esto permite configurar hosts "imaginarios" para permitir el uso de multiples claves ssh if host.endswith(".bitbucket.org"): host = "bitbucket.org" elif host.endswith(".github.com"): host = "github.com" if host not in SUPPORTED_REMOTE_APIS: raise GitFlowError("El host del repositorio remoto es inválido") repository.removesuffix(".git") return [host, repository] @abstractmethod def create_pull_request( self, source: str, destination: str, title: str | None = None, description: str | None = None, ) -> str: pass @abstractmethod def create_tag(self, tag: str, commit: str) -> str: pass @abstractmethod def get_endpoint(self, resource: str) -> str: pass def get_headers(self): return { "Accept": "application/json", "Content-Type": "application/json", "Authorization": "Bearer " + self.token, }