Leer los registros de cambios antes de actualizar tres dependencias desactualizadas
La misma revisión del repositorio que encontró ningún escaneo de dependencias también marcó tres dependencias específicas del Cargo.toml de Greenhouse como desactualizadas: serde_yaml 0.9 está archivado y sin mantenimiento, rusqlite 0.31 enlazaba estáticamente un SQLite empaquetado de hace dos años, sin toda esa ventana de correcciones posteriores del proyecto original, y thiserror 1 era una versión mayor duplicada ya reemplazada en el resto del árbol de dependencias.
Por qué este enfoque
Ninguna de estas necesitaba una decisión de diseño, solo verificar que la ruta de actualización fuera realmente segura antes de tocar nada. Un cambio de versión en un driver de base de datos y en una biblioteca de serialización es exactamente el tipo de cambio que parece trivial y a veces no lo es.
Implementación
Antes de editar una sola línea, busqué con grep cada punto de uso de los tres crates en todo el código: cuatro usos de serde_yaml::, unas ocho variantes derivadas de thiserror en un enum de errores, y más de una docena de llamadas a rusqlite en la capa de base de datos (conexiones, transacciones, sentencias preparadas, la macro params!, variantes de error específicas). Después revisé cada uso contra lo que realmente cambió en el proyecto original, no solo el número de versión:
- serde_yaml → yaml_serde 0.10.4: confirmado en crates.io como el fork mantenido por la organización YAML, con una API idéntica a serde_yaml (from_str/to_string/Value/Error coinciden todos). Es un cambio de nombre de paquete de Cargo, no una migración de código,
serde_yaml = { package = "yaml_serde", version = "0.10" }y cada punto de uso existente deserde_yaml::en el código sigue compilando sin cambios. - rusqlite 0.31 → 0.40.1: nueve versiones menores, con el SQLite empaquetado saltando de 3.45.1 a 3.53.2. Revisé las notas de lanzamiento de GitHub de cada versión intermedia y comparé cada línea de cambio disruptivo con lo que el db.rs de Greenhouse realmente usa. Los cambios disruptivos se concentraban en tablas virtuales, el caché de sentencias, y conversiones de tipo u64/usize, ninguno de los cuales usa este código (timestamps i64 e IDs de tipo UUID-string en todas partes, sin funciones de vtab/functions/backup/blob).
- thiserror 1 → 2: el propio árbol de dependencias de Tauri ya estaba en thiserror 2 para todo excepto este crate. Los cambios disruptivos de la versión 2.0 son casos límite de format-strings (captura de argumentos posicionales, ambigüedad de índices de tupla) que no aplican a un enum de error derivado simple.
La trampa
Ninguna, y eso fue justamente lo interesante. Tres dependencias, nueve versiones menores de desfase en la peor, y la actualización real fue cargo build funcionando al primer intento. El trabajo no estuvo en escribir código, estuvo en leer suficiente registro de cambios como para saber de antemano que nada se iba a romper: buscar primero los puntos de uso con grep, y después comparar la superficie exacta de la API que esos puntos de uso tocan contra la lista exacta de lo que cambió, en vez de subir la versión y enterarse por el compilador.
Resultados
Las 95 pruebas pasan, incluyendo dos que ya hacían un ciclo completo de serializar-escribir-leer-deserializar sobre los mismos tipos Config que toca el cambio a yaml_serde. cargo build limpio, clippy (deny warnings), y fmt check. Cargo.lock confirma que el paquete anterior serde_yaml desapareció por completo, y que thiserror 1.0.69/2.0.18 ahora coexisten sin problemas, ya que un puñado de dependencias transitivas no relacionadas (bindings de GTK/Android que arrastran los backends no-macOS de Tauri) todavía están fijadas en 1.x.
Lecturas relacionadas
Cierre de la deriva del PRD encontrada en una revisión de código
Cuatro puntos donde la especificación de Greenhouse y el código no coincidían, ninguno era un error, todos eran decisiones tomadas en el código y nunca documentadas.
Dos notas que nadie vio jamás
Greenhouse guardaba fielmente una nota de captura y una nota de traspaso, y no mostraba ninguna de las dos: una no tenía campo en el tipo de wire, la otra tenía un comando funcional que nadie llamaba.
Dos estadísticas, dos definiciones de "capturado"
La racha y la insignia calculaban el mismo concepto de dos formas distintas, y las importaciones estaban acreditando en silencio ideas de hace seis meses como el acto creativo de hoy.