Files
controlando_git_desde_python/github_crear_repo.py
T
2025-09-11 03:44:53 +02:00

228 lines
7.6 KiB
Python

import marimo
__generated_with = "0.15.2"
app = marimo.App(width="medium")
@app.cell
def _():
import marimo as mo
return (mo,)
@app.cell
def _(mo):
mo.md(r"""# Github: Crear repo y subirlo""")
return
@app.cell
def _():
import os
import requests
import subprocess
from datetime import datetime
# Variables configurables
HOST = "http://10.8.0.6:3123/" # Cambia entre GitHub, GitLab o tu servidor Gitea
USERNAME = "egutierrez"
TOKEN = "7dedbd8257bd85ac023d18fb15f3c26d6fb3c3b5" # Token personal / PAT
# Nombre de la carpeta padre
carpeta_actual = os.path.basename(os.getcwd())
repo_name = carpeta_actual
def crear_repo(host, username, token, repo_name, private=False, description=""):
"""Crea un repositorio en GitHub, GitLab o Gitea según el host.
Devuelve 'ok: nombre_repo url' o 'fail'.
"""
headers = {"Content-Type": "application/json"}
try:
# --- GitHub ---
if "github" in host:
headers["Authorization"] = f"token {token}"
api_url = "https://api.github.com"
resp = requests.get(f"{api_url}/user/repos", headers=headers)
repos_existentes = [r["name"] for r in resp.json()]
if repo_name in repos_existentes:
repo_name += "_" + datetime.now().strftime("%Y%m%d")
payload = {"name": repo_name, "private": private, "description": description}
r = requests.post(f"{api_url}/user/repos", headers=headers, json=payload)
if r.status_code in (200, 201):
url = r.json().get("html_url", "")
return f"ok: {repo_name} {url}"
return "fail"
# --- GitLab ---
elif "gitlab" in host:
headers["PRIVATE-TOKEN"] = token
api_url = f"{host}/api/v4"
resp = requests.get(f"{api_url}/projects?owned=true", headers=headers)
repos_existentes = [r["name"] for r in resp.json()]
if repo_name in repos_existentes:
repo_name += "_" + datetime.now().strftime("%Y%m%d")
payload = {
"name": repo_name,
"visibility": "private" if private else "public",
"description": description,
}
r = requests.post(f"{api_url}/projects", headers=headers, data=payload)
if r.status_code in (200, 201):
url = r.json().get("web_url", "")
return f"ok: {repo_name} {url}"
return "fail"
# --- Gitea ---
elif "gitea" in host or "http" in host:
headers["Authorization"] = f"token {token}"
api_url = f"{host}/api/v1"
resp = requests.get(f"{api_url}/user/repos", headers=headers)
repos_existentes = [r["name"] for r in resp.json()]
if repo_name in repos_existentes:
repo_name += "_" + datetime.now().strftime("%Y%m%d")
payload = {"name": repo_name, "private": private, "description": description}
r = requests.post(f"{api_url}/user/repos", headers=headers, json=payload)
if r.status_code in (200, 201):
url = r.json().get("html_url", "")
return f"ok: {repo_name} {url}"
return "fail"
else:
return "fail"
except Exception:
return "fail"
def run_cmd(cmd):
"""Ejecuta un comando en shell y muestra salida."""
result = subprocess.run(cmd, shell=True, text=True, capture_output=True)
if result.returncode != 0:
print("Error:", result.stderr.strip())
else:
print(result.stdout.strip())
return result.returncode == 0
def commit_and_push(resultado_creacion, commit_message="Commit automático inicial"):
"""
Recibe el resultado de crear_repo, por ejemplo:
'ok: nombre_repo https://gitlab.com/usuario/nombre_repo'
Hace init, commit y push a ese remoto.
"""
if not resultado_creacion.startswith("ok:"):
print("No hay repo remoto válido.")
return
partes = resultado_creacion.split()
if len(partes) < 3:
print("Formato inesperado:", resultado_creacion)
return
repo_name = partes[1]
remote_url = partes[2]
if not os.path.exists(".git"):
run_cmd("git init")
# Detectar rama actual (master, main, etc.)
result = subprocess.run(
"git rev-parse --abbrev-ref HEAD",
shell=True, text=True, capture_output=True
)
branch = result.stdout.strip()
if not branch: # Si aún no hay rama, crear main
branch = "main"
run_cmd(f"git checkout -b {branch}")
run_cmd("git remote remove origin || true")
run_cmd(f"git remote add origin {remote_url}")
run_cmd("git add .")
run_cmd(f'git commit -m "{commit_message}" || echo "Nada que commitear"')
run_cmd(f"git push -u origin {branch}")
# --- Flujo principal ---
resultado = crear_repo(
HOST, USERNAME, TOKEN, repo_name,
private=True,
description=f"Repositorio generado automáticamente para {carpeta_actual}"
)
print("Resultado creación:", resultado)
if resultado.startswith("ok:"):
commit_and_push(resultado)
return HOST, TOKEN, USERNAME, requests
@app.cell
def _(mo):
mo.md(r"""Aqui borramos si generamos sin querer, cuidado!""")
return
@app.cell
def _(HOST, TOKEN, USERNAME, requests):
NOMBRE_REPO = "controlando_git_desde_python"
def borrar_repo(host, username, token, repo_name):
"""Borra un repositorio en GitHub, GitLab o Gitea según el host.
Devuelve 'ok: nombre_repo borrado' o 'fail'.
"""
headers = {"Content-Type": "application/json"}
try:
# --- GitHub ---
if "github" in host:
headers["Authorization"] = f"token {token}"
api_url = "https://api.github.com"
r = requests.delete(f"{api_url}/repos/{username}/{repo_name}", headers=headers)
if r.status_code == 204:
return f"ok: {repo_name} borrado"
return "fail"
# --- GitLab ---
elif "gitlab" in host:
headers["PRIVATE-TOKEN"] = token
api_url = f"{host}/api/v4"
# Ojo: GitLab usa ID o namespace/proyecto
r = requests.delete(f"{api_url}/projects/{username}%2F{repo_name}", headers=headers)
if r.status_code == 202:
return f"ok: {repo_name} borrado"
return "fail"
# --- Gitea ---
elif "gitea" in host or "http" in host:
headers["Authorization"] = f"token {token}"
api_url = f"{host}/api/v1"
r = requests.delete(f"{api_url}/repos/{username}/{repo_name}", headers=headers)
if r.status_code == 204:
return f"ok: {repo_name} borrado"
return "fail"
else:
return "fail"
except Exception as e:
print("Error:", str(e))
return "fail"
# Ejemplo de uso:
resultado_borrado = borrar_repo(HOST, USERNAME, TOKEN, NOMBRE_REPO)
print("Resultado borrado:", resultado_borrado)
return
@app.cell
def _():
return
if __name__ == "__main__":
app.run()