Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
432885e107 | ||
|
|
a7ea4a6149 | ||
|
|
717708469a | ||
|
|
542c629489 | ||
|
|
3c271be415 | ||
|
|
c74f1a3093 | ||
|
|
eafb3f1b31 | ||
|
|
82b9a70400 | ||
|
|
6f90a37ba2 | ||
|
|
5a641938c0 |
@@ -1,3 +1,22 @@
|
|||||||
|
## v1.5.0 - 2025-11-27
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
|
||||||
|
- **feature**: modifico formato de listado de ramas [[jonathan.nerat](mailto:jonathan.nerat@gmail.com)] (7177084)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## v1.4.0 - 2025-11-23
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
|
||||||
|
- **feature**: agrego comando branch para listar ramas [[jonathan.nerat](mailto:jonathan.nerat@gmail.com)] (c74f1a3)
|
||||||
|
- **feature**: agrego soporte para parametros repetidos en llamadas a Git [[jonathan.nerat](mailto:jonathan.nerat@gmail.com)] (eafb3f1)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
## v1.3.0 - 2025-11-23
|
## v1.3.0 - 2025-11-23
|
||||||
|
|
||||||
### Commits
|
### Commits
|
||||||
|
|||||||
@@ -7,6 +7,30 @@ Herramienta para establecer un workflow siguiendo [Conventional Commits
|
|||||||
Esta diseñada para facilitar la creación de commits y branches en un formato estandar, que permite
|
Esta diseñada para facilitar la creación de commits y branches en un formato estandar, que permite
|
||||||
derivar versiones automaticamente de los merges sobre ramas principales.
|
derivar versiones automaticamente de los merges sobre ramas principales.
|
||||||
|
|
||||||
|
## Instalación
|
||||||
|
|
||||||
|
Para instalar Git Flow, se sugiere utilizar [pipx](https://github.com/pypa/pipx) (seguir la
|
||||||
|
documentación para instalarlo). Una vez instalado `pipx`, simplemente clonamos el repositorio en una
|
||||||
|
carpeta local, y lo instalamos:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ~/Downloads
|
||||||
|
git clone git@bitbucket.org:sushi2717/git-flow.git
|
||||||
|
cd git-flow
|
||||||
|
pipx install .
|
||||||
|
```
|
||||||
|
|
||||||
|
Luego podemos verificar que se haya instalado correctamente ejecutando: `git-flow -h`
|
||||||
|
|
||||||
|
Para actualizarlo, hacemos un pull de los cambios recientes del repositorio, y hacemos el upgrade
|
||||||
|
mediante `pipx`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ~/Downloads/git-flow
|
||||||
|
git pull
|
||||||
|
pipx upgrade git-flow
|
||||||
|
```
|
||||||
|
|
||||||
## Configuración
|
## Configuración
|
||||||
|
|
||||||
Para poder usar la herramienta en un repositorio, necesitamos inicializarlo:
|
Para poder usar la herramienta en un repositorio, necesitamos inicializarlo:
|
||||||
@@ -22,18 +46,15 @@ El comando solicitará 2 opciones:
|
|||||||
- **Remoto** (opcional): Nombre del remoto que se usará para crear PRs, y taggear merges
|
- **Remoto** (opcional): Nombre del remoto que se usará para crear PRs, y taggear merges
|
||||||
automáticamente. Por el momento, se soportan los siguientes remotos:
|
automáticamente. Por el momento, se soportan los siguientes remotos:
|
||||||
|
|
||||||
- [x] Bitbucket
|
- [x] Bitbucket
|
||||||
- [ ] Github: planeado
|
- [ ] Github: planeado
|
||||||
|
|
||||||
La configuración del remoto requiere tener un API Token para poder crear los PRs automáticamente.
|
La configuración del remoto requiere tener un API Token para poder crear los PRs automáticamente.
|
||||||
El mismo se puede crear desde: *"Atlassian Account Settings" > "Security" > "Create and Manage API
|
El mismo se puede crear desde: *"Atlassian Account Settings" > "Security" > "Create and Manage API
|
||||||
Tokens" > "Create API Tokens with scopes"*. El token necesita el scope `write:pullrequest:bitbucket`
|
Tokens" > "Create API Tokens with scopes"*. El token necesita el scope `write:pullrequest:bitbucket`
|
||||||
|
|
||||||
- `write:repository:bitbucket`
|
Luego se debe guardar el token dentro del repositorio a configurar, en el archivo
|
||||||
|
`.repository-token`. De no especificarse, los merges y tags se harán de forma local.
|
||||||
Luego se debe guardar el token dentro del repositorio a configurar, en el archivo `.repository-token`.
|
|
||||||
|
|
||||||
De no especificarse, los merges y tags se harán de forma local.
|
|
||||||
|
|
||||||
## Utilización
|
## Utilización
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ COLOR_5 = "\033[35m"
|
|||||||
COLOR_6 = "\033[36m"
|
COLOR_6 = "\033[36m"
|
||||||
COLOR_7 = "\033[37m"
|
COLOR_7 = "\033[37m"
|
||||||
COLOR_BLACK_BOLD = "\033[1;30m"
|
COLOR_BLACK_BOLD = "\033[1;30m"
|
||||||
|
COLOR_WHITE_BOLD = "\033[1;37m"
|
||||||
COLOR_RESET = "\033[0m"
|
COLOR_RESET = "\033[0m"
|
||||||
|
|
||||||
TYPE_SUCCESS = 0
|
TYPE_SUCCESS = 0
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
from argparse import ArgumentParser, Namespace
|
||||||
|
from git_flow import GitFlowError
|
||||||
|
from git_flow.command.base import COLOR_GREEN, COLOR_RED, COLOR_RESET, COLOR_WHITE_BOLD, Command
|
||||||
|
from git_flow.git import Git
|
||||||
|
|
||||||
|
|
||||||
|
BRANCH_FORMAT = "%(refname:short)"
|
||||||
|
|
||||||
|
|
||||||
|
class BranchCommand(Command):
|
||||||
|
def name(self) -> str:
|
||||||
|
return "branch"
|
||||||
|
|
||||||
|
def description(self) -> str:
|
||||||
|
return """Lista ramas del repositorio, agrupandolas por entorno objetivo"""
|
||||||
|
|
||||||
|
def setup_parser(self, parser: ArgumentParser) -> ArgumentParser:
|
||||||
|
parser.add_argument(
|
||||||
|
"environment",
|
||||||
|
nargs="?",
|
||||||
|
help="Entorno de las ramas a listar. Puede ser vacio para listar ramas de todos los entornos, un entorno válido, o 'trash' para listar las ramas eliminadas.",
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def run(self, args: Namespace = Namespace()):
|
||||||
|
self.ensure_initialized()
|
||||||
|
|
||||||
|
self.current_branch = Git.get_current_branch()
|
||||||
|
self.environments = self.flowconfig["flow.branches"].split(",")
|
||||||
|
|
||||||
|
if args.environment is None:
|
||||||
|
self.show_envs()
|
||||||
|
self.show_all_branches()
|
||||||
|
elif args.environment in self.environments:
|
||||||
|
self.show_envs()
|
||||||
|
self.show_env_branches(args.environment)
|
||||||
|
elif args.environment == "trash":
|
||||||
|
self.show_trash_branches()
|
||||||
|
else:
|
||||||
|
raise GitFlowError(f"'{args.environment}' no es un entorno válido.")
|
||||||
|
|
||||||
|
def show_trash_branches(self):
|
||||||
|
branches = self.get_trash_branches()
|
||||||
|
|
||||||
|
if not branches:
|
||||||
|
print("No hay ramas a mostrar.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for branch in branches:
|
||||||
|
prefix = (COLOR_RED + "*") if branch == self.current_branch else " "
|
||||||
|
print(prefix + " " + branch + COLOR_RESET)
|
||||||
|
|
||||||
|
def get_trash_branches(self):
|
||||||
|
return Git("for-each-ref", "refs/heads/trash/", format=BRANCH_FORMAT).lines()
|
||||||
|
|
||||||
|
def show_all_branches(self):
|
||||||
|
for environment in self.environments:
|
||||||
|
self.show_env_branches(environment, len(self.environments) > 1)
|
||||||
|
|
||||||
|
trash = len(self.get_trash_branches())
|
||||||
|
|
||||||
|
if trash:
|
||||||
|
print()
|
||||||
|
print(COLOR_WHITE_BOLD + "Papelera: " + COLOR_RESET + str(trash) + " rama" + ("" if trash == 1 else "s"))
|
||||||
|
|
||||||
|
def show_envs(self):
|
||||||
|
print(COLOR_WHITE_BOLD + "Entornos" + COLOR_RESET)
|
||||||
|
for environment in self.environments:
|
||||||
|
prefix = (COLOR_GREEN + "*") if environment == self.current_branch else " "
|
||||||
|
print(prefix + " " + environment + COLOR_RESET)
|
||||||
|
print()
|
||||||
|
|
||||||
|
def show_env_branches(self, environment: str, show_env: bool = False):
|
||||||
|
is_first_env = environment == self.environments[0]
|
||||||
|
pattern = "refs/heads/" if is_first_env else "refs/heads/release/" + environment + "/"
|
||||||
|
pattern += "*/*"
|
||||||
|
exclude = ["refs/heads/trash/", "refs/heads/release/"] if is_first_env else []
|
||||||
|
branches = Git("for-each-ref", pattern, exclude=exclude, format=BRANCH_FORMAT).lines()
|
||||||
|
|
||||||
|
print(COLOR_WHITE_BOLD + (environment if show_env else "Ramas") + COLOR_RESET)
|
||||||
|
|
||||||
|
if not branches:
|
||||||
|
print("No hay ramas a mostrar.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for branch in branches:
|
||||||
|
prefix = (COLOR_GREEN + "*") if branch == self.current_branch else " "
|
||||||
|
print(prefix + " " + branch + COLOR_RESET)
|
||||||
+4
-1
@@ -89,7 +89,7 @@ class Git:
|
|||||||
def is_repository() -> bool:
|
def is_repository() -> bool:
|
||||||
return Git("rev-parse", is_inside_work_tree=True).code() == 0
|
return Git("rev-parse", is_inside_work_tree=True).code() == 0
|
||||||
|
|
||||||
def __init__(self, subcommand: str, *args: str, **kwargs: str | int | bool | None) -> None:
|
def __init__(self, subcommand: str, *args: str, **kwargs: str | int | bool | list[str] | None) -> None:
|
||||||
self.command = ["git", subcommand]
|
self.command = ["git", subcommand]
|
||||||
|
|
||||||
for option, value in kwargs.items():
|
for option, value in kwargs.items():
|
||||||
@@ -103,6 +103,9 @@ class Git:
|
|||||||
self.command.append(prefix + option)
|
self.command.append(prefix + option)
|
||||||
elif value is None:
|
elif value is None:
|
||||||
continue
|
continue
|
||||||
|
elif isinstance(value, list):
|
||||||
|
for v in value:
|
||||||
|
self.command.append("--" + option + "=" + v)
|
||||||
else:
|
else:
|
||||||
value = value if isinstance(value, str) else str(value)
|
value = value if isinstance(value, str) else str(value)
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from argparse import Namespace, ArgumentParser
|
|||||||
|
|
||||||
from git_flow import GitFlowError
|
from git_flow import GitFlowError
|
||||||
from git_flow.command.base import Command
|
from git_flow.command.base import Command
|
||||||
|
from git_flow.command.branch import BranchCommand
|
||||||
from git_flow.command.commit import CommitCommand
|
from git_flow.command.commit import CommitCommand
|
||||||
from git_flow.command.init import InitCommand
|
from git_flow.command.init import InitCommand
|
||||||
from git_flow.command.merge import MergeCommand
|
from git_flow.command.merge import MergeCommand
|
||||||
@@ -70,6 +71,7 @@ def main():
|
|||||||
MergeCommand(),
|
MergeCommand(),
|
||||||
TagCommand(),
|
TagCommand(),
|
||||||
ReleaseCommand(),
|
ReleaseCommand(),
|
||||||
|
BranchCommand()
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
command.run()
|
command.run()
|
||||||
|
|||||||
Reference in New Issue
Block a user