Saltar al contenido
← Volver

BrewPackageManager: Cómo saber qué paquetes de Homebrew necesitan actualización sin acordarte de ningún comando

8 min de lectura
SwiftSwiftUImacOSHomebrewMenu BarOpen Source

Tienes 47 paquetes instalados con Homebrew. Tres están desactualizados pero no lo sabes porque nunca ejecutas brew outdated. Cuando te acuerdas, ya llevas semanas con versiones antiguas. Esta app de barra de menú para macOS detecta actualizaciones automáticamente, te avisa con un badge, y te deja actualizar con un clic. Sin terminal, sin comandos, sin excusas.

Instalas Homebrew. Durante la primera semana ejecutas brew update && brew upgrade religiosamente. La segunda semana lo haces cada dos días. La tercera, cuando te acuerdas. Al mes, solo cuando algo falla y sospechas que una versión antigua puede ser el problema.

Este patrón se repite en todos los desarrolladores que conozco. Homebrew es la herramienta de gestión de paquetes más usada en macOS, pero su interfaz es exclusivamente de terminal. No hay notificaciones de actualizaciones. No hay recordatorios. Si no ejecutas el comando, no te enteras.

El problema se agrava cuando tienes docenas de paquetes instalados. Node.js, Python, Git, FFmpeg, ImageMagick, postgresql, redis, nginx. Cada uno con su ciclo de actualizaciones. Algunos con parches de seguridad críticos. Pero como Homebrew no avisa, sigues usando versiones con vulnerabilidades conocidas durante semanas o meses.

La situación típica es esta: estás desarrollando un proyecto, algo falla con un mensaje críptico, buscas en Stack Overflow, descubres que el bug se corrigió en una versión más reciente, ejecutas brew outdated, ves que llevas tres versiones de retraso, actualizas, y el problema desaparece. Tiempo perdido: dos horas. Frustración: alta.

El ciclo infinito de comandos que nunca recuerdas

Homebrew tiene comandos para todo. El problema es recordarlos y ejecutarlos en el orden correcto.

Para ver qué tienes instalado: brew list. Para ver qué está desactualizado: brew outdated. Para actualizar el índice de paquetes: brew update. Para actualizar un paquete específico: brew upgrade nombre. Para actualizar todos: brew upgrade. Para limpiar versiones antiguas: brew cleanup. Para ver servicios: brew services list. Para iniciar un servicio: brew services start nombre.

Son comandos simples individualmente. Pero nadie los ejecuta con la frecuencia necesaria porque requieren abrir terminal, escribir, esperar, leer output. Es fricción suficiente para que lo pospongas indefinidamente.

Lo que necesitaba era algo que hiciera el trabajo sin pedirme nada. Que comprobara actualizaciones automáticamente, me avisara cuando hubiera algo pendiente, y me dejara actualizar sin escribir comandos. Que viviera en la barra de menú, siempre visible, sin ocupar espacio en el dock.

BrewPackageManager: gestión visual desde la barra de menú

La solución es una app nativa de macOS construida con Swift 6 y SwiftUI que vive en la barra de menú. Un icono de cubo que cambia según el estado: normal cuando todo está actualizado, con badge cuando hay actualizaciones pendientes, con flechas girando cuando está procesando.

Al hacer clic en el icono se abre un popover con la lista de paquetes instalados. Cada paquete muestra nombre, versión actual, y si está desactualizado, la versión disponible. Puedes seleccionar paquetes individuales con checkboxes o usar “Select All Outdated” para marcar todos los que necesitan actualización. Un clic en “Update Selected” y la app ejecuta los comandos necesarios mostrando progreso en tiempo real.

La app comprueba actualizaciones automáticamente. Puedes configurar el intervalo de refresco en segundos o desactivarlo si prefieres comprobar manualmente. Por defecto usa 24 horas, suficiente para estar al día sin consumir recursos constantemente.

BrewPackageManager - Vista principal

Instalación

La app requiere macOS 15.0 o superior y Homebrew instalado. Homebrew debe estar en /opt/homebrew/bin/brew para Apple Silicon o /usr/local/bin/brew para Intel.

Desde el DMG:

  1. Descarga el DMG desde la sección de releases en GitHub
  2. Abre el DMG y arrastra BrewPackageManager.app a la carpeta Aplicaciones
  3. Ejecuta desde Aplicaciones

La primera vez que ejecutes la app, macOS te pedirá permiso porque no está firmada con certificado de desarrollador. Ve a Ajustes del Sistema > Privacidad y Seguridad y permite la ejecución.

Si prefieres compilar desde el código fuente, necesitas Xcode 16.0 o superior:

git clone https://github.com/686f6c61/BrewPackageManager.git
cd BrewPackageManager
./create-dmg.sh

El script genera un DMG listo para instalar.

Gestión de paquetes: todo lo que hace brew, pero visual

La pestaña principal muestra todos los paquetes instalados. Puedes alternar entre ver fórmulas (paquetes de línea de comandos), casks (aplicaciones con interfaz gráfica), o ambos.

Cada paquete tiene un menú contextual con opciones. Clic derecho para ver información detallada: descripción, homepage, versión instalada, versión disponible si hay actualización, tap de origen. También puedes desinstalar desde el menú contextual con confirmación para evitar borrados accidentales.

La búsqueda filtra la lista en tiempo real mientras escribes. Útil cuando tienes cientos de paquetes y buscas uno específico.

El botón de actualización ejecuta brew update para sincronizar el índice de paquetes con los repositorios remotos. Esto no actualiza los paquetes instalados, solo descarga la información de qué versiones están disponibles. Es equivalente a actualizar la lista de paquetes disponibles en cualquier gestor de paquetes.

Para actualizar paquetes, seleccionas los que quieras con checkboxes y pulsas “Update Selected”. La app ejecuta brew upgrade para cada paquete seleccionado, mostrando el progreso. Si alguno falla, muestra el error pero continúa con los demás.

Búsqueda e instalación de paquetes nuevos

La pestaña de búsqueda permite encontrar paquetes disponibles en Homebrew que no tienes instalados. Escribes el nombre o parte del nombre, seleccionas si buscas en todas las categorías, solo fórmulas, o solo casks, y la app muestra los primeros 15 resultados.

El límite de 15 resultados es deliberado. Homebrew tiene miles de paquetes y mostrar todos los que coinciden con “python” o “node” generaría una lista interminable. Si tu búsqueda tiene más de 15 resultados, la app te sugiere refinar el término.

BrewPackageManager - Búsqueda de paquetes

Para instalar, seleccionas el paquete y confirmas. La app ejecuta brew install nombre y muestra el progreso. Una vez instalado, el paquete aparece en la lista principal.

Gestión de servicios

Homebrew puede gestionar servicios del sistema: bases de datos, servidores web, colas de mensajes. PostgreSQL, Redis, Nginx, MySQL. La pestaña de servicios muestra todos los servicios disponibles con su estado actual.

Cada servicio muestra si está corriendo o detenido, el PID del proceso si está activo, y qué usuario lo ejecuta. Puedes iniciar, detener o reiniciar servicios con un clic. Los cambios de estado se reflejan en la interfaz inmediatamente.

Las estadísticas en la parte superior muestran cuántos servicios tienes activos y cuántos detenidos. Útil para ver de un vistazo si todo está funcionando o si algo se cayó.

Limpieza de caché y versiones antiguas

Homebrew guarda las versiones anteriores de los paquetes por si necesitas hacer rollback. También guarda archivos descargados en caché. Con el tiempo, esto ocupa gigabytes de espacio en disco.

La pestaña de limpieza analiza cuánto espacio ocupan las versiones antiguas y el caché. Muestra el tamaño total y te ofrece dos opciones: limpiar solo versiones antiguas manteniendo el caché de descargas, o vaciar todo incluyendo el caché.

Si el caché supera 500 MB, la app muestra una alerta sugiriendo limpieza. Es un umbral razonable: suficiente para notar que algo está ocupando espacio, pero no tan agresivo como para molestar constantemente.

Después de limpiar, la app muestra cuánto espacio se liberó. Es satisfactorio ver que recuperaste 3 GB de disco con un clic.

Dependencias

