macsetup
Tus Macs, descritas en YAML
Describe lo que debe tener cada Mac, mira el plan antes de tocar nada y aplícalo.
Escribes en YAML los paquetes y archivos de configuración que lleva una máquina. macsetup plan te muestra la diferencia con lo que hay instalado y macsetup apply la cierra, con Homebrew por debajo. Volver a correrlo en una máquina al día no hace nada.
$ macsetup plan
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Module ┃ Package ┃ State ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ core │ git, gh │ satisfied │
│ cli │ ripgrep │ install │
│ cli │ ~/.config/macsetup/zsh/90-… │ update │
│ lang-python │ uv │ satisfied │
└──────────────┴──────────────────────────────┴───────────┘
1 to install, 1 file to update, 6 satisfied
plan y apply comparten el mismo planificador, así que lo que ves es exactamente lo que se va a hacer.
Un plan antes de cada cambio
plan no cambia nada: lista qué se instala, qué archivo se actualiza y qué ya está bien. status muestra la deriva y untracked lo que instalaste a mano y ningún módulo explica.
Varias Macs, cada una con lo suyo
Los paquetes se agrupan en módulos y los módulos en perfiles como trabajo, personal o mínimo. Cada máquina guarda su propia selección, así que un módulo nuevo en un perfil no se instala solo en todas.
Agregar software es editar YAML
Nunca hay que tocar código. Los casks se marcan explícitamente, porque docker es una fórmula y también Docker Desktop, y un error de tipeo en el manifiesto falla al cargar, no a mitad de la instalación.
Dotfiles sin symlinks
Copia archivos tal cual, renderiza plantillas con variables por máquina o mantiene un bloque marcado dentro de un archivo que no es suyo, como tu .zshrc. Antes de pisar algo que no creó, deja una copia de respaldo.
Tengo varias Macs que deberían compartir un entorno, pero no todas necesitan lo mismo: la de trabajo lleva cosas que la personal no, y una máquina de viaje solo necesita la terminal. Un Brewfile por máquina se desincroniza, y uno solo para todas instala de más.
chezmoi resuelve los dotfiles pero no los paquetes. brew bundle resuelve los paquetes pero no tiene vista previa, ni reporte de deriva, ni idea de qué subconjunto lleva cada máquina. nix-darwin hace todo, si quieres aprender Nix. macsetup queda en el medio: YAML simple, Homebrew por debajo y un plan que lees antes de que pase nada.
apply nunca actualiza lo que ya está instalado, para que poner una máquina al día no se convierta en cuarenta minutos de upgrades; eso queda detrás de --upgrade. Y en una máquina al día el plan tarda menos de un segundo, sin importar el tamaño del catálogo.
En una Mac recién estrenada
Una línea en la Terminal. Instala Homebrew si falta, luego uv, luego macsetup, y termina en el asistente. Cada paso revisa primero, así que se puede volver a correr sin riesgo.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/neosergio/macsetup/main/install.sh)"
Si ya tienes Homebrew
brew install uv
uv tool install macsetup
macsetup init
Sin preguntas
Cada respuesta del asistente tiene su flag, así que una máquina se puede aprovisionar sin nadie delante:
curl -fsSL https://raw.githubusercontent.com/neosergio/macsetup/main/install.sh \
| bash -s -- apply --profile work --yes
La primera vez: un asistente en español o inglés te pide un nombre para la máquina, para qué es y qué apps quieres, todas en una sola lista. Lo guarda y lo aplica.
macsetup init
Qué haría apply, sin cambiar nada:
macsetup plan
Hacerlo:
macsetup apply
Qué se movió desde la última vez, y qué tienes instalado que ningún módulo elegido explica:
macsetup status
macsetup untracked
Cambiar lo que lleva esta máquina. Antes de guardar, la revisión nombra lo que sacas de la selección, que se queda instalado:
macsetup configure
macsetup trae un catálogo de ejemplo para que una instalación nueva tenga con qué correr. La idea es reemplazarlo por el tuyo, en un repo privado, y dejar el motor público. Un módulo es un archivo:
# manifests/modules/cli.yaml
id: cli
name: CLI tools
requires: [fonts]
packages:
- ripgrep
- {name: ghostty, cask: true}
files:
- copy: zsh/cli.zsh
to: ~/.config/macsetup/zsh/90-cli.zsh
export MACSETUP_MANIFESTS=~/dotfiles/manifests
export MACSETUP_FILES=~/dotfiles/files
Perfiles, plantillas, bloques y el resto de las decisiones de diseño están en el README.
macOS
Homebrew, que el instalador pone si falta
Python 3.12 o superior, que uv resuelve solo
Asistente en español e inglés
¿Lo estás usando?
Me sirve saber dónde no encaja: un plan que no coincide con lo que hizo apply, un paquete que detecta mal, o una forma de repartir tus máquinas que los perfiles no cubren.
Abrir un issue