From f3891185156316a4a498f1791a0910c096cec97f Mon Sep 17 00:00:00 2001 From: Jonathan Teran Carballo Date: Tue, 19 May 2026 23:29:22 -0300 Subject: [PATCH] feature: agrego soporte para especificar tickets en nombre e rama --- src/git_flow/command/base.py | 12 +++++++++++ src/git_flow/command/merge.py | 40 +++++++++++++++++++++++------------ src/git_flow/command/new.py | 18 +++++++++++++--- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/git_flow/command/base.py b/src/git_flow/command/base.py index a7aedec..ae0d3b4 100644 --- a/src/git_flow/command/base.py +++ b/src/git_flow/command/base.py @@ -113,3 +113,15 @@ def get_remote_api(token: str) -> RemoteAPI: return GithubRemoteAPI(repository, token) else: raise GitFlowError("El host del repositorio remoto es inválido") + +def is_valid_ticket(ticket: str) -> bool: + """Check if the specified string is a valid ticket number (ABC-123)""" + components = ticket.split("-") + + if len(components) != 2: + return False + + ticket_project = components[0] + ticket_number = components[1] + + return ticket_project.isalpha() and ticket_project.isupper() and ticket_number.isnumeric() \ No newline at end of file diff --git a/src/git_flow/command/merge.py b/src/git_flow/command/merge.py index a24f872..feb7156 100644 --- a/src/git_flow/command/merge.py +++ b/src/git_flow/command/merge.py @@ -83,21 +83,12 @@ def check_merge_conflicts(target: str): def create_pull_request(token: str, branch: str, target: str): changelog = Changelog() commits = Git("log", target + "..", format="%s").lines() + title = commits[0] if len(commits) == 1 else _get_pr_title_from_branch(branch) - if len(commits) == 1: - title = commits[0] - else: - title = branch.replace("/", ": ").replace("-", " ") + panel("Título del PR", title) - if title.startswith("release: "): - title = title[title.index(" ", title.index(" ") + 1) + 1 :] - - info("Título del PR por defecto: " + title) - - opt_title = prompt("[Opcional] Ingrese otro titulo para el PR") - - if opt_title: - title = opt_title + if confirm("¿Desea cambiar el título del PR?", False): + title = prompt("Título del PR") message = get_remote_api(token).create_pull_request( branch, @@ -111,3 +102,26 @@ def create_pull_request(token: str, branch: str, target: str): if confirm("¿Desea cambiar a la rama objetivo y bajar los cambios?"): Git("switch", target).exec(print="Cambiando a rama objetivo") Git("pull").exec(print="Obteniendo cambios") + +def _get_pr_title_from_branch(branch: str) -> str: + components = branch.split("-") # / or release/// + branch_type = components[-2] + branch_desc = components[-1] + + # detect if branch description has ticket as prefix: = ABC-123-my-branch-name + branch_ticket = None + first_dash = branch_desc.find("-") + second_dash = branch_desc.find("-", first_dash + 1) + + if first_dash >= 0 and second_dash >= 0: + maybe_ticket = branch_desc[:second_dash] + if is_valid_ticket(maybe_ticket): + branch_ticket = maybe_ticket + branch_desc = branch_desc[:second_dash+1] + + return " ".join(filter(None, [ + f"[Pasaje a {components[1]}]" if len(components) == 4 else None, + branch_type + ":", + branch_ticket, + branch_desc.replace("-", " ") + ])) \ No newline at end of file diff --git a/src/git_flow/command/new.py b/src/git_flow/command/new.py index 8e0e9b4..d381d93 100644 --- a/src/git_flow/command/new.py +++ b/src/git_flow/command/new.py @@ -2,6 +2,7 @@ import typer from git_flow import BRANCH_TYPES from git_flow.command.base import * from git_flow.git import Git +from typing import Optional app = typer.Typer() @@ -21,7 +22,8 @@ def new(): info("Debe seleccionar el tipo de cambio a realizar.") branch_type = choice("Tipos de cambio", BRANCH_TYPES) - new_branch = _get_unique_branch_name(branch_type) + ticket = _get_optional_ticket() + new_branch = _get_unique_branch_name(branch_type, ticket) if "flow.remote" in flowconfig and Git.get_tracking_branch(branch): Git("pull").exec(print="Actualizando rama actual") @@ -29,8 +31,18 @@ def new(): if confirm(f"¿Crear rama '{new_branch}' sobre la rama actual?"): Git("switch", new_branch, create=True).exec(print="Creando nueva rama") +def _get_optional_ticket() -> Optional[str]: + ticket = prompt("[Opcional] Ticket que respalda el cambio (en formato ABC-123)") -def _get_unique_branch_name(branch_type: str) -> str: + if not ticket: + return None + if not is_valid_ticket(ticket): + warning("Formato de ticket inválido, ignorando.") + return None + + return ticket + +def _get_unique_branch_name(branch_type: str, ticket: Optional[str]) -> str: info(f"Ingrese las palabras clave que describan el cambio de tipo '{branch_type}'.") branch = None branches = Git.get_branches() @@ -42,7 +54,7 @@ def _get_unique_branch_name(branch_type: str) -> str: ) keywords = filter(lambda k: len(k) > 0, keywords.split(" ")) - branch = branch_type + "/" + "-".join(keywords) + branch = branch_type + "/" + (ticket + "-" if ticket else "") + "-".join(keywords) if branch in branches: error(