La pestaña de dependencias muestra qué paquetes dependen de otros. Seleccionas un paquete y ves tres listas: dependencias directas (qué necesita este paquete para funcionar), dependencias opcionales y de compilación (necesarias solo para compilar desde fuente), y dependencias inversas (qué otros paquetes dependen de este).

Esta información es crítica antes de desinstalar algo. Si vas a eliminar un paquete que tiene dependencias inversas, romperás otros paquetes. La app te avisa antes de dejarte cometer ese error.

Las estadísticas muestran el total de relaciones de dependencia en tu sistema. En una instalación típica con 50 paquetes, puede haber cientos de dependencias cruzadas.

Historial y estadísticas

La app registra todas las operaciones: instalaciones, actualizaciones, desinstalaciones, limpiezas. El historial persiste entre sesiones y guarda hasta 1000 entradas.

Puedes filtrar el historial por tipo de operación. Ver solo instalaciones, solo actualizaciones, solo errores. Cada entrada muestra qué operación se realizó, sobre qué paquete, cuándo, y si tuvo éxito o falló.

Las estadísticas muestran los 10 paquetes más frecuentemente instalados o actualizados. Útil para identificar qué paquetes actualizas constantemente (quizás porque están en desarrollo activo) o cuáles has reinstalado varias veces (quizás porque algo no funciona bien).

Exportación de datos

Desde los ajustes puedes exportar la lista completa de paquetes instalados a CSV. El archivo incluye nombre, tipo (fórmula o cask), versión instalada, versión disponible si está desactualizado, tap de origen, descripción y homepage.

Útil para documentar el entorno de desarrollo, compartir con compañeros de equipo, o tener un respaldo de qué tenías instalado antes de formatear el Mac.

Configuración

La app tiene varias opciones configurables:

Lanzamiento al inicio de sesión: Actívalo para que la app arranque automáticamente cuando enciendes el Mac. Así siempre tendrás el icono en la barra de menú listo para avisarte de actualizaciones.

Intervalo de refresco automático: Cuántos segundos entre comprobaciones automáticas de actualizaciones. 0 desactiva el refresco automático. Por defecto usa un valor que comprueba cada 24 horas aproximadamente.

Modo solo desactualizados: En la lista principal, muestra solo paquetes que necesitan actualización. Útil si tienes muchos paquetes y solo te interesa ver los pendientes.

Modo depuración: Activa logging detallado para diagnosticar problemas. Los logs se guardan usando el sistema OSLog de macOS y puedes verlos en Console.app.

Actualizaciones de la aplicación

La app comprueba automáticamente si hay versiones nuevas disponibles en GitHub. Cada 24 horas consulta el repositorio y compara con la versión instalada.

Si hay actualización disponible, muestra una notificación con el número de versión y el registro de cambios. Puedes actualizar inmediatamente, posponer con “Remind Me Later”, o marcar esa versión como ignorada si no quieres actualizarla.

El sistema de actualizaciones está separado de Homebrew. La app se actualiza desde GitHub, los paquetes se actualizan desde los repositorios de Homebrew.

Arquitectura técnica

La app está construida con Swift 6 usando las características más recientes del lenguaje: macros @Observable para estado reactivo, strict concurrency checking activado, y SwiftUI para toda la interfaz.

La estructura del proyecto separa responsabilidades:

La concurrencia está diseñada para evitar problemas comunes. El BrewPackagesClient es un actor que serializa todas las llamadas a Homebrew. Esto evita que dos comandos se ejecuten simultáneamente y corrompan el estado. El PackagesStore vive en el @MainActor porque toda actualización de UI debe ocurrir en el hilo principal.

Los comandos de Homebrew se ejecutan con variables de entorno específicas para evitar efectos secundarios. La app configura HOMEBREW_NO_AUTO_UPDATE=1 para que brew install no intente actualizar el índice automáticamente (eso lo controlamos nosotros), y otras variables que desactivan comportamientos interactivos.

El manejo de errores usa un enum AppError con casos específicos: Homebrew no encontrado, timeout en comando, error de parseo JSON, operación cancelada. Cada error tiene un mensaje descriptivo que se muestra al usuario.

Comandos Homebrew que usa la app

