import typer from git_flow import FLOWCONFIG_FILENAME, FLOWCONFIG_VERSION, GitFlowError from git_flow.git import Git from git_flow.command.base import * app = typer.Typer() @app.command() def init(): """Inicializa el repositorio para utilizar git-flow""" _ensure_is_repository() _ensure_not_already_initialized() branches = _setup_flow_branches() (remote, remote_type) = _setup_flow_remote() flowconfig = { "flow.version": str(FLOWCONFIG_VERSION), "flow.initialized": "true", "flow.branches": ",".join(branches), } if remote and remote_type: flowconfig["flow.remote"] = remote flowconfig["flow.remote-type"] = remote_type Git.set_config(flowconfig, FLOWCONFIG_FILENAME) Git("add", FLOWCONFIG_FILENAME).exec() Git("commit", message="feature: initialize git-flow").exec() _ensure_all_flow_branches_exist(branches, remote) def _ensure_is_repository(): if not Git.is_repository(): warning("El directorio actual no es un repositorio.") if not confirm("¿Desea inicializarlo?"): raise GitFlowError("No se puede continuar sin inicializar el repositorio") Git("init").exec() def _ensure_not_already_initialized(): if not flowconfig: return elif flowconfig.get("flow.initialized") == "true": raise GitFlowError("El repositorio ya fue inicializado para usar git-flow") else: raise GitFlowError("Valor de 'flow.initialized' es inválido") def _setup_flow_branches(): panel( "Configuración de entornos", """Ingrese las ramas que representan los entornos de deploy del proyecto en orden creciente de cercanía al entorno productivo, y separados por coma. Por ejemplo: "dev, test, prod".""", ) branches = list(map(lambda b: b.strip(), prompt("Ramas", "main").split(","))) if not all(branches): raise GitFlowError("No puede ingresar una rama vacia") return branches def _setup_flow_remote(): panel( "Configuración de remoto", "Puede configurar un repositorio remoto para generar PRs automáticamente", ) remote = None remote_type = None if confirm("¿Configurar repositorio remoto?"): remotes = Git("remote").lines(print="Listando remotos disponibles") if not remotes: info("No tiene ningún repositorio remoto, se creará uno.") url = prompt( "Ingrese la URL del repositorio (e.g. https://github.com/user/repo.git)", persistent=True, ) remote = "origin" Git("remote", "add", remote, url).exec(print="Agregando remoto") elif len(remotes) == 1: remote = remotes[0] else: info("Tiene más de un remoto, seleccione el que va a utilizar.") remote = choice("Remoto", remotes) remote_type = choice("Tipo de remoto:", ["bitbucket", "github", "gitea"]) return (remote, remote_type) def _ensure_all_flow_branches_exist(branches: list[str], remote: str | None): existing_branches = Git.get_branches() if not all(map(lambda b: b in existing_branches, branches)): warning("Algunas de las ramas de entornos expecificadas no existen.") info("Debe indicar sobre que rama se crearán las ramas de entorno.") target_branch = choice("Rama", existing_branches) for branch in branches: if branch not in existing_branches: Git("branch", branch, target_branch).exec( print="Creando rama inexistente" ) if remote: Git("push", remote, branch, set_upstream=True).exec( print="Creando rama en remoto" )