Modulos de restauracion: - bootstrap: instala yq, age y dependencias base (curl, wget, git, nano, gpg) - ssh: descifra e instala claves SSH desde secrets/sshKeys.tar.gz.age - registry: aplica paquetes apt/snap/flatpak, dotfiles, servicios y configs Docker - thunderbird: instala Thunderbird snap y restaura perfil desde ZIP - claudeCode: configura repositorio apt de Anthropic e instala claude-code - easyEffects: restaura configuracion y presets desde ZIP - wireplumber: restaura dispositivo Bluetooth por defecto y perfiles de audio - cups: restaura impresoras y drivers PPD desde ZIP Scripts de captura (correr antes de push): - scripts/encryptSsh.sh: cifra ~/.ssh con age - scripts/thunderbird/capture.sh: captura perfil de Thunderbird snap - scripts/easyEffects/capture.sh: captura config de EasyEffects flatpak - scripts/wireplumber/capture.sh: captura estado de WirePlumber - scripts/cups/capture.sh: captura impresoras CUPS y PPDs (requiere sudo) Registro de aplicaciones (config/registry.yaml): - 9 paquetes apt, 1 snap (dbeaver-ce), 22 flatpaks incluyendo VSCodium, Bitwarden, Inkscape, LibreOffice, OBS Studio, Nextcloud Desktop, entre otros Secretos incluidos: - secrets/sshKeys.tar.gz.age: claves SSH cifradas con age - secrets/thunderbirdProfile.zip: perfil de Thunderbird sin emails ni cache - secrets/easyEffectsConfig.zip: ajustes y presets de salida de audio - secrets/wireplumberState.zip: estado de audio incluyendo auriculares Bluetooth - secrets/cupsConfig.zip: 5 impresoras configuradas con sus drivers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.4 KiB
Guía de estilo — STP
Nomenclatura: camelCase sin excepciones
Todo identificador del proyecto usa camelCase. No se usa guión bajo (_) ni guión (-) en nombres de variables, funciones o archivos Bash.
| Tipo | Correcto | Incorrecto |
|---|---|---|
| Variable local | packageName |
package_name, pkg |
| Variable exportada | stpRoot, verbose |
STP_ROOT, VERBOSE |
Constante (readonly) |
readonly packagesConfig |
readonly PACKAGES_CONFIG |
| Función | installAptPackages() |
install_apt_packages() |
| Función privada | log::emit |
log::_emit, _emit |
| Archivo Bash | encryptSsh.sh |
encrypt-ssh.sh, encrypt_ssh.sh |
Los nombres de archivos YAML (packages.yaml, audio.yaml) son palabras simples y no requieren separador.
Clean Code — Robert C. Martin
Una función, una responsabilidad
Cada función hace exactamente una cosa. Un bloque de código que necesita un comentario para explicarse debe convertirse en una función con un nombre descriptivo.
# MAL — lógica mezclada con comentario explicativo
if apt-cache show age &>/dev/null 2>&1; then
sudo apt-get install -y age # instala desde apt si está disponible
else
# descarga binario de GitHub...
fi
# BIEN — la intención es legible sin comentarios
if ageIsAvailableInApt; then
installAgeFromApt
else
installAgeFromGithub
fi
Nombres completos, sin abreviaciones
# MAL
for pkg in "${packages[@]}"; do ...
for svc in "${services[@]}"; do ...
# BIEN
for packageName in "${packages[@]}"; do ...
for serviceName in "${services[@]}"; do ...
Palabras prohibidas como nombre de variable: pkg, svc, src, dest, dir, tmp, cfg, val, ret, f, i (salvo índices numéricos en bucles simples).
Predicados como preguntas
Las funciones booleanas se nombran como preguntas que responden verdadero o falso:
pipewireIsEnabled() # ¿PipeWire está habilitado en la config?
isPpaAlreadyAdded() # ¿el PPA ya fue registrado en sources.list?
dotfilesDirectoryIsEmpty() # ¿no hay dotfiles para desplegar?
Comentarios solo para el PORQUÉ
El código expresa el QUÉ. Solo se agrega un comentario cuando el PORQUÉ no es evidente: una restricción externa, una solución provisional, un comportamiento sorpresivo.
# MAL — el comentario dice lo mismo que el código
# Verifica si el PPA ya está en sources.list.d
isPpaAlreadyAdded "$ppaAddress" && continue
# BIEN — el código habla por sí mismo; el comentario solo si hay un "porqué" no obvio
Código funcional sin modo simulación
No existe --dry-run. El sistema es idempotente: verifica el estado actual antes de actuar y omite lo que ya está configurado.
# Antes de instalar un paquete
util::isAptInstalled "$packageName" && continue
# Antes de agregar un PPA
isPpaAlreadyAdded "$ppaAddress" && continue
# Antes de instalar una clave SSH
[[ -f "$destination" ]] && { log::warn "Ya existe: $keyFilename"; return 1; }
Ejecutar el STP dos veces produce exactamente el mismo resultado que ejecutarlo una vez.
Agregar una nueva configuración al sistema
La forma principal de agregar algo al STP es agregar una entrada a config/registry.yaml. No se necesita crear un módulo nuevo para la mayoría de los casos.
# Basta con agregar una línea a la lista:
- id: neovim
type: apt
# La próxima ejecución de stp.sh la detecta y aplica
Tipos disponibles en el registro: ppa, apt, snap, flatpak, dotfile, service, pipewire, video.
Solo creá un módulo nuevo cuando la configuración requiera pasos que ningún tipo del registro puede manejar (compilación desde fuente, instaladores externos, configuración interactiva, etc.).
Estructura de un módulo
#!/usr/bin/env bash
set -euo pipefail
source "$stpRoot/lib/log.sh"
source "$stpRoot/lib/utils.sh"
source "$stpRoot/lib/yaml.sh" # solo si el módulo lee YAML
readonly nombreConfig="$stpRoot/config/nombre.yaml"
# Funciones auxiliares específicas (las más pequeñas y concretas)
helperEspecifico() { ... }
# Funciones principales que usan las auxiliares
hacerAlgo() {
log::info "Descripción breve..."
helperEspecifico
log::ok "Completado"
}
# Verificación inicial: salir si no hay configuración
if [[ ! -f "$nombreConfig" ]]; then
log::info "Sin configuración para este módulo, salteando"
exit 0
fi
# Punto de entrada al final del archivo
hacerAlgo