La app usa exclusivamente la API JSON de Homebrew para obtener datos estructurados en lugar de parsear texto plano. Esto hace el código más robusto porque el formato JSON está documentado y es estable entre versiones.

Para listar paquetes instalados: brew info --json=v2 --installed

Para ver paquetes desactualizados: brew outdated --json=v2

Para buscar paquetes: brew search --json=v2 <query>

Para listar servicios: brew services list --json

Para limpiar caché: brew cleanup --prune=all

Las operaciones de modificación (install, upgrade, uninstall) no tienen formato JSON porque son interactivas, pero la app captura stdout y stderr para mostrar progreso y detectar errores.

Por qué una app nativa y no una webapp o CLI wrapper

Había alternativas. Podía crear un wrapper en Node.js que ejecutara comandos brew periódicamente. O una webapp local con Electron que mostrara estado en el navegador. O simplemente un cron job que enviara notificaciones.

Elegí app nativa de macOS por varias razones:

Integración con el sistema: La barra de menú es el lugar natural para herramientas de monitorización en macOS. Siempre visible, no ocupa espacio en el dock, accesible con un clic.

Consumo de recursos: Una app Swift nativa consume mínima RAM y CPU comparada con Electron o cualquier solución basada en runtime de JavaScript.

Permisos: macOS permite que apps nativas ejecuten comandos de terminal sin problemas. Las webapps necesitan workarounds complicados para ejecutar comandos locales.

Experiencia de usuario: SwiftUI permite crear interfaces que se sienten nativas porque lo son. Los controles, animaciones, y comportamientos son los que un usuario de Mac espera.

La desventaja es que solo funciona en macOS. Homebrew también existe para Linux, pero esta app no. Si hay demanda suficiente, podría crear una versión Linux con GTK o Qt, pero de momento el foco está en macOS donde vive la mayoría de usuarios de Homebrew.

Casos de uso

El desarrollador olvidadizo: Instalas la app, activas lanzamiento al inicio, y te olvidas. Cuando haya actualizaciones pendientes verás el badge en la barra de menú. Actualizas con un clic y vuelves al trabajo.

El equipo con entorno estandarizado: Exportas tu lista de paquetes a CSV. Compartes el archivo con el equipo. Cada miembro puede ver qué debería tener instalado y verificar si le falta algo.

El desarrollador con espacio limitado: La pestaña de limpieza te avisa cuando el caché de Homebrew crece demasiado. Liberas gigabytes de espacio que no sabías que estabas usando.

El administrador de servicios locales: Si trabajas con PostgreSQL, Redis, Elasticsearch localmente, la pestaña de servicios te muestra qué está corriendo. Un clic para reiniciar un servicio que se colgó.

El curioso de las dependencias: Antes de desinstalar algo, compruebas las dependencias inversas. Evitas romper otros paquetes que dependían de lo que ibas a borrar.

Requisitos y limitaciones

La app necesita macOS 15.0 (Sequoia) o superior. Usa características del sistema operativo que no existen en versiones anteriores.

Homebrew debe estar instalado en la ruta estándar. Si lo instalaste en una ubicación personalizada, la app no lo encontrará.

El App Sandbox está deshabilitado porque la app necesita ejecutar comandos de terminal. Esto es una limitación de macOS: las apps sandboxed no pueden ejecutar procesos arbitrarios. La app no se puede distribuir en la Mac App Store por este motivo.

La app no solicita permisos de acceso total al disco ni a la cámara ni al micrófono. Solo ejecuta comandos brew y lee/escribe en su propio directorio de Application Support.

El código está en GitHub

El proyecto es open source bajo licencia MIT. El código fuente está en github.com/686f6c61/BrewPackageManager.

Puedes compilarlo tú mismo, modificarlo, o contribuir mejoras. Los pull requests son bienvenidos si siguen los patrones establecidos en el código y compilan sin warnings en modo strict concurrency.

El proyecto reutiliza algunos componentes de BrewServicesManager, un proyecto previo bajo MIT del que tomé inspiración para la arquitectura de ejecución de comandos.

Si encuentras bugs o tienes sugerencias, abre un issue en GitHub. Si la app te resulta útil, una estrella en el repositorio ayuda a que otros la descubran.