working composectl, first attemp

This commit is contained in:
2026-09-23 12:42:19 -03:00
parent d1829fb5db
commit ef0e91ae41
10 changed files with 66 additions and 66 deletions
+14 -4
View File
@@ -1,3 +1,7 @@
# vim: set ft=toml ts=4 sw=4 et: fenc=utf-8
# SPDX-FileCopyrightText: 2025-present RenatoXSR <renatoxsr@gmail.com>
# SPDX-License-Identifier: BSD-3-Clause-Clear
[build-system]
requires = ["setuptools>=61.0.0", "setuptools-scm[simple]>=9.2"]
build-backend = "setuptools.build_meta"
@@ -28,6 +32,7 @@ dependencies = [
"python-datauri",
"rich",
"Jinja2",
"base58",
]
authors = [
@@ -54,12 +59,17 @@ Homepage = "https://git.silveirarosa.com/renatoxsr/monorepo"
Issues = "https://git.silveirarosa.com/renatoxsr/monorepo/issues"
[project.scripts]
composectl = "scripts.composectl.main"
composectl = "renatoxsr.scripts.composectl:main"
# SETUPTOOLS
[tool.setuptools.packages.find]
where = ["src/renatoxsr-py"]
exclude = ["src/vendor*"]
where = ["src-py"]
exclude = ["vendor*"]
# See: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#src-layout
# # Reserved package names
# FlatLayoutPackageFinder.DEFAULT_EXCLUDE: ClassVar[tuple[str, ...]] = ('ci', 'ci.*', 'bin', 'bin.*', 'debian', 'debian.*', 'doc', 'doc.*', 'docs', 'docs.*', 'documentation', 'documentation.*', 'manpages', 'manpages.*', 'news', 'news.*', 'newsfragments', 'newsfragments.*', 'changelog', 'changelog.*', 'test', 'test.*', 'tests', 'tests.*', 'unit_test', 'unit_test.*', 'unit_tests', 'unit_tests.*', 'example', 'example.*', 'examples', 'examples.*', 'scripts', 'scripts.*', 'tools', 'tools.*', 'util', 'util.*', 'utils', 'utils.*', 'python', 'python.*', 'build', 'build.*', 'dist', 'dist.*', 'venv', 'venv.*', 'env', 'env.*', 'requirements', 'requirements.*', 'tasks', 'tasks.*', 'fabfile', 'fabfile.*', 'site_scons', 'site_scons.*', 'benchmark', 'benchmark.*', 'benchmarks', 'benchmarks.*', 'exercise', 'exercise.*', 'exercises', 'exercises.*', 'htmlcov', 'htmlcov.*', '[._]*', '[._]*.*')
# # Reserved top-level module names
# FlatLayoutModuleFinder.DEFAULT_EXCLUDE: ClassVar[tuple[str, ...]] = ('setup', 'conftest', 'test', 'tests', 'example', 'examples', 'build', 'toxfile', 'noxfile', 'pavement', 'dodo', 'tasks', 'fabfile', '[Ss][Cc]onstruct', 'conanfile', 'manage', 'benchmark', 'benchmarks', 'exercise', 'exercises', '[._]*')
[tool.setuptools.dynamic]
#version = {attr = "__version__"}
@@ -126,4 +136,4 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" # Allow unused vari
quote-style = "double" # Use double quotes (like Black)
indent-style = "space" # Like Black, indent with spaces, rather than tabs.
skip-magic-trailing-comma = false # Like Black, respect magic trailing commas.
line-ending = "auto" # Like Black, automatically detect the appropriate line ending.
line-ending = "auto" # Like Black, automatically detect the appropriate line ending.
@@ -3,14 +3,16 @@
# SPDX-FileCopyrightText: 2025-present RenatoXSR <renatoxsr@gmail.com>
# SPDX-License-Identifier: BSD-3-Clause-Clear
"""RenatoXSR's Python Utilities (monorepo)"""
import os, sys, platform
# Setup
import const
import logger
import renatoxsr.const
import renatoxsr.logger
logger = renatoxsr.logger.logger
logger.debug("platform: %s", platform.platform())
logger.debug("system: %s", platform.system())
logger.debug("node: %s", platform.node())
# Import modules that should be exported
import utils
import scripts.composectl
import renatoxsr.utils
import renatoxsr.scripts.composectl
@@ -290,6 +290,7 @@ class ACTION(Enum):
LOGSF = ("--progress=plain", "logs","-f")
LS = ("--progress=plain", "ls",)
BUILD = ("--progress=plain", "build", "--pull", "--push")
PUSH = ("--progress=plain", "push")
@@ -300,11 +301,15 @@ def main():
p.add_argument("--root", type=Path, default="/srv/containers")
#p.add_argument("--prefix", default="", help="Prefix of compose files")
#p.add_argument("--suffix", default="", help="Suffix to find compose files, before .yml extension")
p.add_argument("--subdir", default="", help="Subdir to find containers")
p.add_argument("--subdir", default="./", help="Subdir to find containers")
p.add_argument("--name", default="*", help="Name of folder to find compose.yml file")
p.add_argument("--cmd", default="docker compose", help="compose command")
p.add_argument("--file", default="compose.yml")
p.add_argument("--profiles", help="Comma separated list of compose profiles")
#p.add_argument("--project", help="Project directories to find compose.yml and/or names")
p.add_argument("--services", help="services of compose file")
p.add_argument("action", choices=[a.name.lower() for a in ACTION])
p.add_argument("project_and_or_services", nargs="*", help="project and/or services (this list will be parsed before used)")
args = p.parse_args()
logger.debug("Args:")
for k,v in vars(args).items():
@@ -360,4 +365,4 @@ if __name__ == "__main__":
logger.critical("[RuntimeError] %s", str(e))
#sys.exit(1)
#EOF
#EOF
@@ -3,4 +3,4 @@
# SPDX-FileCopyrightText: 2025-present RenatoXSR <renatoxsr@gmail.com>
# SPDX-License-Identifier: BSD-3-Clause-Clear
"""`utils` package of RenatoXSR's Python Utilities (monorepo)"""
import uuid7_base58
import renatoxsr.utils.uuid7_base58
+38
View File
@@ -0,0 +1,38 @@
import sys
import uuid
import base58
### Garante suporte nativo no Python 3.14+ ou usa fallback para versões anteriores
if sys.version_info >= (3, 14):
from uuid import uuid7
else:
from uuid6 import uuid7
def uuid7_to_base58() -> tuple[str, str]:
"""Gera um UUIDv7 e o codifica em uma string compacta Base58."""
### 1. Gera o UUIDv7 padrão (128 bits / 16 bytes)
u7 = uuid7()
### 2. Transforma os 16 bytes do UUID em Base58 (sem o checksum do Bitcoin)
# .zfill(22) garante que ele sempre tenha 22 caracteres se houver zeros à esquerda
encoded_b58 = base58.b58encode(u7.bytes).decode('utf-8').zfill(22)
return str(u7), encoded_b58
def base58_to_uuid7(b58_string: str) -> str:
"""Decodifica uma string Base58 de volta para o formato original de UUIDv7."""
### 1. Decodifica a string de volta para os 16 bytes originais
decoded_bytes = base58.b58decode(b58_string)
### 2. Reconstrói o objeto UUID a partir dos bytes
return str(uuid.UUID(bytes=decoded_bytes))
def demo():
""" --- Demonstração de Uso ---"""
### Gerando o ID compactado
uuid_original, id_base58 = uuid7_to_base58()
print(f"UUIDv7 Original (36 chars): {uuid_original}")
print(f"UUIDv7 em Base58 (22 chars): {id_base58}")
### Revertendo para provar que é bidirecional (lossless)
uuid_revertido = base58_to_uuid7(id_base58)
print(f"Decodificado de volta: {uuid_revertido}")
assert uuid_original == uuid_revertido, "Erro: Os UUIDs não coincidem!"
print("\nSucesso! Conversão perfeita e segura para URLs.")
-55
View File
@@ -1,55 +0,0 @@
import sys
import uuid
import base58
### Garante suporte nativo no Python 3.14+ ou usa fallback para versões anteriores
if sys.version_info >= (3, 14):
from uuid import uuid7
else:
from uuid6 import uuid7
def uuid7_to_base58() -> tuple[str, str]:
"""Gera um UUIDv7 e o codifica em uma string compacta Base58."""
### 1. Gera o UUIDv7 padrão (128 bits / 16 bytes)
u7 = uuid7()
### 2. Transforma os 16 bytes do UUID em Base58 (sem o checksum do Bitcoin)
# .zfill(22) garante que ele sempre tenha 22 caracteres se houver zeros à esquerda
encoded_b58 = base58.b58encode(u7.bytes).decode('utf-8').zfill(22)
return str(u7), encoded_b58
def base58_to_uuid7(b58_string: str) -> str:
"""Decodifica uma string Base58 de volta para o formato original de UUIDv7."""
### 1. Decodifica a string de volta para os 16 bytes originais
decoded_bytes = base58.b58decode(b58_string)
### 2. Reconstrói o objeto UUID a partir dos bytes
return str(uuid.UUID(bytes=decoded_bytes))
### --- Demonstração de Uso ---
if **name** == "**main**":
### Gerando o ID compactado
uuid_original, id_base58 = uuid7_to_base58()
print(f"UUIDv7 Original (36 chars): {uuid_original}")
print(f"UUIDv7 em Base58 (22 chars): {id_base58}")
### Revertendo para provar que é bidirecional (lossless)
uuid_revertido = base58_to_uuid7(id_base58)
print(f"Decodificado de volta: {uuid_revertido}")
assert uuid_original == uuid_revertido, "Erro: Os UUIDs não coincidem!"
print("\nSucesso! Conversão perfeita e segura para URLs.")