- Um caso em que, no processo de desenvolvimento de um aplicativo de geração de relatórios, foi adicionada a opção
--dry-run para permitir simular o resultado da execução
- Essa opção mostra quais ações seriam executadas sem fazer alterações reais, permitindo testes seguros e feedback rápido
- Com isso, o desenvolvedor consegue verificar imediatamente configurações, acessibilidade e o estado do sistema, usando o recurso como uma ferramenta de verificação do dia a dia
- Como desvantagem, menciona-se um leve aumento de complexidade por ser necessário verificar a flag
dryRun dentro do código
- Em aplicativos imperativos, a funcionalidade
--dry-run é muito útil, e quanto mais cedo ela for introduzida no projeto, maior tende a ser a eficiência no desenvolvimento
Contexto
- O novo aplicativo de geração de relatórios em desenvolvimento tem uma estrutura que gera relatórios todos os dias úteis, compacta esses arquivos, faz upload para um servidor sftp, verifica respostas de erro e envia e-mails de notificação
- Os arquivos gerados e os arquivos de feedback de cada etapa são movidos para diretórios diferentes conforme a fase do processo
- No início do desenvolvimento, ao lembrar do Subversion e da opção
--dry-run de vários comandos Linux, foi adicionada a mesma funcionalidade
- Essa opção mostra o que aconteceria na execução sem realizar mudanças reais
- Ao executar com
--dry-run, são exibidos por etapa os relatórios que seriam gerados e os que seriam excluídos, os arquivos que seriam compactados e movidos, e os arquivos alvo de upload e download via sftp
Uso e benefícios
- É uma funcionalidade tão útil que passou a ser usada diariamente durante o desenvolvimento e os testes
- Quando usada para verificar o estado antes da execução, permite confirmar imediatamente configurações, acessibilidade e o estado do sistema
- Como não há mudanças reais, pode ser executada com segurança
- Após alterar a data do arquivo de estado do relatório, é possível confirmar imediatamente se aquele relatório será gerado ou não
- A geração real do relatório leva tempo, mas o dry-run fornece feedback rápido
- Mesmo em testes do sistema completo, ele oferece um ciclo rápido de validação
Desvantagens
- Como é preciso verificar repetidamente a flag
dryRun dentro do código, ocorre uma pequena poluição no código
- Em cada etapa principal, a flag é verificada para exibir apenas logs em vez de executar de fato
- No entanto, essa verificação não é profunda, e não é necessário tratamento separado dentro da lógica de geração de relatórios
- A checagem ocorre apenas nas camadas superiores que decidem se a execução acontecerá ou não
Conclusão
- Aplicativos executados de forma imperativa e que produzem resultados combinam bem com a opção
--dry-run
- Em contrapartida, ela não é adequada para aplicativos reativos que ficam aguardando mensagens
- O fato de ter sido adicionada no início do projeto ajudou muito a melhorar a eficiência do desenvolvimento
- Não é uma funcionalidade necessária em todos os casos, mas, quando apropriada, é uma ferramenta extremamente útil
1 comentários
Comentários do Hacker News
Ao interagir com sistemas com estado, até um
--dry-runpode sofrer com condições de corrida (race conditions)A ferramenta mostra “o que vai fazer” com base no estado atual, mas, no momento da execução real, a situação pode já ter mudado
Por isso, eu prefiro a abordagem do modo “plan” do Terraform. Esse modo cria um plano executável e, se as suposições feitas no momento do planejamento mudarem, ele pode interromper ou fazer rollback
Além disso, não é preciso espalhar
if dry_run:pelo código, e dá para simplificar separando planejamento e execução no formatoexecute(plan())Por um problema de timing entre o DNS Planner e o Enactor, um plano antigo acabou sobrescrevendo o plano mais recente
Isso também foi discutido em um thread anterior no HN
Afinal, criar um modo de planejamento exige uma linguagem específica de domínio ou uma estrutura de dados própria
(1) capturar o estado do sistema de arquivos e salvar o plano → (2) verificar se o estado não mudou, então executar e registrar logs → (3) comparar com o estado anterior para validar se houve perda de dados
Estou usando essas três etapas separadas em scripts ou flags diferentes
rmQuando alguma ferramenta não tem
--dry-run, às vezes eu mesmo monto algo equivalentePor exemplo, antes de executar um comando
sedmais complexo, usodiffpara comparar previamente as mudançasDá para verificar a diferença com algo como
diff -u <(echo "hello") <(echo "hello" | sed "s/hello/hi/g")Reuni mais exemplos no meu blog
Eu gosto do padrão
--dry-run, mas o código do caminho dry precisa se comportar igual ao caminho realSe ele só imprimir “o que faria” e pular a lógica de verdade, bugs podem passar despercebidos na execução real
Ele deveria rodar da mesma forma até imediatamente antes de uma escrita no banco de dados ou de uma chamada de API
O dry-run serve para mostrar “o que aconteceria”, enquanto teste real é outro assunto
Eu prefiro o contrário: ter uma flag
--commitou--execute, e deixar a execução padrão como somente leitura (dry)Assim, a chance de causar mudanças reais por acidente diminui
--commité explicitadoJá houve muitos acidentes por executar algo esquecendo do
--dry-runPor padrão ela só compara, e só substitui por hardlinks quando se usa
--executeEsse tipo de etapa de confirmação é eficaz para reduzir erros
--wet-run. Dependendo do caso, uma flag com o sentido oposto pode ser mais intuitivaDELETE-ACCOUNTAté hoje nunca apaguei uma conta por engano
Para evitar poluir o código, a persistência deve ser separada como uma estratégia injetável
Não é uma boa ideia espalhar
if dry_run:por toda parteNa verdade, pode ser mais seguro exigir explicitamente a execução de produção com
--wet-runAssim, a decisão sobre ser dry-run ou não fica em um único lugar — no estilo “functional core, imperative shell”
rm --wet-run tempfile.tmptoda vez seria incômodoTalvez fosse melhor deixar a execução real como padrão e, em vez disso, ter uma opção
--undopara desfazer a última ação--wet-run, mas já usei uma abordagem em que o padrão é dry-run e só há mudança ao explicitar--no-dry-runEm serviços, o ideal seria escolher automaticamente um modo seguro conforme o ambiente de execução (dev/prod)
O texto dizia que “adicionou
--dry-runlogo no começo e isso acabou sendo surpreendentemente útil”,mas, na prática, esse tipo de flag muitas vezes é sugerido automaticamente por agentes de codificação com IA (ex.: Claude)
Talvez o motivo de tantas ferramentas CLI hoje terem um padrão parecido seja esse fenômeno de convergência de código baseado em agentes
--dry-rundo Subversion, isso parece uma explicação bem convincenteEu costumo adicionar uma flag
--reallyem utilitários CLI e deixar o padrão como somente leituraÉ uma forma de exigir uma etapa deliberada de confirmação para evitar erros
--i-meant-thatEra um comando para apagar uma máquina remota e, por padrão, ele esperava 10 segundos para dar chance de cancelar
Felizmente, essa flag nunca foi usada de forma errada
Uma das coisas legais do PowerShell é que, se você adicionar uma única linha
[CmdletBinding(SupportsShouldProcess)],já pode usar automaticamente o recurso de dry-run com
-WhatIf. É uma funcionalidade muito conveniente-Confirmtambém é ativado, e com a funçãoShouldProcessdá para interagir com o limiar de confirmação do usuário. É um design realmente eleganteNo CLI interno que eu mantenho, coloco
if not dry_run:dentro da parte que faz as chamadas à API RESTAssim, no lugar da chamada real, eu registro o comando CURL para verificar que requisição seria enviada
Mas, quando a integração entre APIs fica mais complexa, a simulação se torna difícil e muito mais complicada do que um simples
if not dry_run:Eu mantenho muitos CLIs para pipelines de automação, e aplico esse padrão em quase todas as ferramentas
A ideia é que o mais importante é construir primeiro boas ferramentas locais
Se a flag
--dry-runestiver espalhada por todo o código, pode ser uma boa aplicar o padrão de máquina de estados para separar claramente cada etapa