In praise of –dry-run
Default behavior: dry vs. “really do it”
- Many prefer tools to default to safe/no-op and require an explicit
--commit/--execute/--reallyflag to make changes, especially for high‑impact scripts (DB, APIs, mass updates). - Others argue most everyday commands (e.g.,
rm,cp) should default to doing the thing, with safety handled by filesystem snapshots or selective safeguards (--no-preserve-root, interactive prompts only in dangerous cases). - Several people bias their own custom tools to default to dry‑run, adding flags like
--no-dry-run,--live-run, or humorous variants (--safety-off,--make-it-so).
Implementation patterns and code structure
- A common concern is avoiding
if dry_run:checks scattered everywhere. Proposed solutions:- Inject “persistence strategies” or use builders so writes can be swapped for logging.
- “Functional core, imperative shell”: core produces a list of actions; a single executor either logs or performs them.
- Use database transactions: run everything normally but roll back on dry‑run.
- Some tooling wraps REST calls or writes in a single layer so dry‑run affects only that layer.
Safety UX: confirmations and friction
- Techniques include countdown timers, requiring typing a random code or phrase, or using parameters like
--yes-delete-all-data-in=...to bind intent to a specific system. - Tools such as molly‑guard or tarsnap’s “type this phrase to continue” are cited as real‑world examples.
- Several commenters note that repeated confirmations get automated away by users; true safety often requires easy undo (snapshots, versioned filesystems) rather than only extra prompts.
Limitations and nuances of dry‑run
- A dry‑run can diverge from reality if it doesn’t exercise all hot‑path logic; it should do everything except the final side effects.
- Race conditions: state can change between dry‑run and real run. Terraform‑style “plan then apply” with a persisted plan is praised as a stronger pattern, though some argue this can devolve into designing a mini DSL/VM.
Ecosystem and tooling
- Examples: PowerShell’s built‑in
-WhatIf/-Confirm, internal migration frameworks, CI jobs parameterized withDRY_RUN, andpreview/no‑clobberflags. - Some mention roll‑your‑own approaches (aliases,
diff-based previews, OverlayFS/Docker) when tools lack dry‑run.
Agents and convergence
- Multiple people observe that code‑generation tools and LLMs now routinely add
--dry-runoptions by default, potentially standardizing CLI patterns across projects.