diff --git a/README.md b/README.md index a5b2ea9..e846040 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ El comando solicitará 2 opciones: - [x] Bitbucket - [x] Github - [x] Gitea + - [x] Gitlab La configuración del remoto requiere tener un Access Token para poder crear los PRs automáticamente. El mismo se puede crear desde el repositorio al que se quiere dar acceso: *"Repository settings" > diff --git a/src/git_flow/command/base.py b/src/git_flow/command/base.py index 398cd1d..cde9021 100644 --- a/src/git_flow/command/base.py +++ b/src/git_flow/command/base.py @@ -11,6 +11,7 @@ from git_flow.remote.base import RemoteAPI from git_flow.remote.bitbucket import BitbucketRemoteAPI from git_flow.remote.github import GithubRemoteAPI from git_flow.remote.gitea import GiteaRemoteAPI +from git_flow.remote.gitlab import GitlabRemoteAPI from git_flow.io import * from os.path import isfile @@ -123,6 +124,9 @@ def get_remote_api(token: str) -> RemoteAPI: if remote_type == "gitea": remote_schema = "https://" if schema == "ssh://" else schema return GiteaRemoteAPI(remote_schema + host, repository, token) + elif remote_type == "gitlab": + remote_schema = "https://" if schema == "ssh://" else schema + return GitlabRemoteAPI(remote_schema + host, repository, token) elif remote_type == "bitbucket": return BitbucketRemoteAPI(repository, token) elif remote_type == "github": diff --git a/src/git_flow/command/init.py b/src/git_flow/command/init.py index 24db201..3890d03 100644 --- a/src/git_flow/command/init.py +++ b/src/git_flow/command/init.py @@ -101,7 +101,7 @@ uno nuevo.""", remote = base.io_choice("Remoto", remotes) remote_type = base.io_choice( - "Tipo de remoto:", ["bitbucket", "github", "gitea"] + "Tipo de remoto:", ["bitbucket", "github", "gitea", "gitlab"] ) return (remote, remote_type) diff --git a/src/git_flow/remote/gitlab.py b/src/git_flow/remote/gitlab.py new file mode 100644 index 0000000..312dd9d --- /dev/null +++ b/src/git_flow/remote/gitlab.py @@ -0,0 +1,59 @@ +from urllib.parse import quote + +import requests +from git_flow import GitFlowError +from git_flow.remote.base import RemoteAPI + + +class GitlabRemoteAPI(RemoteAPI): + def __init__(self, base_url: str, repository: str, token: str) -> None: + super().__init__(repository, token) + self.base_url = base_url + + def create_pull_request( + self, + source: str, + destination: str, + title: str | None = None, + description: str | None = None, + close_source_branch: bool = True + ) -> str: + response = requests.post( + self.get_endpoint("/merge_requests"), + headers=self.get_headers(), + json={ + "title": title, + "description": description, + "source_branch": source, + "target_branch": destination, + "remove_source_branch": close_source_branch, + }, + ) + + if response.ok: + return "PR creado exitosamente: " + response.json()["web_url"] + else: + raise GitFlowError("Ocurrió un error al crear el PR: " + response.text) + + def create_tag(self, tag: str, commit: str) -> str: + response = requests.post( + self.get_endpoint("/repository/tags"), + headers=self.get_headers(), + json={"tag_name": tag, "ref": commit}, + ) + + if response.ok: + return "Tag creado exitosamente: " + tag + else: + raise GitFlowError("Ocurrió un error al crear el tag: " + response.text) + + def get_endpoint(self, resource: str) -> str: + project_id = quote(self.repository, safe="") + return f"{self.base_url}/api/v4/projects/{project_id}{resource}" + + def get_headers(self): + return { + "Accept": "application/json", + "Content-Type": "application/json", + "PRIVATE-TOKEN": self.token, + }