I've done that and called the counter option --for-real, but I'd like both args so runbooks can spell out:
1. do-step-one --dry-run
2. (do validation)
3. do-step-one --real-run
4. (do validation)
Many commandline parsing libraries assume you're doing booleans, and I think --dry-run and --no-dry-run is confusing. And, internally, you have a boolean flag so there's always the possibility of some code getting it backwards.
Internally, I'd like an enum flag that's clearly dry_run or real_run, so the guards are using positive logic:
switch(run) {
case dry_run:
print("Would do this...");
case real_run:
do_real_thing();
}
I think the point here, though, is that the user needs to be explicit on the command line: they have to specify one of `--wet` or `--dry`; specifying neither is an error. It's not clear from your code if you do that, or if you interpret `--dry-run` as `DryRunMode.Dry` and the absence of an option as `DryRunMode.Wet`.
While I kinda like this idea in principle, I haven't really seen any CLI apps that require an explicit option for both modes, so it might be a bit of unexpected UX for people.
I noticed that after I posted and had read a bit more; but you're also using F# which has proper ADTs. I'm typically writing support scripts in Python or the like, and even very good libraries like click[1] nevertheless reflect the idioms popular in the language.
I really came back to this post because I was struggling with Gradle and if there is a more perfect illustration of how a dry run mode could help than that, I don't know what it could be. Gradle builds are a fucking mystery, every time, and there's no excuse for it.
Internally, I'd like an enum flag that's clearly dry_run or real_run, so the guards are using positive logic: