From c620db69c275237bc42330e39f9feb2c7d6b4dda Mon Sep 17 00:00:00 2001 From: Marco Gallegos Date: Sat, 15 Nov 2025 02:07:44 +0000 Subject: [PATCH] ajustes de optimizacion --- Readme.md | 50 +++-- modules/apps.sh | 131 +++++------- modules/davinci-resolve.sh | 261 +++++++++++++---------- format.sh => modules/disk-format.sh | 33 +-- modules/hyprland-config.sh | 56 +++++ modules/icon_manager.sh | 96 +++++---- modules/icon_manager.sh@@ -45,6 +45,9 @@ | 180 ++++++++++++++++ omarchy-setup.sh | 225 ++++++++----------- 8 files changed, 621 insertions(+), 411 deletions(-) rename format.sh => modules/disk-format.sh (74%) create mode 100644 modules/hyprland-config.sh create mode 100644 modules/icon_manager.sh@@ -45,6 +45,9 @@ diff --git a/Readme.md b/Readme.md index 07e4242..2badca0 100644 --- a/Readme.md +++ b/Readme.md @@ -49,15 +49,17 @@ Al ejecutar `./omarchy-setup.sh`, verás un menú con las siguientes opciones: Selecciona las opciones que deseas instalar: - 1) 📦 Instalar Aplicaciones (VS Code, Cursor, VLC, herramientas) - 2) 🐚 Configurar Zsh (shell, plugins, configuración personalizada) + 1) 📦 Instalar Aplicaciones (VS Code, VLC, drivers, etc.) + 2) 🐚 Configurar Zsh (shell, plugins, config) 3) 🐳 Instalar Docker y Portainer - 4) 🌐 Instalar ZeroTier + 4) 🌐 Instalar ZeroTier VPN 5) 🖨️ Configurar Impresoras (CUPS) - 6) 🎬 Instalar DaVinci Resolve (Intel Edition) - 7) 🔄 Actualizar Sistema - 8) 🧹 Limpiar Paquetes Huérfanos - 9) ✅ Instalar Todo (opciones 1-5) + 6) 🖱️ Instalar Tema de Cursor (Bibata) + 7) 🎨 Gestionar Temas de Iconos (Papirus, Tela, etc.) + 8) 🎬 Instalar DaVinci Resolve (Intel Edition) + A) ✅ Instalar Todo (opciones 1, 2, 3, 4, 5, 6) + F) 💾 Formatear un Disco (FAT32, exFAT, NTFS, ext4) + H) 🎨 Instalar Configuración de Hyprland 0) 🚪 Salir ``` @@ -621,24 +623,28 @@ fi 2. Agrega el módulo al menú en `omarchy-setup.sh`: +Dentro del script `omarchy-setup.sh`, localiza el array asociativo `MODULES` y añade una nueva línea. + ```bash -# En la función show_menu(), agrega: -echo -e " ${GREEN}X)${NC} 📦 Descripción del módulo" - -# En el case statement, agrega: -X) - run_module "nombre-modulo" - echo "" - read -p "Presiona Enter para continuar..." - ;; - -# En la función run_module(), agrega: -"nombre-modulo") - install_nombre_modulo - ;; +# --- Definición de Módulos --- +# Clave: Opción del menú +# Valor: "Nombre del Fichero;Función Principal;Descripción;Tipo (bg/fg)" +declare -A MODULES +MODULES=( + ["1"]="apps;run_module_main;📦 Instalar Aplicaciones;bg" + # ... otros módulos ... + ["N"]="nombre-modulo;install_nombre_modulo;🚀 Mi Nuevo Módulo;fg" +) ``` -3. Si quieres incluirlo en "Instalar Todo", agrégalo al array `modules` en la función `install_all()`. +- **Clave (`"N"`):** La tecla que el usuario presionará en el menú. +- **Valor:** Una cadena de texto con 4 partes separadas por punto y coma (`;`): + 1. `nombre-modulo`: El nombre del fichero `.sh` sin la extensión. + 2. `install_nombre_modulo`: La función dentro de ese fichero que se debe ejecutar. + 3. `🚀 Mi Nuevo Módulo`: La descripción que aparecerá en el menú. + 4. `fg` o `bg`: `fg` (foreground) para scripts interactivos, `bg` (background) para tareas que pueden usar un spinner. + +3. Si quieres incluirlo en la opción "Instalar Todo", añade la clave del menú (en este caso, `"N"`) al array `INSTALL_ALL_CHOICES`. --- diff --git a/modules/apps.sh b/modules/apps.sh index 5f9f47e..00506f7 100755 --- a/modules/apps.sh +++ b/modules/apps.sh @@ -24,48 +24,58 @@ install_homebrew() { fi } -install_apps() { +run_module_main() { log_step "Instalación de Aplicaciones" - - # Paquetes base esenciales + + # --- Definición de Paquetes --- + local PACMAN_BASE=( + git curl wget base-devel unzip neofetch htop fastfetch btop + vim nano tmux xdg-utils xdg-user-dirs stow + ) + local PACMAN_MULTIMEDIA=( + vlc vlc-plugins-all libdvdcss audacity inkscape + ffmpeg gstreamer gst-plugins-good gst-plugins-bad gst-plugins-ugly + yt-dlp + ) + local PACMAN_NETWORK=( + filezilla telegram-desktop scrcpy + ) + local PACMAN_INTEL_GFX=( + mesa vulkan-intel lib32-mesa lib32-vulkan-intel + ) + local PACMAN_INTEL_VIDEO=( + intel-media-driver libva-utils libvdpau-va-gl libva-mesa-driver + ) + local PACMAN_OPENCL=( + ocl-icd libclc clinfo + ) + local AUR_PACKAGES=( + "visual-studio-code-bin" "cursor-bin" "keyd" "fragments" + "logiops" "ltunify" "teamviewer" "intel-compute-runtime" + ) + log_info "Instalando herramientas base..." - sudo pacman -S --noconfirm --needed \ - git curl wget base-devel unzip \ - neofetch htop fastfetch btop \ - vim nano tmux \ - xdg-utils xdg-user-dirs stow || { + sudo pacman -S --noconfirm --needed "${PACMAN_BASE[@]}" || { log_error "Error al instalar herramientas base" return 1 } # Instalar Homebrew install_homebrew - - # Aplicaciones multimedia + log_info "Instalando aplicaciones multimedia..." - sudo pacman -S --noconfirm --needed \ - vlc vlc-plugins-all libdvdcss \ - audacity inkscape \ - ffmpeg gstreamer gst-plugins-good gst-plugins-bad gst-plugins-ugly \ - yt-dlp || { + sudo pacman -S --noconfirm --needed "${PACMAN_MULTIMEDIA[@]}" || { log_warning "Algunos paquetes multimedia no se pudieron instalar" } - - # Configurar VLC como reproductor predeterminado + log_info "Configurando VLC como reproductor predeterminado..." - xdg-mime default vlc.desktop audio/mpeg 2>/dev/null || true - xdg-mime default vlc.desktop audio/mp4 2>/dev/null || true - xdg-mime default vlc.desktop audio/x-wav 2>/dev/null || true - xdg-mime default vlc.desktop video/mp4 2>/dev/null || true - xdg-mime default vlc.desktop video/x-matroska 2>/dev/null || true - xdg-mime default vlc.desktop video/x-msvideo 2>/dev/null || true - xdg-mime default vlc.desktop video/x-ms-wmv 2>/dev/null || true - xdg-mime default vlc.desktop video/webm 2>/dev/null || true - - # Aplicaciones de red y transferencia de archivos + local mime_types=("audio/mpeg" "audio/mp4" "audio/x-wav" "video/mp4" "video/x-matroska" "video/x-msvideo" "video/x-ms-wmv" "video/webm") + for type in "${mime_types[@]}"; do + xdg-mime default vlc.desktop "$type" 2>/dev/null || true + done + log_info "Instalando aplicaciones de red..." - sudo pacman -S --noconfirm --needed \ - filezilla telegram-desktop scrcpy || { + sudo pacman -S --noconfirm --needed "${PACMAN_NETWORK[@]}" || { log_warning "Algunos paquetes de red no se pudieron instalar" } @@ -74,11 +84,9 @@ install_apps() { sudo pacman -S --noconfirm --needed flatpak || { log_warning "Flatpak no se pudo instalar" } - - # Drivers y codecs para Intel Iris Xe + log_info "Instalando drivers y codecs para Intel Iris Xe..." - - # Instalar headers del kernel si son necesarios + KVER="$(uname -r)" if [[ ! -d "/usr/lib/modules/${KVER}/build" ]]; then log_info "Instalando headers de kernel..." @@ -86,57 +94,30 @@ install_apps() { log_warning "No se pudieron instalar headers de kernel" } fi - - # Drivers de gráficos Intel + log_info "Instalando drivers de gráficos Intel..." - sudo pacman -S --noconfirm --needed \ - mesa vulkan-intel \ - lib32-mesa lib32-vulkan-intel || { + sudo pacman -S --noconfirm --needed "${PACMAN_INTEL_GFX[@]}" || { log_warning "Algunos drivers de gráficos no se pudieron instalar" } - - # Drivers de video y hardware acceleration + log_info "Instalando drivers de video Intel (VA-API/VDPAU)..." - sudo pacman -S --noconfirm --needed \ - intel-media-driver \ - libva-utils \ - libvdpau-va-gl \ - libva-mesa-driver || { + sudo pacman -S --noconfirm --needed "${PACMAN_INTEL_VIDEO[@]}" || { log_warning "Algunos drivers de video no se pudieron instalar" } - - # OpenCL para Intel + log_info "Instalando soporte OpenCL para Intel..." - sudo pacman -S --noconfirm --needed \ - ocl-icd \ - libclc \ - clinfo || { + sudo pacman -S --noconfirm --needed "${PACMAN_OPENCL[@]}" || { log_warning "Algunos paquetes OpenCL no se pudieron instalar" } - - # Verificar e instalar helper AUR si es necesario + AUR_HELPER=$(ensure_aur_helper) - - # Intel Compute Runtime desde AUR (necesario para OpenCL en Intel) - log_info "Instalando Intel Compute Runtime desde AUR..." - if [ "$AUR_HELPER" = "yay" ]; then - yay -S --noconfirm intel-compute-runtime || { - log_warning "No se pudo instalar intel-compute-runtime desde AUR" - } - elif [ "$AUR_HELPER" = "paru" ]; then - paru -S --noconfirm intel-compute-runtime || { - log_warning "No se pudo instalar intel-compute-runtime desde AUR" - } - fi - - # Configurar OpenCL para Intel + if [[ ! -f /etc/OpenCL/vendors/intel.icd ]] && [[ -f /usr/lib/intel-opencl/libigdrcl.so ]]; then log_info "Configurando OpenCL para Intel..." sudo mkdir -p /etc/OpenCL/vendors echo "/usr/lib/intel-opencl/libigdrcl.so" | sudo tee /etc/OpenCL/vendors/intel.icd >/dev/null fi - - # Actualizar cache de librerías + sudo ldconfig || true # Verificar instalación de drivers @@ -151,17 +132,7 @@ install_apps() { clinfo 2>/dev/null | grep -E "Platform Name|Device Name" || true fi - # Aplicaciones desde AUR log_info "Instalando aplicaciones desde AUR..." - AUR_PACKAGES=( - "visual-studio-code-bin" - "cursor-bin" - "keyd" - "fragments" - "logiops" - "ltunify" - "teamviewer" - ) for pkg in "${AUR_PACKAGES[@]}"; do log_info "Instalando ${pkg}..." @@ -207,5 +178,5 @@ install_apps() { # Ejecutar si se llama directamente if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - install_apps "$@" + run_module_main "$@" fi diff --git a/modules/davinci-resolve.sh b/modules/davinci-resolve.sh index e290e8b..27923f2 100755 --- a/modules/davinci-resolve.sh +++ b/modules/davinci-resolve.sh @@ -6,148 +6,167 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" +# --- Definición de Dependencias --- +# Paquetes de los repositorios oficiales de Arch +PACMAN_DEPS=( + # Herramientas básicas + unzip patchelf libarchive xdg-user-dirs desktop-file-utils file rsync + # Dependencias de Resolve + libpng libtiff libcurl ocl-icd libxcrypt-compat ffmpeg glu gtk2 fuse2 + # Dependencias de Qt + qt5-base qt5-svg qt5-x11extras + # Drivers y herramientas Intel + intel-media-driver libva-utils libvdpau-va-gl clinfo +) + +# Paquetes del AUR +AUR_DEPS=( + "intel-compute-runtime" # Runtime OpenCL para GPUs Intel +) + +# Directorio de descargas y nombre del ejecutable +DOWNLOADS_DIR="${HOME}/Downloads" +INSTALL_DIR="/opt/resolve" +WRAPPER_PATH="/usr/local/bin/resolve-intel" + # Función para mostrar una barra de progreso # Uso: show_progress TOTAL_ITEMS CURRENT_ITEM "Mensaje" show_progress() { local total=$1 local current=$2 local msg=$3 + local last_percent=${4:-"-1"} # Nuevo: Almacena el último porcentaje mostrado local percent=$((current * 100 / total)) - local completed_len=$((percent / 2)) - local bar="" - for ((i=0; i/dev/null | head -n1 || true)" - + log_step "Iniciando instalación de DaVinci Resolve (Intel Edition)" + + # --- 1. Verificaciones Previas --- + log_info "Realizando verificaciones previas..." + + # Comprobar que el ZIP de Resolve existe + local RESOLVE_ZIP + RESOLVE_ZIP="$(find "${DOWNLOADS_DIR}" -maxdepth 1 -name 'DaVinci_Resolve*_Linux.zip' -print -quit)" + if [[ -z "${RESOLVE_ZIP}" ]]; then - log_error "No se encontró ningún ZIP de DaVinci Resolve en ${ZIP_DIR}." + log_error "No se encontró el ZIP de DaVinci Resolve en ${DOWNLOADS_DIR}." log_info "Ve al sitio de descargas de Blackmagic Design:" log_info "https://www.blackmagicdesign.com/support/" - log_info "Descarga el archivo Linux ZIP y colócalo en ${ZIP_DIR}" + log_info "Descarga el archivo Linux ZIP y colócalo en ${DOWNLOADS_DIR}" return 1 fi - log_info "Usando ZIP: ${RESOLVE_ZIP}" - - start_spinner "Instalando dependencias básicas..." - # Instalación de paquetes básicos - sudo pacman -S --needed --noconfirm \ - unzip patchelf libarchive xdg-user-dirs desktop-file-utils \ - file gtk-update-icon-cache rsync clinfo qt5-base qt5-svg qt5-x11extras \ - libpng libtiff libcurl &> /dev/null - stop_spinner $? "Dependencias básicas instaladas." - - # Configurar OpenCL / Intel GPU - log_info "Configurando runtime OpenCL de Intel y drivers de video..." - - # Eliminar posibles paquetes NVIDIA conflictivos + + # Verificar espacio en disco + local NEEDED_GB=10 + local FREE_KB + FREE_KB=$(df --output=avail -k "${DOWNLOADS_DIR}" | tail -n1) + local FREE_GB=$((FREE_KB / 1024 / 1024)) + if (( FREE_GB < NEEDED_GB )); then + log_error "No hay suficiente espacio libre en ${DOWNLOADS_DIR}: ${FREE_GB}GiB disponibles, se necesitan ${NEEDED_GB}GiB." + return 1 + fi + + # Advertir sobre paquetes NVIDIA if pacman -Qi nvidia &>/dev/null; then - log_warning "Quitando paquetes NVIDIA para evitar conflictos..." - sudo pacman -Rns --noconfirm nvidia nvidia-utils nvidia-settings opencl-nvidia || true - fi - - start_spinner "Instalando headers del kernel (si es necesario)..." - # Instalar headers del kernel si son necesarios - KVER="$(uname -r)" - if [[ ! -d "/usr/lib/modules/${KVER}/build" ]]; then - log_info "Instalando headers de kernel..." - sudo pacman -S --needed --noconfirm linux-headers linux-zen-headers &> /dev/null - fi - stop_spinner $? "Headers del kernel verificados." - - # Instalar runtime OpenCL (compute runtime), desde AUR si es necesario - if ! pacman -Qi intel-compute-runtime &>/dev/null; then - start_spinner "Instalando intel-compute-runtime desde AUR..." - log_info "Instalando intel-compute-runtime (puede venir del AUR)..." - AUR_HELPER=$(ensure_aur_helper) - if [ "$AUR_HELPER" = "yay" ]; then - yay -S --noconfirm intel-compute-runtime || { - log_error "No se pudo instalar intel-compute-runtime" - return 1 - } - elif [ "$AUR_HELPER" = "paru" ]; then - paru -S --noconfirm intel-compute-runtime || { - log_error "No se pudo instalar intel-compute-runtime" - return 1 - } + log_warning "Se detectaron paquetes de NVIDIA. Resolve para Intel puede tener conflictos." + read -p "¿Deseas intentar desinstalar los paquetes de NVIDIA? [s/N]: " confirm + if [[ "${confirm}" =~ ^[Ss]$ ]]; then + start_spinner "Desinstalando paquetes de NVIDIA..." + sudo pacman -Rns --noconfirm nvidia nvidia-utils nvidia-settings opencl-nvidia &> /dev/null + stop_spinner $? "Paquetes de NVIDIA desinstalados." else - if ! sudo pacman -S --needed --noconfirm intel-compute-runtime; then - log_error "No se pudo instalar intel-compute-runtime desde pacman." - log_error "Asegúrate de tener un helper AUR como yay o paru" - return 1 - fi + log_info "Continuando sin desinstalar los paquetes de NVIDIA. La instalación podría fallar." fi - stop_spinner $? "intel-compute-runtime instalado." fi - - start_spinner "Instalando paquetes de video y OpenCL..." - # Instalar otros paquetes Intel / VA-API / OpenCL - sudo pacman -S --needed --noconfirm \ - intel-media-driver \ - ocl-icd \ - libxcrypt-compat \ - ffmpeg \ - glu \ - gtk2 \ - fuse2 \ - libva-utils libvdpau-va-gl &> /dev/null - stop_spinner $? "Paquetes de video instalados." - + + # --- 2. Instalación de Dependencias --- + log_info "Instalando dependencias necesarias..." + + # Instalar headers del kernel correspondiente + local KERNEL_VERSION + KERNEL_VERSION=$(uname -r) + local KERNEL_PKG + # Extrae el nombre base del kernel (ej. 'linux', 'linux-zen', 'linux-lts') + KERNEL_PKG=$(pacman -Qo "/boot/vmlinuz-${KERNEL_VERSION%%-*}" | awk '{print $1}') + if [[ -n "$KERNEL_PKG" && ! -d "/usr/lib/modules/${KERNEL_VERSION}/build" ]]; then + log_info "Instalando headers para el kernel actual (${KERNEL_PKG}-headers)..." + sudo pacman -S --needed --noconfirm "${KERNEL_PKG}-headers" || log_warning "No se pudieron instalar los headers del kernel." + fi + + # Instalar dependencias de Pacman + start_spinner "Instalando dependencias de Pacman..." + sudo pacman -S --needed --noconfirm "${PACMAN_DEPS[@]}" &> /dev/null + stop_spinner $? "Dependencias de Pacman instaladas." + + # Instalar dependencias de AUR + local AUR_HELPER + AUR_HELPER=$(ensure_aur_helper) + if [[ -n "$AUR_HELPER" ]]; then + start_spinner "Instalando dependencias de AUR con ${AUR_HELPER}..." + "$AUR_HELPER" -S --needed --noconfirm "${AUR_DEPS[@]}" &> /dev/null + stop_spinner $? "Dependencias de AUR instaladas." + else + log_error "No se encontró un ayudante de AUR (yay, paru). No se pueden instalar paquetes como 'intel-compute-runtime'." + return 1 + fi + + # --- 3. Configuración del Entorno --- + log_info "Configurando el entorno para OpenCL..." + # Asegurar el archivo ICD para OpenCL de Intel if [[ ! -f /etc/OpenCL/vendors/intel.icd ]]; then log_info "Creando vendor file de OpenCL para Intel..." sudo mkdir -p /etc/OpenCL/vendors echo "/usr/lib/intel-opencl/libigdrcl.so" | sudo tee /etc/OpenCL/vendors/intel.icd >/dev/null fi - + # Crear enlace /etc/pki/tls si es necesario if [[ ! -e /etc/pki/tls ]]; then log_info "Creando enlace /etc/pki/tls → /etc/ssl" sudo mkdir -p /etc/pki sudo ln -sf /etc/ssl /etc/pki/tls fi - + sudo ldconfig || true - + # Verificaciones log_info "Verificando OpenCL instalado..." clinfo | grep -E "Platform Name|Device Name" || true - + log_info "Verificando soporte de decodificación VA-API para H264 / HEVC..." vainfo | grep -E "H264|HEVC" || true - + + # --- 4. Extracción e Instalación de DaVinci Resolve --- start_spinner "Extrayendo DaVinci Resolve del ZIP (puede tardar)..." - NEEDED_GB=10 - FREE_KB=$(df --output=avail -k "${ZIP_DIR}" | tail -n1) - FREE_GB=$((FREE_KB / 1024 / 1024)) - if (( FREE_GB < NEEDED_GB )); then - log_error "No hay suficiente espacio libre en ${ZIP_DIR}: ${FREE_GB} GiB < ${NEEDED_GB} GiB" - return 1 - fi - - WORKDIR="$(mktemp -d -p "${ZIP_DIR}" .resolve-extract-XXXXXXXX)" + local WORKDIR + WORKDIR="$(mktemp -d -p "${DOWNLOADS_DIR}" .resolve-extract-XXXXXXXX)" trap 'rm -rf "${WORKDIR}"' EXIT - unzip -q "${RESOLVE_ZIP}" -d "${WORKDIR}" + unzip -q "${RESOLVE_ZIP}" -d "${WORKDIR}" stop_spinner $? "ZIP extraído." - - RUN_FILE="$(find "${WORKDIR}" -maxdepth 2 -type f -name 'DaVinci_Resolve_*_Linux.run' | head -n1 || true)" + + local RUN_FILE + RUN_FILE="$(find "${WORKDIR}" -maxdepth 2 -type f -name 'DaVinci_Resolve_*_Linux.run' -print -quit)" if [[ -z "${RUN_FILE}" ]]; then log_error "No se encontró el archivo .run dentro del ZIP." return 1 @@ -155,18 +174,19 @@ install_davinci_resolve() { chmod +x "${RUN_FILE}" start_spinner "Extrayendo AppImage..." + local EX_DIR EX_DIR="$(dirname "${RUN_FILE}")" ( cd "${EX_DIR}" && "./$(basename "${RUN_FILE}")" --appimage-extract >/dev/null ) stop_spinner $? "AppImage extraído." - APPDIR="${EX_DIR}/squashfs-root" + local APPDIR="${EX_DIR}/squashfs-root" if [[ ! -d "${APPDIR}" ]]; then log_error "No se extrajo correctamente la carpeta squashfs-root." return 1 fi chmod -R u+rwX,go+rX,go-w "${APPDIR}" - if [[ ! -s "${APPDIR}/bin/resolve" ]]; then + if [[ ! -x "${APPDIR}/bin/resolve" ]]; then log_error "El binario resolve no existe o está vacío." return 1 fi @@ -180,6 +200,7 @@ install_davinci_resolve() { ln -sf /usr/lib/libgmodule-2.0.so.0 libs/libgmodule-2.0.so.0 popd >/dev/null + # --- 5. Aplicar Patches y Copiar Archivos --- log_info "Aplicando RPATH con patchelf (esto puede tardar)..." RPATH_DIRS=( "libs" @@ -193,53 +214,61 @@ install_davinci_resolve() { ) RPATH_ABS="" for p in "${RPATH_DIRS[@]}"; do - RPATH_ABS+="/opt/resolve/${p}:" + RPATH_ABS+="${INSTALL_DIR}/${p}:" done RPATH_ABS+="\$ORIGIN" # Usar barra de progreso para patchelf - if command -v patchelf &>/dev/null; then + if ! command_exists patchelf; then + log_warning "El comando 'patchelf' no está instalado. Es necesario para ajustar las librerías." + start_spinner "Instalando patchelf..." + sudo pacman -S --noconfirm --needed patchelf &> /dev/null + stop_spinner $? "patchelf instalado." + fi + + if command_exists patchelf; then local files_to_patch files_to_patch=$(find "${APPDIR}" -type f -exec file {} + | grep "ELF" | cut -d: -f1) local total_files=$(echo "$files_to_patch" | wc -l) local current_file=0 + local last_percent=-1 echo "$files_to_patch" | while read -r file; do current_file=$((current_file + 1)) - show_progress "$total_files" "$current_file" "Aplicando RPATH..." sudo patchelf --set-rpath "${RPATH_ABS}" "$file" &>/dev/null + last_percent=$(show_progress "$total_files" "$current_file" "Aplicando RPATH..." "$last_percent") done log_success "RPATH aplicado a $total_files archivos." fi start_spinner "Copiando archivos a /opt/resolve..." - sudo rm -rf /opt/resolve - sudo mkdir -p /opt/resolve - sudo rsync -a --delete "${APPDIR}/" /opt/resolve/ - stop_spinner $? "Archivos copiados a /opt/resolve." + sudo rm -rf "${INSTALL_DIR}" + sudo mkdir -p "${INSTALL_DIR}" + sudo rsync -a --delete "${APPDIR}/" "${INSTALL_DIR}/" + stop_spinner $? "Archivos copiados a ${INSTALL_DIR}." - sudo mkdir -p /opt/resolve/.license + sudo mkdir -p "${INSTALL_DIR}/.license" # Enlazar libcrypt legado si es necesario - sudo pacman -S --needed --noconfirm libxcrypt-compat || true sudo ldconfig || true if [[ -e /usr/lib/libcrypt.so.1 ]]; then - sudo ln -sf /usr/lib/libcrypt.so.1 /opt/resolve/libs/libcrypt.so.1 + sudo ln -sf /usr/lib/libcrypt.so.1 "${INSTALL_DIR}/libs/libcrypt.so.1" fi + # --- 6. Crear Wrapper y Acceso Directo --- # Crear wrapper + acceso en escritorio log_info "Creando wrapper y acceso para DaVinci Resolve..." - cat << 'EOF' | sudo tee /usr/local/bin/resolve-intel >/dev/null + cat << EOF | sudo tee "${WRAPPER_PATH}" >/dev/null #!/usr/bin/env bash set -euo pipefail find /tmp -maxdepth 1 -type f -name "qtsingleapp-DaVinci*lockfile" -delete 2>/dev/null || true export QT_QPA_PLATFORM=xcb export QT_AUTO_SCREEN_SCALE_FACTOR=1 export OCL_ICD_VENDORS=/etc/OpenCL/vendors -exec /opt/resolve/bin/resolve "$@" +exec ${INSTALL_DIR}/bin/resolve "\$@" EOF - sudo chmod +x /usr/local/bin/resolve-intel + sudo chmod +x "${WRAPPER_PATH}" mkdir -p "${HOME}/.local/share/applications" cat > "${HOME}/.local/share/applications/davinci-resolve-wrapper.desktop" << EOF @@ -247,8 +276,8 @@ EOF Type=Application Name=DaVinci Resolve (Intel) Comment=DaVinci Resolve usando OpenCL de Intel -Exec=/usr/local/bin/resolve-intel %U -TryExec=/usr/local/bin/resolve-intel +Exec=${WRAPPER_PATH} %U +TryExec=${WRAPPER_PATH} Terminal=false Icon=davinci-resolve Categories=AudioVideo;Video;Graphics; @@ -258,9 +287,9 @@ EOF update-desktop-database "${HOME}/.local/share/applications" >/dev/null 2>&1 || true sudo gtk-update-icon-cache -f /usr/share/icons/hicolor >/dev/null 2>&1 || true - - log_success "DaVinci Resolve (Intel Edition) instalado en /opt/resolve" - log_info "Usa 'resolve-intel' para lanzar la aplicación" + + log_success "DaVinci Resolve (Intel Edition) instalado en ${INSTALL_DIR}" + log_info "Usa '${WRAPPER_PATH##*/}' para lanzar la aplicación" log_info "Para verificar OpenCL: clinfo | grep -E 'Platform Name|Device Name'" return 0 diff --git a/format.sh b/modules/disk-format.sh similarity index 74% rename from format.sh rename to modules/disk-format.sh index 3b9d399..82e3706 100644 --- a/format.sh +++ b/modules/disk-format.sh @@ -1,24 +1,26 @@ #!/usr/bin/env bash set -euo pipefail -# Módulo: Formateo de discos (FAT32 / exFAT / NTFS / ext4) +# =============================================================== +# disk-format.sh - Formateo de discos (FAT32 / exFAT / NTFS / ext4) +# =============================================================== -format_disk() { +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/common.sh" + +run_module_main() { log_step "Módulo: Formateo de discos (FAT32 / exFAT / NTFS / ext4)" # Dependencias local PKGS=(dosfstools exfatprogs ntfs-3g e2fsprogs) - local missing=() - for p in "${PKGS[@]}"; do - if ! pacman -Qi "$p" &>/dev/null; then - missing+=("$p") - fi - done - if [[ ${#missing[@]} -gt 0 ]]; then - log_info "Instalando dependencias: ${missing[*]}" - sudo pacman -Sy --needed --noconfirm "${missing[@]}" || { - log_error "No se pudieron instalar: ${missing[*]}" + if ! pacman -T "${PKGS[@]}" &>/dev/null; then + log_info "Instalando dependencias necesarias..." + start_spinner "Instalando: ${PKGS[*]}..." + if sudo pacman -S --needed --noconfirm "${PKGS[@]}"; then + stop_spinner 0 "Dependencias instaladas." + else + stop_spinner 1 "No se pudieron instalar las dependencias." return 1 - } + fi fi echo @@ -87,4 +89,7 @@ format_disk() { fi } -export -f format_disk \ No newline at end of file +# Ejecutar si se llama directamente +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + run_module_main "$@" +fi \ No newline at end of file diff --git a/modules/hyprland-config.sh b/modules/hyprland-config.sh new file mode 100644 index 0000000..53b8e12 --- /dev/null +++ b/modules/hyprland-config.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# =============================================================== +# hyprland-config.sh - Instala la configuración personalizada de Hyprland +# =============================================================== + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/common.sh" + +# Cargar el gestor de iconos para usar sus funciones +source "${SCRIPT_DIR}/icon_manager.sh" + +run_module_main() { + log_step "Instalación de Configuración de Hyprland" + + # --- 1. Copiar archivos de configuración --- + # La configuración de Hyprland debe estar en una carpeta 'hypr' en la raíz del repo + local source_dir="${SCRIPT_DIR}/../hypr" + local dest_dir="$HOME/.config/hypr" + + if [[ ! -d "$source_dir" ]]; then + log_error "No se encontró el directorio de configuración 'hypr' en la raíz del repositorio." + log_info "Asegúrate de que la carpeta con tu configuración se llame 'hypr'." + return 1 + fi + + # Crear copia de seguridad si ya existe una configuración + if [[ -d "$dest_dir" ]]; then + local backup_dir="${dest_dir}.bak_$(date +%F_%T)" + log_warning "Configuración de Hyprland existente encontrada." + log_info "Creando copia de seguridad en: ${backup_dir}" + if mv "$dest_dir" "$backup_dir"; then + log_success "Copia de seguridad creada." + else + log_error "No se pudo crear la copia de seguridad. Abortando." + return 1 + fi + fi + + log_info "Copiando la configuración de Hyprland a ${dest_dir}..." + # Usamos rsync para una copia eficiente + rsync -a --info=progress2 "$source_dir/" "$dest_dir/" + + # --- 2. Establecer el tema de iconos por defecto --- + log_info "Estableciendo el tema de iconos por defecto (Tela Nord)..." + # Llamamos a la función específica de icon_manager.sh + set_default_icon_theme + + log_success "Configuración de Hyprland instalada correctamente." + log_warning "Por favor, cierra sesión y vuelve a iniciarla para aplicar los cambios." + return 0 +} + +# Ejecutar si se llama directamente +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + run_module_main "$@" +fi \ No newline at end of file diff --git a/modules/icon_manager.sh b/modules/icon_manager.sh index acec7f7..b70b323 100755 --- a/modules/icon_manager.sh +++ b/modules/icon_manager.sh @@ -6,6 +6,9 @@ # en un entorno Hyprland/Omarchy. Incluye temas base y personalizaciones. # +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/common.sh" + # --- Variables Globales --- AUTOSTART_FILE="$HOME/.config/hypr/autostart.conf" TEMP_DIR="/tmp/icon_theme_setup" @@ -15,17 +18,18 @@ ICON_DIR_USER="$HOME/.local/share/icons" # Función para verificar dependencias check_deps() { - if ! command -v git &> /dev/null; then - echo "Error: git no está instalado. Por favor, instálalo para continuar (ej. sudo pacman -S git)." - exit 1 + if ! command_exists git; then + log_error "git no está instalado. Por favor, instálalo para continuar (ej. sudo pacman -S git)." + return 1 fi + return 0 } # Función para aplicar la configuración de forma persistente # Argumento 1: Nombre del tema de iconos (ej. 'Tela-nord-dark') apply_theme() { local theme_name="$1" - echo "Aplicando el tema de iconos '$theme_name'..." + log_info "Aplicando el tema de iconos '$theme_name'..." mkdir -p "$(dirname "$AUTOSTART_FILE")" touch "$AUTOSTART_FILE" @@ -45,41 +49,45 @@ apply_theme() { # Añadir el comando gsettings para el tema seleccionado echo "exec-once = gsettings set org.gnome.desktop.interface icon-theme '$theme_name'" >> "$AUTOSTART_FILE" - echo "¡Tema configurado! La configuración se ha guardado en $AUTOSTART_FILE" + log_success "¡Tema configurado! La configuración se ha guardado en $AUTOSTART_FILE" } # --- Funciones de Instalación de Temas --- # Función auxiliar para asegurar que el tema base Papirus esté instalado ensure_papirus_installed() { - if [ ! -d "$ICON_DIR_USER/Papirus-Dark" ]; then - echo "El tema base Papirus no está instalado. Instalándolo ahora..." + if [[ ! -d "$ICON_DIR_USER/Papirus-Dark" ]]; then + log_info "El tema base Papirus no está instalado. Instalándolo ahora..." git clone --depth 1 https://github.com/PapirusDevelopment/papirus-icon-theme.git "$TEMP_DIR/papirus" "$TEMP_DIR/papirus/install.sh" else - echo "El tema base Papirus ya está instalado." + log_info "El tema base Papirus ya está instalado." fi } -install_tela_nord() { +# Función para instalar y aplicar el tema Tela Nord (usado como default) +set_default_icon_theme() { local theme_name="Tela-nord-dark" - echo "--- Gestionando Tela Nord Icons ---" - if [ -d "$ICON_DIR_USER/$theme_name" ]; then - echo "El tema ya está instalado." + log_info "Gestionando el tema de iconos '$theme_name'..." + if [[ -d "$ICON_DIR_USER/$theme_name" ]]; then + log_info "El tema '$theme_name' ya está instalado." else - echo "Instalando el tema..." + log_info "Instalando el tema '$theme_name'..." + rm -rf "$TEMP_DIR" && mkdir -p "$TEMP_DIR" # Asegurar directorio limpio git clone --depth 1 https://github.com/vinceliuice/Tela-icon-theme.git "$TEMP_DIR/tela" "$TEMP_DIR/tela/install.sh" -c nord + rm -rf "$TEMP_DIR" # Limpieza fi apply_theme "$theme_name" } + install_papirus() { local theme_name="Papirus-Dark" echo "--- Gestionando Papirus Icons (Estándar) ---" ensure_papirus_installed # Si el usuario quiere el Papirus estándar, restauramos los colores por si acaso - if [ -f "$ICON_DIR_USER/papirus-folders" ]; then + if command_exists papirus-folders; then "$ICON_DIR_USER/papirus-folders" --default --theme "$theme_name" fi apply_theme "$theme_name" @@ -88,10 +96,10 @@ install_papirus() { install_candy() { local theme_name="Candy" echo "--- Gestionando Candy Icons ---" - if [ -d "$ICON_DIR_USER/$theme_name" ]; then - echo "El tema ya está instalado." + if [[ -d "$ICON_DIR_USER/$theme_name" ]]; then + log_info "El tema ya está instalado." else - echo "Instalando el tema..." + log_info "Instalando el tema..." git clone --depth 1 https://github.com/EliverLara/candy-icons.git "$TEMP_DIR/candy" "$TEMP_DIR/candy/install.sh" fi @@ -109,7 +117,7 @@ install_papirus_catppuccin() { ensure_papirus_installed # 2. Descargar y ejecutar el script de personalización - echo "Descargando y aplicando el colorizador Catppuccin..." + log_info "Descargando y aplicando el colorizador Catppuccin..." git clone --depth 1 https://github.com/catppuccin/papirus-folders.git "$TEMP_DIR/papirus-folders-catppuccin" chmod +x "$TEMP_DIR/papirus-folders-catppuccin/papirus-folders" @@ -121,20 +129,26 @@ install_papirus_catppuccin() { } # --- Función Principal (Menú) --- -main_menu() { +run_module_main() { + log_step "Gestor de Temas de Iconos para Hyprland" + + if ! check_deps; then + return 1 + fi + while true; do clear - echo "==========================================" - echo " Gestor de Temas de Iconos para Hyprland " - echo "==========================================" + echo -e "${CYAN}==========================================${NC}" + echo -e " ${BOLD}Gestor de Temas de Iconos para Hyprland${NC} " + echo -e "${CYAN}==========================================${NC}" echo "Selecciona el tema que quieres instalar/activar:" echo - echo " 1) Tela (variante Nord)" - echo " 2) Papirus (estándar, oscuro)" - echo " 3) Papirus (con colores Catppuccin Mocha)" - echo " 4) Candy Icons" + echo -e " ${GREEN}1)${NC} Tela (variante Nord)" + echo -e " ${GREEN}2)${NC} Papirus (estándar, oscuro)" + echo -e " ${GREEN}3)${NC} Papirus (con colores Catppuccin Mocha)" + echo -e " ${GREEN}4)${NC} Candy Icons" echo - echo " q) Salir" + echo -e " ${YELLOW}q)${NC} Volver al menú principal" echo read -p "Tu elección: " choice @@ -143,27 +157,25 @@ main_menu() { mkdir -p "$TEMP_DIR" case $choice in - 1) install_tela_nord ;; + 1) set_default_icon_theme ;; 2) install_papirus ;; 3) install_papirus_catppuccin ;; 4) install_candy ;; - [qQ]) break ;; - *) echo "Opción no válida. Inténtalo de nuevo." ;; + [qQ]) + log_info "Volviendo al menú principal." + break + ;; + *) log_error "Opción no válida. Inténtalo de nuevo." ;; esac echo - read -p "Presiona Enter para continuar..." + read -p "Presiona Enter para continuar..." || true done + # Limpieza final + rm -rf "$TEMP_DIR" + return 0 } - -# --- Ejecución del Script --- - -check_deps -main_menu - -# Limpieza final -rm -rf "$TEMP_DIR" -clear -echo "¡Proceso finalizado! Cierra sesión y vuelve a iniciarla para ver los cambios." -exit 0ch \ No newline at end of file +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + run_module_main "$@" +fi \ No newline at end of file diff --git a/modules/icon_manager.sh@@ -45,6 +45,9 @@ b/modules/icon_manager.sh@@ -45,6 +45,9 @@ new file mode 100644 index 0000000..f721460 --- /dev/null +++ b/modules/icon_manager.sh@@ -45,6 +45,9 @@ @@ -0,0 +1,180 @@ +#!/bin/bash +# +# icon_manager.sh (v2) +# +# Un script de gestión para instalar y cambiar entre diferentes temas de iconos +# en un entorno Hyprland/Omarchy. Incluye temas base y personalizaciones. +# + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/common.sh" + +# --- Variables Globales --- +AUTOSTART_FILE="$HOME/.config/hypr/autostart.conf" +TEMP_DIR="/tmp/icon_theme_setup" +ICON_DIR_USER="$HOME/.local/share/icons" + +# --- Funciones de Utilidad --- + +# Función para verificar dependencias +check_deps() { + if ! command_exists git; then + log_error "git no está instalado. Por favor, instálalo para continuar (ej. sudo pacman -S git)." + return 1 + fi + return 0 +} + +# Función para aplicar la configuración de forma persistente +# Argumento 1: Nombre del tema de iconos (ej. 'Tela-nord-dark') +apply_theme() { + local theme_name="$1" + log_info "Aplicando el tema de iconos '$theme_name'..." + + mkdir -p "$(dirname "$AUTOSTART_FILE")" + touch "$AUTOSTART_FILE" + + # Eliminar cualquier configuración de icon-theme anterior para evitar conflictos + sed -i '/exec-once = gsettings set org.gnome.desktop.interface icon-theme/d' "$AUTOSTART_FILE" + + # Añadir el bloque de configuración si no existe + if ! grep -Fq "CONFIGURACIÓN DE TEMA DE ICONOS" "$AUTOSTART_FILE"; then + echo -e "\n# -----------------------------------------------------" >> "$AUTOSTART_FILE" + echo "# CONFIGURACIÓN DE TEMA DE ICONOS" >> "$AUTOSTART_FILE" + echo "# -----------------------------------------------------" >> "$AUTOSTART_FILE" + echo "exec-once = /usr/lib/xdg-desktop-portal-gtk" >> "$AUTOSTART_FILE" + echo "exec-once = sleep 1" >> "$AUTOSTART_FILE" + fi + + # Añadir el comando gsettings para el tema seleccionado + echo "exec-once = gsettings set org.gnome.desktop.interface icon-theme '$theme_name'" >> "$AUTOSTART_FILE" + + # Aplicar el tema en la sesión actual para un efecto inmediato + gsettings set org.gnome.desktop.interface icon-theme "$theme_name" + + log_success "¡Tema configurado! La configuración se ha guardado en $AUTOSTART_FILE" +} + +# --- Funciones de Instalación de Temas --- + +# Función auxiliar para asegurar que el tema base Papirus esté instalado +ensure_papirus_installed() { + if [[ ! -d "$ICON_DIR_USER/Papirus-Dark" ]]; then + log_info "El tema base Papirus no está instalado. Instalándolo ahora..." + git clone --depth 1 https://github.com/PapirusDevelopment/papirus-icon-theme.git "$TEMP_DIR/papirus" + "$TEMP_DIR/papirus/install.sh" + else + log_info "El tema base Papirus ya está instalado." + fi +} + +install_tela_nord() { + local theme_name="Tela-nord-dark" + echo "--- Gestionando Tela Nord Icons ---" + if [[ -d "$ICON_DIR_USER/$theme_name" ]]; then + log_info "El tema ya está instalado." + else + log_info "Instalando el tema..." + git clone --depth 1 https://github.com/vinceliuice/Tela-icon-theme.git "$TEMP_DIR/tela" + "$TEMP_DIR/tela/install.sh" -c nord + fi + apply_theme "$theme_name" +} + +install_papirus() { + local theme_name="Papirus-Dark" + echo "--- Gestionando Papirus Icons (Estándar) ---" + ensure_papirus_installed + # Si el usuario quiere el Papirus estándar, restauramos los colores por si acaso + if command_exists papirus-folders; then + "$ICON_DIR_USER/papirus-folders" --default --theme "$theme_name" + fi + apply_theme "$theme_name" +} + +install_candy() { + local theme_name="Candy" + echo "--- Gestionando Candy Icons ---" + if [[ -d "$ICON_DIR_USER/$theme_name" ]]; then + log_info "El tema ya está instalado." + else + log_info "Instalando el tema..." + git clone --depth 1 https://github.com/EliverLara/candy-icons.git "$TEMP_DIR/candy" + "$TEMP_DIR/candy/install.sh" + fi + apply_theme "$theme_name" +} + +install_papirus_catppuccin() { + local theme_name="Papirus-Dark" + # Catppuccin tiene 4 variantes: latte, frappe, macchiato, mocha. Usaremos Mocha. + local catppuccin_flavor="mocha" + + echo "--- Gestionando Papirus Icons con colores Catppuccin ($catppuccin_flavor) ---" + + # 1. Asegurarse de que el tema base Papirus exista + ensure_papirus_installed + + # 2. Descargar y ejecutar el script de personalización + log_info "Descargando y aplicando el colorizador Catppuccin..." + git clone --depth 1 https://github.com/catppuccin/papirus-folders.git "$TEMP_DIR/papirus-folders-catppuccin" + chmod +x "$TEMP_DIR/papirus-folders-catppuccin/papirus-folders" + + # Ejecutar el script para cambiar el color de las carpetas + "$TEMP_DIR/papirus-folders-catppuccin/papirus-folders" -C "catppuccin-${catppuccin_flavor}" --theme "$theme_name" + + # 3. Aplicar el tema (el nombre sigue siendo Papirus-Dark, pero los iconos han cambiado) + apply_theme "$theme_name" +} + +# --- Función Principal (Menú) --- +run_module_main() { + log_step "Gestor de Temas de Iconos para Hyprland" + + if ! check_deps; then + return 1 + fi + + while true; do + clear + echo -e "${CYAN}==========================================${NC}" + echo -e " ${BOLD}Gestor de Temas de Iconos para Hyprland${NC} " + echo -e "${CYAN}==========================================${NC}" + echo "Selecciona el tema que quieres instalar/activar:" + echo + echo -e " ${GREEN}1)${NC} Tela (variante Nord)" + echo -e " ${GREEN}2)${NC} Papirus (estándar, oscuro)" + echo -e " ${GREEN}3)${NC} Papirus (con colores Catppuccin Mocha)" + echo -e " ${GREEN}4)${NC} Candy Icons" + echo + echo -e " ${YELLOW}q)${NC} Volver al menú principal" + echo + read -p "Tu elección: " choice + + # Limpiar directorio temporal antes de cada operación + rm -rf "$TEMP_DIR" + mkdir -p "$TEMP_DIR" + + case $choice in + 1) install_tela_nord ;; + 2) install_papirus ;; + 3) install_papirus_catppuccin ;; + 4) install_candy ;; + [qQ]) + log_info "Volviendo al menú principal." + break + ;; + *) log_error "Opción no válida. Inténtalo de nuevo." ;; + esac + + echo + read -p "Presiona Enter para continuar..." || true + done + # Limpieza final + rm -rf "$TEMP_DIR" + return 0 +} + +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + run_module_main "$@" +fi \ No newline at end of file diff --git a/omarchy-setup.sh b/omarchy-setup.sh index 4b1bbaf..c232820 100755 --- a/omarchy-setup.sh +++ b/omarchy-setup.sh @@ -77,6 +77,28 @@ stop_spinner() { SPINNER_PID= } +# --- Definición de Módulos --- +# Clave: Opción del menú +# Valor: "Nombre del Fichero;Función Principal;Descripción;Tipo (bg/fg)" +# Tipo 'bg': Tareas de fondo, usan spinner. +# Tipo 'fg': Tareas interactivas (foreground), no usan spinner. +declare -A MODULES +MODULES=( + ["1"]="apps;run_module_main;📦 Instalar Aplicaciones (VS Code, VLC, drivers, etc.);bg" + ["2"]="zsh-config;install_zsh;🐚 Configurar Zsh (shell, plugins, config);bg" + ["3"]="docker;install_docker;🐳 Instalar Docker y Portainer;bg" + ["4"]="zerotier;install_zerotier;🌐 Instalar ZeroTier VPN;bg" + ["5"]="printer;install_printer;🖨️ Configurar Impresoras (CUPS);bg" + ["6"]="mouse_cursor;install_mouse_cursor;🖱️ Instalar Tema de Cursor (Bibata);bg" + ["7"]="icon_manager;run_module_main;🎨 Gestionar Temas de Iconos (Papirus, Tela, etc.);fg" + ["8"]="davinci-resolve;install_davinci_resolve;🎬 Instalar DaVinci Resolve (Intel Edition);fg" + ["H"]="hyprland-config;run_module_main;🎨 Instalar Configuración de Hyprland;bg" + ["F"]="disk-format;run_module_main;💾 Formatear un Disco (FAT32, exFAT, NTFS, ext4);fg" +) + +# Módulos a incluir en la opción "Instalar Todo" +INSTALL_ALL_CHOICES=("1" "2" "3" "4" "5" "6") + # Función para mostrar el menú show_menu() { clear @@ -86,85 +108,66 @@ show_menu() { echo "" echo -e "${BOLD}Selecciona las opciones que deseas instalar:${NC}" echo "" - echo -e " ${GREEN}1)${NC} 📦 Instalar Aplicaciones (VS Code, VLC, drivers, etc.)" - echo -e " ${GREEN}2)${NC} 🐚 Configurar Zsh (shell, plugins, config)" - echo -e " ${GREEN}3)${NC} 🐳 Instalar Docker y Portainer" - echo -e " ${GREEN}4)${NC} 🌐 Instalar ZeroTier" - echo -e " ${GREEN}5)${NC} 🖨️ Configurar Impresoras (CUPS)" - echo -e " ${GREEN}6)${NC} 🖱️ Instalar Tema de Cursor (Bibata)" - echo -e " ${GREEN}7)${NC} 🎨 Gestionar Temas de Iconos (Papirus, Tela, etc.)" - echo -e " ${GREEN}8)${NC} 🎬 Instalar DaVinci Resolve (Intel Edition)" - echo -e " ${GREEN}9)${NC} 🔄 Actualizar Sistema" - echo -e " ${GREEN}C)${NC} 🧹 Limpiar Paquetes Huérfanos" - echo -e " ${GREEN}A)${NC} ✅ Instalar Todo (opciones 1-6)" + # Generar menú dinámicamente + for key in "${!MODULES[@]}"; do + IFS=';' read -r _ _ description _ <<< "${MODULES[$key]}" + # Asegurarse de que las claves numéricas se ordenen correctamente + echo -e " ${GREEN}${key})${NC} ${description}" + done | sort -V + + echo -e " ${GREEN}A)${NC} ✅ Instalar Todo (opciones 1, 2, 3, 4, 5, 6)" echo -e " ${GREEN}0)${NC} 🚪 Salir" echo "" echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" - echo -ne "${BOLD}Selecciona opción [0-9]: ${NC}" + echo -ne "${BOLD}Selecciona opción: ${NC}" } # Función para ejecutar módulo run_module() { - local module_name=$1 - local module_file="${MODULES_DIR}/${module_name}.sh" - - if [[ ! -f "${module_file}" ]]; then - log_error "Módulo ${module_name} no encontrado" + local choice=$1 + IFS=';' read -r module_file func_name description type <<< "${MODULES[$choice]}" + + # Para funciones internas como update_system + if [[ ! -f "${MODULES_DIR}/${module_file}.sh" && "$(type -t "$func_name")" == "function" ]]; then + "$func_name" + return $? + fi + + local full_path="${MODULES_DIR}/${module_file}.sh" + if [[ ! -f "$full_path" ]]; then + log_error "Módulo para la opción '${choice}' (${module_file}.sh) no encontrado." return 1 fi - + # Exportar REPO_BASE para que los módulos lo puedan usar export REPO_BASE - + # Cargar y ejecutar el módulo - source "${module_file}" - - case "${module_name}" in - "apps") - install_apps - ;; - "zsh-config") - install_zsh - ;; - "docker") - install_docker - ;; - "zerotier") - install_zerotier - ;; - "printer") - install_printer - ;; - "mouse_cursor") - install_mouse_cursor - ;; - "davinci-resolve") - install_davinci_resolve - ;; - "icon_manager") - bash "${module_file}" - ;; - *) - log_error "Función no definida para el módulo ${module_name}" - return 1 - ;; - esac + source "$full_path" + + if [[ "$(type -t "$func_name")" != "function" ]]; then + log_error "La función principal '${func_name}' no está definida en '${module_file}.sh'." + return 1 + fi + + "$func_name" + return $? } # Función para instalar todo install_all() { log_step "Instalación Completa de Omarchy" - local modules=("apps" "zsh-config" "docker" "zerotier" "printer" "mouse_cursor") local failed=() - for module in "${modules[@]}"; do - log_info "Procesando módulo: ${module}" - if run_module "${module}"; then - log_success "Módulo ${module} completado" + for choice in "${INSTALL_ALL_CHOICES[@]}"; do + IFS=';' read -r module_file _ description _ <<< "${MODULES[$choice]}" + log_info "Ejecutando: ${description}" + if run_module "${choice}"; then + log_success "Módulo ${module_file} completado" else - log_error "Error en el módulo ${module}" - failed+=("${module}") + log_error "Error en el módulo ${module_file}" + failed+=("${module_file}") fi echo "" done @@ -207,84 +210,35 @@ main() { read -r choice choice=$(echo "${choice// /}" | tr '[:lower:]' '[:upper:]') # Eliminar espacios y convertir a mayúsculas - case "${choice}" in - 1) - start_spinner "Instalando aplicaciones..." - run_module "apps" - stop_spinner $? "Módulo de aplicaciones finalizado." - echo "" - read -p "Presiona Enter para continuar..." - ;; - 2) - start_spinner "Configurando Zsh..." - run_module "zsh-config" - stop_spinner $? "Configuración de Zsh finalizada." - echo "" - read -p "Presiona Enter para continuar..." - ;; - 3) - start_spinner "Instalando Docker..." - run_module "docker" - stop_spinner $? "Instalación de Docker finalizada." - echo "" - read -p "Presiona Enter para continuar..." - ;; - 4) - start_spinner "Instalando ZeroTier..." - run_module "zerotier" - stop_spinner $? "Instalación de ZeroTier finalizada." - echo "" - read -p "Presiona Enter para continuar..." - ;; - 5) - start_spinner "Configurando impresoras..." - run_module "printer" - stop_spinner $? "Configuración de impresoras finalizada." - echo "" - read -p "Presiona Enter para continuar..." - ;; - 6) - start_spinner "Instalando tema de cursor..." - run_module "mouse_cursor" - stop_spinner $? "Tema de cursor instalado." - echo "" - read -p "Presiona Enter para continuar..." - ;; - 7) - # Este módulo es interactivo, no usamos spinner aquí - run_module "icon_manager" - echo "" - read -p "Presiona Enter para continuar..." - ;; - 8) + if [[ -v "MODULES[$choice]" ]]; then + IFS=';' read -r _ _ description type <<< "${MODULES[$choice]}" + + # Manejo especial para DaVinci Resolve + if [[ "$choice" == "8" ]]; then log_warning "DaVinci Resolve requiere el ZIP de instalación en ~/Downloads/" echo -ne "${BOLD}¿Continuar con la instalación? [s/N]: ${NC} " read -r confirm - if [[ "${confirm}" =~ ^[SsYy]$ ]]; then - # El spinner se maneja dentro del módulo de DaVinci - run_module "davinci-resolve" - else + if ! [[ "${confirm}" =~ ^[SsYy]$ ]]; then log_info "Instalación cancelada" + read -p "Presiona Enter para continuar..." + continue fi - echo "" - read -p "Presiona Enter para continuar..." - ;; - 9) - start_spinner "Actualizando el sistema..." - update_system - stop_spinner $? "Sistema actualizado." - echo "" - read -p "Presiona Enter para continuar..." - ;; - C) - start_spinner "Limpiando paquetes huérfanos..." - cleanup_orphans - stop_spinner $? "Limpieza finalizada." - echo "" - read -p "Presiona Enter para continuar..." - ;; - A) - echo -ne "${BOLD}¿Instalar todas las opciones (1-6)? [s/N]: ${NC} " + fi + + if [[ "$type" == "bg" ]]; then + spinner_msg="${description#* }..." # "Instalar Apps..." + start_spinner "Ejecutando: ${spinner_msg}" + run_module "$choice" + stop_spinner $? "Módulo '${description}' finalizado." + else # 'fg' + run_module "$choice" + fi + + echo "" + read -p "Presiona Enter para continuar..." + + elif [[ "$choice" == "A" ]]; then + echo -ne "${BOLD}¿Instalar todas las opciones (1, 2, 3, 4, 5, 6)? [s/N]: ${NC} " read -r confirm if [[ "${confirm}" =~ ^[Ss]$ ]]; then install_all @@ -293,16 +247,13 @@ main() { fi echo "" read -p "Presiona Enter para continuar..." - ;; - 0) + elif [[ "$choice" == "0" ]]; then log_info "Saliendo..." exit 0 - ;; - *) + else log_error "Opción inválida. Presiona Enter para continuar..." read -r - ;; - esac + fi done }