Saltar al contenido
Development

Borrando código muerto, y descubriendo una razón equivocada para una respuesta correcta

Por Victor Da Luz
railsrubydev-logblog-manager

Uno chico hoy: un issue de limpieza para restos de una integración con Medium que arranqué hace semanas (blog-manager ahora publica en Medium a través de Postiz, no con un flujo nativo). El issue listaba cuatro cosas para borrar, un inicializador de CORS, una extensión de navegador, una tarea rake, y tres gemas, con una razón declarada para cada una. Normalmente no cuestiono un issue que escribí yo mismo. Esta vez lo hice de todos modos, y me alegro.

Lo que hice

Borré config/initializers/cors.rb (CORS con comodín acotado a una ruta que ya no existe), la extensión de navegador extension/ (tenía fija esa misma ruta muerta), lib/tasks/medium.rake, y tres gemas ahora sin uso del Gemfile. Directo.

Lo que me sorprendió

El issue decía que la tarea rake debía irse porque “apunta al webhook eliminado.” Abrí el archivo para confirmar antes de borrarlo, y no menciona el webhook para nada. Son tres tareas para rellenar retroactivamente el estado de sindicación de Medium y las imágenes de portada desde snapshots de producción, un asunto completamente distinto. ¿Entonces por qué borrarla?

Revisé qué llamaba realmente: dos clases de servicio, Medium::PublishedBackfill y Medium::HeroImageBackfill. Ninguna existe ya. Se borraron hace semanas en el mismo PR que eliminó todas las columnas medium_* de la base de datos, como parte de la remoción original de Medium. Quien escribió la nota de eliminación de esta tarea rake (yo, evidentemente, con prisa) acertó en la conclusión y se equivocó en el razonamiento. La tarea sí está muerta, solo que no por la razón declarada. Cada una de sus tres tareas lanzaría un NameError en el momento en que se ejecutara.

Esa distinción importa más de lo que parece a primera vista. Si hubiera tomado la razón declarada al pie de la letra y seguido adelante, habría borrado el archivo sin notar que una segunda pieza de funcionalidad, sin relación (rellenar retroactivamente el estado de sindicación desde un snapshot de producción), ya se había podrido en silencio. Resultó estar muerta también, así que no hubo daño esta vez. Pero “la razón declarada está mal” y “la conclusión también está mal” son fallos de tipo distinto, y revisar solo el segundo no cuesta nada extra una vez que ya se está leyendo el archivo.

El issue también pedía limpiar referencias obsoletas a Medium en el README, CLAUDE.md y la documentación. Hice grep primero. No había ninguna, cada mención que quedaba en esos archivos describía con precisión el flujo basado en Postiz que sigue vivo. Otro lugar donde la lista de tareas y la realidad se habían distanciado en silencio desde que la escribí.

Después, la revisión de código del PR atrapó una cosa más que se me había pasado por completo: una credencial huérfana. La extensión se autenticaba contra su webhook con un secreto compartido, guardado en el archivo de credenciales cifrado. Ya nada lo referenciaba, pero no se me había ocurrido revisar credenciales mientras pensaba en código y gemas. La eliminé también, usando un pequeño script no interactivo en vez del flujo habitual de credentials:edit, específicamente para que el valor descifrado nunca tocara una terminal ni un log.

Lo que sigue

Nada dramático, el backlog tiene algunos ítems más de endurecimiento en un espíritu similar. Pero me quedo con una nota para mí mismo: cuando un issue declara una razón para una acción, hay que leer suficiente código para verificar la razón, no solo lo justo para confirmar la acción. Casi siempre coinciden. Cuando no coinciden, vale la pena saber por qué antes de confiar en el siguiente ítem “obviamente correcto”.

Lecturas relacionadas

Development

El botón de commit del editor es un botón de deploy

Confirmar un borrador a main despliega el blog automáticamente. En cuanto eso quedó claro, sync vs. async dejó de ser una cuestión de estilo, más el caso especial de afiliado heredado que un validador nuevo casi rompió.

Leer