from abc import ABC, abstractmethod import giturlparse from git_flow import SUPPORTED_REMOTE_URL_SCHEMAS, 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): """Soportamos 3 tipos de URL: http, https y ssh. Si no se especifica el esquema, asumimos ssh: Ejemplos: - http://gitea/user/repo - https://gitea.com/user/repo.git - git@bitbucket.org:user/repo - git.mygiteainstance.com:user/repo.git - ssh://git@git.mygiteainstance.com:1234/user/repo.git """ url = Git("remote", "get-url", remote).firstline() parsed_url = giturlparse.parse(url) # Validamos que la URL sea válida if not parsed_url.valid: raise GitFlowError(f"La URL del remoto {remote} es inválida: {url}") if not parsed_url.protocol in SUPPORTED_REMOTE_URL_SCHEMAS: raise GitFlowError( f"La URL del remoto {remote} no tiene un esquema soportado: {url}" ) # Cuando el host es seteado por pipeline puede ser "http://gitea/OWNER/REPO", en ese caso # la libreria parsea OWNER="" y REPO="OWNER/REPO" repository = ( "/".join(filter(None, [parsed_url.owner, parsed_url.repo])) .removeprefix("/") .removesuffix(".git") ) return [parsed_url.protocol + "://", parsed_url.host, repository] @abstractmethod def create_pull_request( self, source: str, destination: str, title: str | None = None, description: str | None = None, close_source_branch: bool = True, ) -> 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, }