À propos des avantages de l’option `dry-run`
(henrikwarne.com)- Exemple de l’ajout d’une option
--dry-runlors du développement d’une application de génération de rapports afin de pouvoir simuler le résultat de l’exécution - Cette option affiche quelles opérations seraient effectuées sans appliquer de modifications réelles, ce qui permet des tests sûrs et un retour rapide
- Le développeur peut ainsi vérifier immédiatement la configuration, l’accessibilité et l’état du système, et l’utiliser comme outil de vérification au quotidien
- Comme inconvénient, une légère augmentation de la complexité est mentionnée, car il faut vérifier le flag
dryRundans le code - Dans les applications impératives, la fonctionnalité
--dry-runest très utile, et plus elle est introduite tôt dans le projet, plus l’efficacité du développement augmente
Contexte
- La nouvelle application de génération de rapports en cours de développement génère chaque jour ouvré des rapports, les compresse, les envoie vers un serveur sftp, vérifie les réponses d’erreur et envoie des e-mails de notification
- Les fichiers générés et les fichiers de retour produits à chaque étape sont déplacés vers des répertoires différents selon l’étape
- Au début du développement, en repensant à Subversion et à l’option
--dry-runde plusieurs commandes Linux, la même fonctionnalité a été ajoutée- Cette option affiche ce qui se passerait à l’exécution sans effectuer de changement réel
- Lors d’une exécution avec
--dry-run, les rapports qui seraient générés et ceux qui seraient exclus, les fichiers qui seraient compressés et déplacés, ainsi que les fichiers concernés par l’upload et le téléchargement sftp sont affichés étape par étape
Utilisation et avantages
- Une fonctionnalité suffisamment utile pour être utilisée tous les jours pendant le développement et les tests
- Utilisée pour vérifier l’état avant exécution, elle permet de contrôler immédiatement la configuration, l’accessibilité et l’état du système
- Comme aucun changement réel n’est effectué, elle peut être exécutée en toute sécurité
- En modifiant la date du fichier d’état d’un rapport, il est possible de vérifier immédiatement si ce rapport sera généré
- La génération réelle du rapport prend du temps, mais le dry-run fournit un retour rapide
- Même lors des tests de l’ensemble du système, il offre une boucle de validation rapide
Inconvénients
- Il faut vérifier de façon répétée le flag
dryRundans le code, ce qui entraîne une légère pollution du code- À chaque étape principale, le flag est contrôlé pour n’afficher que des logs au lieu d’exécuter réellement l’action
- Cependant, cette vérification n’est pas profonde et aucun traitement particulier n’est nécessaire à l’intérieur de la logique de génération de rapports
- La vérification n’est faite qu’au niveau supérieur, là où l’exécution effective est décidée
Conclusion
- Les applications exécutées de manière impérative et qui produisent un résultat se prêtent bien à une option
--dry-run- En revanche, elle ne convient pas aux applications réactives qui attendent des messages
- Le fait de l’avoir ajoutée dès le début du projet a été d’une grande aide pour améliorer l’efficacité du développement
- Ce n’est pas une fonctionnalité nécessaire dans tous les cas, mais elle est considérée comme un outil très utile lorsqu’elle est appropriée
1 commentaires
Avis Hacker News
Lorsqu’on interagit avec des systèmes à état, il peut aussi y avoir des conditions de concurrence (race conditions) avec
--dry-runL’outil montre « ce qu’il va faire » à l’instant T, mais au moment de l’exécution réelle, la situation peut avoir changé
C’est pourquoi je préfère l’approche du mode "plan" de Terraform. Ce mode prépare un plan exécutable, puis peut s’interrompre ou revenir en arrière si les hypothèses faites au moment du plan ont changé
Cela évite aussi de parsemer le code de
if dry_run:et permet de simplifier en séparant planification et exécution sous une formeexecute(plan())Un problème de timing entre DNS Planner et Enactor a conduit un ancien plan à écraser le plus récent
Le sujet avait aussi été abordé dans un précédent fil HN
Car créer un mode plan suppose un langage dédié au domaine ou des structures de données adaptées
(1) capturer l’état du système de fichiers et enregistrer un plan → (2) vérifier que l’état n’a pas changé, puis exécuter et journaliser → (3) comparer à l’état précédent pour valider l’absence de perte de données
J’utilise ces trois étapes comme scripts séparés ou via des flags distincts
rmQuand un outil n’a pas de
--dry-run, il m’arrive d’en bricoler un moi-mêmePar exemple, avant d’exécuter une commande
sedcomplexe, j’utilisediffpour comparer à l’avance les modificationsOn peut voir les différences avec quelque chose comme
diff -u <(echo "hello") <(echo "hello" | sed "s/hello/hi/g")J’ai résumé tout ça dans mon blog
J’aime le pattern
--dry-run, mais le code du chemin dry-run doit se comporter comme le chemin réelSi on se contente d’afficher « ce qui va se passer » en sautant la vraie logique, on risque de laisser passer des bugs au moment de l’exécution réelle
Il faut que le déroulement soit identique jusqu’au point juste avant les écritures en base de données ou les appels d’API
Un dry-run sert à montrer « ce qui se passerait », tandis que les vrais tests relèvent d’un autre domaine
À l’inverse, je préfère avoir un flag
--commitou--execute, et faire de l’exécution par défaut un mode lecture seule (dry)Cela réduit le risque de provoquer de vraies modifications par erreur
--commitest explicitement indiquéEn revanche, j’ai souvent vu des incidents causés par l’oubli de
--dry-runPar défaut, il ne fait que comparer, et il faut
--executepour réellement remplacer par des hard linksCe type de confirmation est efficace pour réduire les erreurs
--wet-run. Selon le contexte, un flag au sens inverse peut parfois être plus intuitifDELETE-ACCOUNTJusqu’à présent, je n’ai jamais supprimé un compte par erreur une seule fois
Pour éviter de polluer le code, il faut séparer la persistance comme une stratégie injectable
Mettre des
if dry_run:partout n’est pas une bonne idéeIl est même plus sûr de rendre l’exécution de production explicite avec
--wet-runAinsi, la décision dry-run ou non ne se prend qu’en un seul endroit — dans un style « functional core, imperative shell »
rm --wet-run tempfile.tmpest pénibleJe préférerais que l’exécution réelle reste le comportement par défaut, avec à la place une option
--undopour annuler la dernière action--wet-run, mais j’ai déjà utilisé une approche où le mode par défaut estdry-runet où il faut préciser--no-dry-runpour permettre les modificationsPour un service, l’idéal serait de sélectionner automatiquement le mode de sécurité selon l’environnement d’exécution (dev/prod)
L’article disait : « j’ai ajouté
--dry-runau début et cela s’est révélé étonnamment utile », maisen réalité, ce type de flag est souvent proposé automatiquement par des agents de code IA (par ex. Claude)
Si beaucoup d’outils CLI présentent aujourd’hui des patterns similaires, cela vient peut-être de cette convergence du code pilotée par les agents
--dry-runde Subversion, cela reste une explication tout à fait convaincanteDans mes utilitaires CLI, j’ajoute souvent un flag
--reallyafin que le comportement par défaut reste en lecture seuleL’idée est d’exiger une confirmation délibérée pour éviter les erreurs
--i-meant-thatC’était une commande de suppression de machine distante, et par défaut elle attendait 10 secondes pour laisser le temps d’annuler
Heureusement, ce flag n’a jamais été utilisé à tort
L’un des aspects sympas de PowerShell, c’est qu’en ajoutant simplement
[CmdletBinding(SupportsShouldProcess)],on obtient automatiquement la fonctionnalité de dry-run
-WhatIf. C’est une fonction très pratique-Confirm, et permet d’interagir avec le seuil de confirmation de l’utilisateur via la fonctionShouldProcess. C’est vraiment une belle conceptionDans la CLI interne dont je m’occupe, je place
if not dry_run:dans la partie qui appelle l’API RESTAinsi, au lieu de faire l’appel réel, on conserve un log de commande CURL pour voir quelles requêtes seraient envoyées
Mais quand les interactions entre API deviennent complexes, la simulation devient difficile et bien plus compliquée qu’un simple
if not dry_run:Je maintiens moi aussi beaucoup de CLI pour des pipelines d’automatisation, et j’applique ce pattern à presque tous mes outils
Selon eux, il vaut mieux d’abord bien concevoir les outils locaux
Si le flag
--dry-runest dispersé dans tout le code, il vaut mieux appliquer le pattern de machine à états pour séparer clairement chaque étape