Merged in refactor/migrate-to-typer-framework (pull request #65)
refactor: replace global command class to typer functions Approved-by: Jonathan Teran
This commit is contained in:
@@ -9,3 +9,6 @@ dist/
|
|||||||
build/
|
build/
|
||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
**/*.egg-info/
|
**/*.egg-info/
|
||||||
|
|
||||||
|
# MacOS
|
||||||
|
.DS_Store
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
3.10
|
3.14
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
image: python:3.10
|
image: python:3.14
|
||||||
|
|
||||||
pipelines:
|
pipelines:
|
||||||
branches:
|
branches:
|
||||||
@@ -10,7 +10,5 @@ pipelines:
|
|||||||
script:
|
script:
|
||||||
- pip install uv
|
- pip install uv
|
||||||
- uv run git-flow tag --token=$BEARER
|
- uv run git-flow tag --token=$BEARER
|
||||||
- git status
|
|
||||||
- git log --oneline -5
|
|
||||||
- uv build
|
- uv build
|
||||||
- uv publish --token=$PYPI_TOKEN
|
- uv publish --token=$PYPI_TOKEN
|
||||||
|
|||||||
+2
-2
@@ -6,9 +6,9 @@ build-backend = "setuptools.build_meta"
|
|||||||
name = "git-flow-envs"
|
name = "git-flow-envs"
|
||||||
description = "Git workflow automation to follow best practices when working with multiple environments"
|
description = "Git workflow automation to follow best practices when working with multiple environments"
|
||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
requires-python = ">= 3.10"
|
requires-python = ">= 3.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"requests"
|
"requests", "typer"
|
||||||
]
|
]
|
||||||
authors = [
|
authors = [
|
||||||
{name = "Alan Facundo Biglieri", email = "abiglieri@renatre.org.ar"},
|
{name = "Alan Facundo Biglieri", email = "abiglieri@renatre.org.ar"},
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from argparse import Namespace, ArgumentParser
|
from argparse import Namespace, ArgumentParser
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from os.path import isfile
|
from os.path import isfile
|
||||||
|
import rich
|
||||||
|
from rich.prompt import Prompt, Confirm
|
||||||
|
|
||||||
from git_flow import (
|
from git_flow import (
|
||||||
BRANCH_TYPES,
|
BRANCH_TYPES,
|
||||||
@@ -44,16 +46,16 @@ class Command(ABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def success(self, msg: str):
|
def success(self, msg: str):
|
||||||
self._print(TYPE_SUCCESS, msg)
|
rich.print(f":white_check_mark: [green]{msg}[/green]")
|
||||||
|
|
||||||
def warning(self, msg: str):
|
def warning(self, msg: str):
|
||||||
self._print(TYPE_WARNING, msg)
|
rich.print(f":warning: [yellow]{msg}[/yellow]")
|
||||||
|
|
||||||
def error(self, msg: str):
|
def error(self, msg: str):
|
||||||
self._print(TYPE_ERROR, msg)
|
rich.print(f":x: [red]{msg}[/red]")
|
||||||
|
|
||||||
def info(self, msg: str):
|
def info(self, msg: str):
|
||||||
self._print(TYPE_INFO, msg)
|
rich.print(f":information: [blue]{msg}[/blue]")
|
||||||
|
|
||||||
def prompt(
|
def prompt(
|
||||||
self,
|
self,
|
||||||
@@ -65,11 +67,7 @@ class Command(ABC):
|
|||||||
onetime = not persistent
|
onetime = not persistent
|
||||||
|
|
||||||
while onetime or persistent:
|
while onetime or persistent:
|
||||||
if default:
|
result = Prompt.ask(prompt)
|
||||||
prompt += f" [{default}]"
|
|
||||||
|
|
||||||
prompt += ": "
|
|
||||||
result = input(prompt)
|
|
||||||
result = result.strip() if strip else result
|
result = result.strip() if strip else result
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
@@ -82,40 +80,10 @@ class Command(ABC):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def confirm(self, question: str, default: bool = True):
|
def confirm(self, question: str, default: bool = True):
|
||||||
suffix = " [Y/n]: " if default else " [y/N]: "
|
return Confirm.ask(question, default=default)
|
||||||
answer = input(question + suffix)
|
|
||||||
|
|
||||||
return default if len(answer) == 0 else answer.startswith("y")
|
|
||||||
|
|
||||||
def choice(self, prompt: str, options: list[str]):
|
def choice(self, prompt: str, options: list[str]):
|
||||||
print(prompt)
|
return Prompt.ask(prompt, choices = options)
|
||||||
|
|
||||||
for i, option in enumerate(options):
|
|
||||||
print(f"\t{i+1}. {option}")
|
|
||||||
|
|
||||||
selection = None
|
|
||||||
|
|
||||||
while selection is None:
|
|
||||||
answer = input(f"Seleccione una opción [1-{len(options)}] o escribala: ")
|
|
||||||
|
|
||||||
if answer.isdigit():
|
|
||||||
answer = int(answer)
|
|
||||||
|
|
||||||
if 1 <= answer and answer <= len(options):
|
|
||||||
selection = options[answer - 1]
|
|
||||||
|
|
||||||
if not self.confirm(
|
|
||||||
f"Seleccionó la opción {answer} ({selection}), ¿es correcto?"
|
|
||||||
):
|
|
||||||
selection = None
|
|
||||||
else:
|
|
||||||
self.error(f"La opción {answer} está fuera del rango permitido.")
|
|
||||||
elif answer in options:
|
|
||||||
selection = answer
|
|
||||||
else:
|
|
||||||
self.error(f"La opción '{answer}' es inválida.")
|
|
||||||
|
|
||||||
return selection
|
|
||||||
|
|
||||||
def setup_parser(self, parser: ArgumentParser) -> ArgumentParser:
|
def setup_parser(self, parser: ArgumentParser) -> ArgumentParser:
|
||||||
return parser
|
return parser
|
||||||
|
|||||||
+44
-50
@@ -1,7 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
from argparse import Namespace, ArgumentParser
|
from argparse import Namespace
|
||||||
|
from typing import Optional
|
||||||
|
import typer
|
||||||
|
|
||||||
from git_flow import GitFlowError
|
from git_flow import GitFlowError
|
||||||
from git_flow.command.base import Command
|
from git_flow.command.base import Command
|
||||||
@@ -19,62 +21,56 @@ REPOSITORY_TOKEN_PATH = ".repository-token"
|
|||||||
LOCALE = "es_AR.UTF-8"
|
LOCALE = "es_AR.UTF-8"
|
||||||
|
|
||||||
|
|
||||||
class GitFlowCommand(Command):
|
app = typer.Typer()
|
||||||
commands: tuple[Command, ...]
|
|
||||||
|
|
||||||
def __init__(self, *args: Command) -> None:
|
|
||||||
self.commands = args
|
|
||||||
|
|
||||||
def name(self) -> str:
|
@app.command()
|
||||||
return "git-flow"
|
def init():
|
||||||
|
run(InitCommand())
|
||||||
|
|
||||||
def description(self) -> str:
|
|
||||||
return """Git flow es una herramienta para automatizar un workflow siguiendo conventional commits, conventional branch y semver."""
|
|
||||||
|
|
||||||
def setup_parser(self, parser: ArgumentParser) -> ArgumentParser:
|
@app.command()
|
||||||
subparsers = parser.add_subparsers(
|
def new():
|
||||||
title="comandos", dest="command", required=True
|
run(NewCommand())
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def commit():
|
||||||
|
run(CommitCommand())
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def merge():
|
||||||
|
run(MergeCommand())
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def tag(token: Optional[str] = None):
|
||||||
|
run(TagCommand(), Namespace(token = token))
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def release(group: Optional[str] = None):
|
||||||
|
run(ReleaseCommand(), Namespace(group = group))
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def branch(env: Optional[str] = None, trash: bool = False, wip: bool = False, all: bool = False):
|
||||||
|
args = Namespace(
|
||||||
|
environment = env,
|
||||||
|
trash = trash,
|
||||||
|
wip = wip,
|
||||||
|
all = all,
|
||||||
)
|
)
|
||||||
|
|
||||||
for command in self.commands:
|
run(BranchCommand(), args)
|
||||||
subparser = subparsers.add_parser(
|
|
||||||
command.name(), description=command.description()
|
|
||||||
)
|
|
||||||
command.setup_parser(subparser)
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def get_parser(self) -> ArgumentParser:
|
def run(command: Command, args: Namespace = Namespace()):
|
||||||
parser = ArgumentParser(self.name(), description=self.description())
|
|
||||||
|
|
||||||
return self.setup_parser(parser)
|
|
||||||
|
|
||||||
def run(self, args: Namespace = Namespace()):
|
|
||||||
args = self.get_parser().parse_args()
|
|
||||||
|
|
||||||
for command in self.commands:
|
|
||||||
if command.name() == args.command:
|
|
||||||
command.init()
|
command.init()
|
||||||
return command.run(args)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
try:
|
try:
|
||||||
locale.setlocale(locale.LC_ALL, LOCALE)
|
command.run(args)
|
||||||
except locale.Error as e:
|
|
||||||
print_warning(f"No se pudo configurar el locale '{LOCALE}': {e}")
|
|
||||||
|
|
||||||
command = GitFlowCommand(
|
|
||||||
InitCommand(),
|
|
||||||
NewCommand(),
|
|
||||||
CommitCommand(),
|
|
||||||
MergeCommand(),
|
|
||||||
TagCommand(),
|
|
||||||
ReleaseCommand(),
|
|
||||||
BranchCommand()
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
command.run()
|
|
||||||
except GitFlowError as e:
|
except GitFlowError as e:
|
||||||
command.error(str(e))
|
command.error(str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -83,8 +79,6 @@ def main():
|
|||||||
print()
|
print()
|
||||||
command.error("Ejecución abortada")
|
command.error("Ejecución abortada")
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
|
def main():
|
||||||
if __name__ == "__main__":
|
app()
|
||||||
main()
|
|
||||||
|
|||||||
Reference in New Issue
Block a user