- Un caso en el desarrollo de una aplicación de generación de reportes en el que se agregó la opción
--dry-run para poder simular el resultado de la ejecución
- Esta opción muestra qué tareas se ejecutarían sin realizar cambios reales, lo que permite pruebas seguras y retroalimentación rápida
- Gracias a esto, el desarrollador puede verificar de inmediato la configuración, la accesibilidad y el estado del sistema, y usarla como una herramienta cotidiana de validación
- Se menciona como desventaja un ligero aumento de la complejidad, ya que hay que comprobar la bandera
dryRun dentro del código
- En las aplicaciones imperativas, la función
--dry-run es muy útil, y cuanto antes se incorpore al proyecto, mayor será la eficiencia del desarrollo
Contexto
- La nueva aplicación de generación de reportes que se estaba desarrollando genera reportes cada día hábil, los comprime, los sube a un servidor sftp, revisa las respuestas de error y envía correos de notificación
- Los archivos generados y los archivos de retroalimentación de cada etapa se mueven a distintos directorios según la fase
- Al inicio del desarrollo, se tomó como referencia Subversion y la opción
--dry-run de varios comandos de Linux para agregar la misma funcionalidad
- Esta opción muestra qué ocurriría al ejecutarse sin hacer cambios reales
- Al ejecutar
--dry-run, se muestran por etapas los reportes que se generarían y los que se excluirían, los archivos que se comprimirían y moverían, y los archivos objetivo de subida y descarga por sftp
Uso y beneficios
- Es una función tan útil que se usa todos los días durante el desarrollo y las pruebas
- Al usarla para revisar el estado antes de la ejecución, permite verificar de inmediato la configuración, la accesibilidad y el estado del sistema
- Como no hay cambios reales, puede ejecutarse de forma segura
- Tras cambiar la fecha del archivo de estado de un reporte, se puede comprobar de inmediato si ese reporte se generará o no
- La generación real del reporte toma tiempo, pero
dry-run ofrece retroalimentación rápida
- Incluso en las pruebas de todo el sistema, proporciona un ciclo de validación rápido
Desventajas
- Como hay que comprobar repetidamente la bandera
dryRun dentro del código, se genera una ligera contaminación del código
- En cada etapa principal se revisa la bandera y, en lugar de ejecutar la acción real, solo se imprime el registro
- Sin embargo, esta comprobación no está profundamente integrada, y no se necesita un manejo adicional dentro de la lógica de generación de reportes
- Solo se comprueba en la capa superior que decide si se ejecuta o no
Conclusión
- Las aplicaciones que se ejecutan de forma imperativa y producen resultados encajan muy bien con la opción
--dry-run
- En cambio, no es adecuada para aplicaciones reactivas que esperan mensajes
- Haberla agregado al inicio del proyecto ayudó mucho a mejorar la eficiencia del desarrollo
- No es una función necesaria en todos los casos, pero se considera una herramienta muy útil cuando se aplica en el contexto adecuado
1 comentarios
Comentarios en Hacker News
Al interactuar con sistemas con estado, incluso
--dry-runpuede tener condiciones de carrera (race conditions)La herramienta muestra “qué haría” con el estado actual, pero cuando llega el momento de ejecutar, la situación puede haber cambiado
Por eso prefiero el enfoque del modo “plan” de Terraform. Ese modo genera un plan ejecutable y, si cambian los supuestos del momento en que se planificó, puede detenerse o hacer rollback
Además, evita tener que meter
if dry_run:por todas partes en el código, y simplifica separando planificación y ejecución en una forma comoexecute(plan())Un problema de timing entre DNS Planner y Enactor hizo que un plan antiguo sobrescribiera uno más reciente
El tema también se trató en un hilo anterior de HN
Porque para crear un modo de planificación se necesita un lenguaje específico de dominio o una estructura de datos
(1) capturar el estado del sistema de archivos y guardar el plan → (2) verificar que el estado no haya cambiado, ejecutar y registrar logs → (3) comparar con el estado previo para validar si hubo pérdida de datos
Estoy usando las tres etapas separadas en scripts o flags distintos
rmCuando una herramienta no tiene
--dry-run, a veces lo hago yo mismoPor ejemplo, antes de ejecutar un comando
sedcomplejo, usodiffpara comparar por adelantado los cambiosSe puede revisar la diferencia con algo como
diff -u <(echo "hello") <(echo "hello" | sed "s/hello/hi/g")Lo resumí en mi blog
Me gusta el patrón
--dry-run, pero el código del camino dry debe comportarse igual que el camino realSi solo imprime “esto es lo que haría” y se salta la lógica real, se pueden pasar por alto bugs cuando se ejecute de verdad
Debería correr igual hasta justo antes de una escritura en base de datos o una llamada a API
El dry-run muestra “qué pasaría”, mientras que las pruebas reales son otra cosa
Yo prefiero lo contrario: tener flags como
--commito--execute, y que la ejecución por defecto sea solo lectura (dry)Así se reduce la posibilidad de provocar cambios reales por accidente
--commitEn cambio, sí he visto muchos accidentes por olvidar
--dry-runPor defecto solo compara, y solo reemplaza por hardlinks reales si se usa
--executeEste tipo de confirmación ayuda a reducir errores
--wet-run. Según el contexto, a veces el flag con el significado opuesto resulta más intuitivoDELETE-ACCOUNTHasta ahora no he borrado una cuenta por accidente ni una sola vez
Para evitar contaminar el código, hay que separar la persistencia como una estrategia inyectable
No es buena idea ir dejando
if dry_run:por todos ladosDe hecho, puede ser más seguro dejar explícita la ejecución de producción como
--wet-runAsí solo se decide en un lugar si es dry-run o no — estilo “functional core, imperative shell”
rm --wet-run tempfile.tmpsería molestoSería mejor que por defecto ejecutara de verdad, y en cambio hubiera una opción
--undopara revertir la última operación--wet-run, pero también he usado el enfoque de dejardry-runcomo predeterminado y exigir--no-dry-runpara permitir cambiosEn un servicio, lo ideal sería elegir automáticamente el modo seguro según el entorno de ejecución (dev/prod)
El artículo decía que “agregaron
--dry-runal inicio y resultó inesperadamente útil”,pero en realidad este tipo de flags muchas veces los proponen automáticamente los agentes de coding con IA (por ejemplo, Claude)
Hoy en día que muchas herramientas CLI tengan patrones parecidos podría deberse a este fenómeno de convergencia de código impulsado por agentes
--dry-runde Subversion, también suena a una razón totalmente convincenteYo suelo agregar un flag
--reallya las utilidades CLI, dejando por defecto el modo de solo lecturaLa idea es exigir un paso de confirmación intencional para evitar errores
--i-meant-thatEra un comando para borrar una máquina remota, y por defecto esperaba 10 segundos para dar oportunidad de cancelar
Por suerte, ese flag nunca se usó mal
Una de las cosas geniales de PowerShell es que con solo agregar
[CmdletBinding(SupportsShouldProcess)]ya se habilita automáticamente la función de dry-run con
-WhatIf. Es una función muy práctica-Confirm, y con la funciónShouldProcessse puede interactuar con el umbral de confirmación del usuario. Es un diseño realmente eleganteEn un CLI interno que administro, pongo
if not dry_run:dentro de la parte que hace llamadas REST APIAsí, en lugar de ejecutar la llamada real, se deja un log con el comando CURL para revisar qué request saldría
Pero cuando la integración entre APIs se vuelve compleja, simular eso se hace difícil y termina siendo mucho más complicado que un simple
if not dry_run:Yo también mantengo muchos CLI para pipelines de automatización, y aplico este patrón en casi todas las herramientas
Que lo importante es construir bien primero las herramientas locales
Si el flag
--dry-runestá disperso por todo el código, conviene aplicar el patrón de máquina de estados para separar claramente cada etapa