diff --git a/README.md b/README.md index 6c652bd..4065fb8 100644 --- a/README.md +++ b/README.md @@ -1,119 +1,99 @@ -# 馃殌 git subir +# 馃殌 git-subir -Comando personalizado para automatizar el push de cambios a un repositorio Gitea. Incluye autenticaci贸n segura, commits interactivos, resoluci贸n de conflictos y configuraci贸n automatizada. +Script CLI para automatizar el push de cambios a repositorios Gitea con autenticaci贸n segura, configuraci贸n autom谩tica de remotos, commits interactivos, recuperaci贸n ante errores y cifrado opcional de credenciales. --- -## 馃搨 Archivos incluidos +## 馃摝 Archivos incluidos -### `instalar-subir.sh` -Script de instalaci贸n que: - -- Verifica si `openssl` est谩 instalado (y lo instala si falta). -- Solicita credenciales de Gitea: usuario, token/contrase帽a y URL base de la API. -- Verifica las credenciales contra la API de Gitea. -- Permite guardar las credenciales cifradas con `openssl` o en texto plano. -- Crea el script principal `git-subir.sh` en `~/.scripts/`. -- Genera un alias global `git subir` disponible en todo el sistema. - -### `git-subir.sh` -Script principal que: - -- Carga las credenciales (descifr谩ndolas si est谩n cifradas). -- Detecta cambios sin commitear y ofrece hacer commit autom谩tico. -- Realiza `git push` con autenticaci贸n embebida. -- Si el push falla, intenta `git pull --allow-unrelated-histories`. -- Detecta conflictos y ofrece hacer merge autom谩tico. -- Muestra mensajes claros y estructurados para guiar al usuario. - -### `desinstalar-subir.sh` -Script de desinstalaci贸n que: - -- Elimina el alias global `git subir`. -- Borra el script `git-subir.sh`. -- Elimina las credenciales guardadas (cifradas o no). +| Archivo | Descripci贸n | +|------------------------|-----------------------------------------------------------------------------| +| `instalar-subir.sh` | Instalador interactivo que configura credenciales, instala el comando global `git-subir` y valida entorno. | +| `git-subir` | Script principal que automatiza el flujo de push, commits, configuraci贸n de remotos y recuperaci贸n ante errores. | +| `desinstalar-subir.sh` | Elimina el binario instalado y la configuraci贸n/credenciales guardadas. | --- -## 馃攼 Seguridad +## 馃敡 Requisitos -- Las credenciales pueden guardarse cifradas con `openssl` usando una contrase帽a definida por el usuario. -- El script `git-subir.sh` descifra las credenciales en tiempo de ejecuci贸n y las borra inmediatamente despu茅s de usarlas. -- Si se elige guardar sin cifrar, se almacenan en `~/.scripts/.env` con permisos restringidos (`chmod 600`). - ---- - -## 馃摝 Requisitos - -- `openssl` (se instala autom谩ticamente si falta) -- Acceso a una instancia de Gitea con API habilitada -- Permisos de escritura en `/usr/local/bin` para crear el alias global +- Bash 4+ +- Git instalado y configurado +- `curl`, `jq`, `openssl` disponibles en el sistema +- Acceso a un servidor Gitea con token o usuario/contrase帽a v谩lidos +- Carpeta `~/.local/bin` incluida en el `$PATH` --- ## 馃И Instalaci贸n ```bash -chmod +x desinstalar-subir.sh +chmod +x instalar-subir.sh ./instalar-subir.sh Durante la instalaci贸n se te pedir谩: -Usuario de Gitea +URL base del servidor Gitea (ej: https://gitea.midominio.com) -Token o contrase帽a +Usuario y contrase帽a o token -URL base de la API (ej: https://gitea.midominio.org) +Si quer茅s cifrar las credenciales (usando AES-256-CBC con PBKDF2) -Si quer茅s guardar las credenciales cifradas +Confirmaci贸n para instalar git-subir como comando global -Al finalizar, podr谩s usar el comando: +El script valida las credenciales contra la API de Gitea antes de continuar. + +馃殌 Uso +Una vez instalado, pod茅s usar git-subir desde cualquier repositorio git: bash -git subir +git-subir +El script realiza: + +Carga y descifrado de credenciales (si est谩n cifradas) + +Verificaci贸n de cambios sin commitear + +Commit autom谩tico si lo autoriz谩s + +Verificaci贸n de configuraci贸n del remote origin + +Push al repositorio remoto + +Si el push falla, intenta git pull --rebase y reintenta + +馃攣 Reconfigurar credenciales +Pod茅s ejecutar: + +bash +git-subir --reconfigurar +Esto permite: + +Cambiar usuario/contrase帽a o token + +Elegir si quer茅s cifrar o guardar en texto plano + +Validar nuevamente contra la API + +Reescribir la configuraci贸n en ~/.config/git-subir/ + +馃攼 Seguridad +Cifrado con openssl usando AES-256-CBC y derivaci贸n PBKDF2 + +La contrase帽a de cifrado nunca se guarda + +Los archivos se almacenan en ~/.config/git-subir/ para mantener orden + +El binario se instala en ~/.local/bin/git-subir para uso global 馃Ч Desinstalaci贸n bash -chmod +x ./desinstalar-subir.sh +chmod +x desinstalar-subir.sh ./desinstalar-subir.sh Esto elimina: -El alias git subir +El binario git-subir de ~/.local/bin -El script git-subir.sh - -Las credenciales guardadas - -馃攧 Flujo de uso -Ejecut谩s git subir. - -El script carga las credenciales (descifradas si est谩n cifradas). - -Detecta si hay cambios sin commitear: - -Si hay, ofrece hacer commit autom谩tico. - -Intenta hacer git push al repositorio remoto con autenticaci贸n embebida. - -Si el push falla: - -Intenta git pull --allow-unrelated-histories. - -Si hay conflictos, los muestra y ofrece hacer merge autom谩tico. - -Si todo sale bien, muestra 馃帀 Push completado. - -馃挕 Ejemplo de uso -bash -git subir -Si hay cambios sin commitear, te preguntar谩 si quer茅s hacer commit. - -Si hay conflictos, te preguntar谩 si quer茅s hacer merge autom谩tico. - -Si todo est谩 limpio, sube los cambios directamente. +Las credenciales y configuraci贸n de ~/.config/git-subir 馃 Autor -Nahuel Baglietto Scripts dise帽ados para mejorar la experiencia de trabajo con Git y Gitea, priorizando seguridad, automatizaci贸n y facilidad de uso. - -馃洝锔 Licencia -Este proyecto puede ser usado, modificado y distribuido libremente bajo los t茅rminos que defina su autor. +Nahuel Baglietto diff --git a/credenciales.enc b/credenciales.enc new file mode 100644 index 0000000..6b4676e --- /dev/null +++ b/credenciales.enc @@ -0,0 +1 @@ +Salted__ П|R穗R禞蛥7" B訽螙桫虁^-;W 荥抬 <\譌僆;郱碃孏'|蘇琦 \ No newline at end of file diff --git a/desinstalar-subir.sh b/desinstalar-subir.sh index 844ecfc..bc7d1e6 100755 --- a/desinstalar-subir.sh +++ b/desinstalar-subir.sh @@ -1,11 +1,11 @@ #!/bin/bash -set -e echo "馃Ч Desinstalando git subir..." -sudo rm -f /usr/local/bin/git-subir -rm -f "$HOME/.scripts/git-subir.sh" -rm -f "$HOME/.scripts/.env" -rm -f "$HOME/.scripts/.env.enc" +# Eliminar binario +rm -f "$HOME/.local/bin/git-subir" + +# Eliminar credenciales y config +rm -rf "$HOME/.config/git-subir" echo "鉁 Desinstalaci贸n completa." diff --git a/instalar-subir.sh b/instalar-subir.sh index 1f4a122..186ae4a 100755 --- a/instalar-subir.sh +++ b/instalar-subir.sh @@ -1,147 +1,143 @@ #!/bin/bash -set -e -echo "馃敡 Instalaci贸n del comando git subir" +echo "馃殌 Instalando comando git subir..." -# 馃摝 Verificar openssl -if ! command -v openssl &> /dev/null; then - echo "鈿狅笍 openssl no est谩 instalado. Instalando..." - if command -v apt &> /dev/null; then - sudo apt update && sudo apt install -y openssl - elif command -v pacman &> /dev/null; then - sudo pacman -Sy --noconfirm openssl - else - echo "鉂 No se pudo instalar openssl autom谩ticamente. Instalalo manualmente." - exit 1 - fi -fi - -# 馃搧 Crear carpeta -mkdir -p "$HOME/.scripts" - -# 馃攧 Reconfigurar si existen credenciales -if [[ -f "$HOME/.scripts/.env" || -f "$HOME/.scripts/.env.enc" ]]; then - read -p "鈿狅笍 Ya existen credenciales. 驴Quer茅s reconfigurarlas? (s/n): " reconfig - [[ "$reconfig" != "s" ]] && echo "馃毇 Instalaci贸n cancelada." && exit 0 -fi - -# 馃攼 Solicitar credenciales -read -p "馃懁 Usuario de Gitea: " GITEA_USER -read -s -p "馃攽 Token o contrase帽a: " GITEA_TOKEN +# Solicitar datos +read -p "馃懁 Usuario de Gitea: " USUARIO +read -s -p "馃攽 Token o contrase帽a: " TOKEN echo "" -read -p "馃寪 URL base de la API de Gitea (ej: https://gitea.midominio.org): " GITEA_API_URL +read -p "馃寪 URL base de la API de Gitea: " API_BASE -# 馃攷 Verificar credenciales -response=$(curl -s -u "$GITEA_USER:$GITEA_TOKEN" "$GITEA_API_URL/api/v1/user") -if ! echo "$response" | grep -q '"login":"'"$GITEA_USER"'"'; then - echo "鉂 Credenciales inv谩lidas. Abortando instalaci贸n." - exit 1 +# Verificar credenciales antes de cifrar +ENDPOINTS=("$API_BASE/user" "$API_BASE/api/v1/user") +ENDPOINT_VALIDO="" +for URL in "${ENDPOINTS[@]}"; do + RESP=$(curl -s -o /dev/null -w "%{http_code}" -u "$USUARIO:$TOKEN" "$URL") + echo "馃攳 Probando $URL 鈫 C贸digo: $RESP" + if [ "$RESP" == "200" ]; then + ENDPOINT_VALIDO="$URL" + break + fi +done + +if [ -z "$ENDPOINT_VALIDO" ]; then + echo "鉂 Error de autenticaci贸n. No se encontr贸 endpoint v谩lido." + exit 1 fi -# 馃攼 Cifrar si desea -read -p "驴Quer茅s guardar las credenciales cifradas con openssl? (s/n): " cifrar -if [[ "$cifrar" == "s" ]]; then - echo "馃攼 Ingres谩 una contrase帽a para cifrar:" - read -s passphrase - echo -e "GITEA_USER=$GITEA_USER\nGITEA_TOKEN=$GITEA_TOKEN\nGITEA_API_URL=$GITEA_API_URL" | \ - openssl enc -aes-256-cbc -pbkdf2 -salt -out "$HOME/.scripts/.env.enc" -pass pass:"$passphrase" - rm -f "$HOME/.scripts/.env" - echo "鉁 Credenciales cifradas guardadas." +echo "鉁 Autenticaci贸n exitosa con $ENDPOINT_VALIDO" + +# Crear carpeta segura +CONFIG_DIR="$HOME/.config/git-subir" +mkdir -p "$CONFIG_DIR" + +# Preguntar si desea cifrar +read -p "馃攼 驴Quer茅s cifrar las credenciales? (s/n): " CIFRAR +if [[ "$CIFRAR" == "s" ]]; then + read -s -p "馃攽 Contrase帽a para cifrado: " CLAVE + echo "" + echo "$USUARIO:$TOKEN:$API_BASE" | openssl enc -aes-256-cbc -pbkdf2 -salt -out "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE" else - echo -e "GITEA_USER=$GITEA_USER\nGITEA_TOKEN=$GITEA_TOKEN\nGITEA_API_URL=$GITEA_API_URL" > "$HOME/.scripts/.env" - chmod 600 "$HOME/.scripts/.env" - rm -f "$HOME/.scripts/.env.enc" - echo "鈿狅笍 Credenciales guardadas sin cifrar." + echo "$USUARIO:$TOKEN:$API_BASE" > "$CONFIG_DIR/credenciales.txt" fi -# 馃摐 Script principal -cat <<'EOF' > "$HOME/.scripts/git-subir.sh" +# Crear script git-subir +cat > "$CONFIG_DIR/git-subir" <<'EOF' #!/bin/bash -set -e + +CONFIG_DIR="$HOME/.config/git-subir" # 馃攼 Cargar credenciales -if [[ -f "$HOME/.scripts/.env.enc" ]]; then - echo "馃攼 Ingres谩 la contrase帽a para descifrar tus credenciales:" - read -s passphrase - openssl enc -aes-256-cbc -pbkdf2 -d -in "$HOME/.scripts/.env.enc" -pass pass:"$passphrase" > /tmp/.env.dec - source /tmp/.env.dec - rm /tmp/.env.dec -elif [[ -f "$HOME/.scripts/.env" ]]; then - source "$HOME/.scripts/.env" -else - echo "鉂 No se encontraron credenciales. Ejecut谩 instalar-subir.sh primero." +if [ -f "$CONFIG_DIR/credenciales.enc" ]; then + read -s -p "馃攽 Ingres谩 la contrase帽a de cifrado: " CLAVE + echo "" + CREDS=$(openssl enc -aes-256-cbc -pbkdf2 -d -in "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE" 2>/dev/null) + if [ -z "$CREDS" ]; then + echo "鉂 Error al descifrar credenciales." exit 1 + fi +else + CREDS=$(cat "$CONFIG_DIR/credenciales.txt") fi -# 馃搷 Verificar si estamos en un repositorio Git -if ! git rev-parse --is-inside-work-tree &> /dev/null; then - echo "馃搧 Este directorio no es un repositorio Git." - read -p "驴Quer茅s inicializarlo ahora? (s/n): " init_repo - if [[ "$init_repo" == "s" ]]; then - git init - read -p "馃摝 Ingres谩 el nombre del repositorio remoto (ej: git-operaciones.git): " repo_nombre - remote_url="$GITEA_API_URL/$GITEA_USER/$repo_nombre" - git remote add origin "$remote_url" - echo "鉁 Repositorio inicializado y remoto configurado: $remote_url" - else - echo "馃毇 Operaci贸n cancelada. Ejecut谩 desde un repositorio Git v谩lido." - exit 1 - fi +USUARIO=$(echo "$CREDS" | cut -d: -f1) +TOKEN=$(echo "$CREDS" | cut -d: -f2) +API_BASE=$(echo "$CREDS" | cut -d: -f3) + +# 馃攣 Reconfigurar credenciales +if [[ "$1" == "--reconfigurar" ]]; then + read -p "馃懁 Nuevo usuario: " USUARIO + read -s -p "馃攽 Nuevo token: " TOKEN + echo "" + read -p "馃寪 Nueva URL base: " API_BASE + read -p "馃攼 驴Cifrar credenciales? (s/n): " CIFRAR + if [[ "$CIFRAR" == "s" ]]; then + read -s -p "馃攽 Contrase帽a para cifrado: " CLAVE + echo "" + echo "$USUARIO:$TOKEN:$API_BASE" | openssl enc -aes-256-cbc -pbkdf2 -salt -out "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE" + rm -f "$CONFIG_DIR/credenciales.txt" + else + echo "$USUARIO:$TOKEN:$API_BASE" > "$CONFIG_DIR/credenciales.txt" + rm -f "$CONFIG_DIR/credenciales.enc" + fi + echo "鉁 Credenciales reconfiguradas." + exit 0 fi -remote_url=$(git remote get-url origin | sed 's|https://||') -auth_url="https://$GITEA_USER:$GITEA_TOKEN@$remote_url" +# 馃搨 Verificar si estamos en un repo +git rev-parse --is-inside-work-tree &>/dev/null || { + echo "鉂 No est谩s en un repositorio Git." + exit 1 +} -function marco() { - echo -e "鈺斺晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晽" - echo -e "鈺 $1" - echo -e "鈺氣晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨晲鈺愨暆" +# 馃Ъ Detectar si el repo est谩 vac铆o +git rev-parse HEAD &>/dev/null +if [ $? -ne 0 ]; then + echo "馃搧 El repositorio est谩 vac铆o." + read -p "驴Quer茅s crear README.md inicial? (s/n): " RESP + if [[ "$RESP" == "s" ]]; then + touch README.md + git add README.md + git commit -m "Commit inicial por git subir" + fi +fi + +# 馃寪 Verificar remote origin +git remote -v | grep origin >/dev/null || { + read -p "馃寪 No hay remote origin. Ingres谩 URL del remote: " REMOTE + git remote add origin "$REMOTE" } # 馃摝 Detectar cambios sin commitear -if ! git diff-index --quiet HEAD; then - echo "馃摝 Se detectaron cambios sin commitear:" - git status -s - read -p "驴Quer茅s hacer commit autom谩tico de estos cambios? (s/n): " auto_commit - if [[ "$auto_commit" == "s" ]]; then - read -p "馃摑 Ingres谩 el mensaje de commit: " mensaje - git add . - git commit -m "$mensaje" - echo "鉁 Commit realizado." - fi +if ! git diff-index --quiet HEAD --; then + echo "馃摝 Hay cambios sin commitear." + read -p "驴Quer茅s hacer commit autom谩tico? (s/n): " RESP + if [[ "$RESP" == "s" ]]; then + git add . + git commit -m "Commit autom谩tico por git subir" + fi fi # 馃殌 Intentar push -echo "馃殌 Subiendo archivos al repositorio remoto..." -if ! git push "$auth_url"; then - echo "鈿狅笍 Push fallido. Intentando pull con --allow-unrelated-histories..." - git pull "$auth_url" --allow-unrelated-histories || true - - conflictos=$(git diff --name-only --diff-filter=U) - if [[ -n "$conflictos" ]]; then - echo "馃毃 Conflictos detectados:" - echo "$conflictos" - read -p "驴Hacer merge autom谩tico? (s/n): " merge_auto - if [[ "$merge_auto" == "s" ]]; then - git add . - git commit -m "馃攢 Merge autom谩tico" - else - echo "鉂 Merge cancelado. Resolv茅 los conflictos manualmente." - exit 1 - fi - fi - - git push "$auth_url" +echo "馃殌 Ejecutando git push..." +git push +if [ $? -ne 0 ]; then + echo "鈿狅笍 Push fall贸. Intentando git pull y reintento..." + git pull --rebase + git push fi - -echo "馃帀 Push completado." EOF -chmod +x "$HOME/.scripts/git-subir.sh" +chmod +x "$CONFIG_DIR/git-subir" -# 馃敆 Alias global -echo "Creando alias git-subir..." -echo -e "#!/bin/bash\nexec \"$HOME/.scripts/git-subir.sh\" \"\$@\"" | sudo tee /usr/local/bin/git-subir > /dev/null -sudo chmod +x /usr/local/bin/git-subir +# Instalar en ~/.local/bin +mkdir -p "$HOME/.local/bin" +cp "$CONFIG_DIR/git-subir" "$HOME/.local/bin/git-subir" +chmod +x "$HOME/.local/bin/git-subir" -echo "鉁 Instalaci贸n completa. Us谩 el comando: git subir" +# Asegurar que ~/.local/bin est茅 en PATH +SHELL_RC="$HOME/.bashrc" +[[ "$SHELL" == */zsh ]] && SHELL_RC="$HOME/.zshrc" +grep -q 'export PATH="$HOME/.local/bin:$PATH"' "$SHELL_RC" || echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$SHELL_RC" + +echo "鉁 Instalaci贸n completa. Us谩 'git subir' desde cualquier repositorio."