Live data from Hacker News

In praise of –dry-run

henrikwarne.com

81–90 of 175 posts

Re: In praise of –dry-run

#82
post #78

Earlier quoted context omitted.

Yes, but it depends on the context. For little scripts, I'm not writing unit tests- running it is the test. But I want to be able to iterate without side effects, so it's important that the dry mode be as representative as possible for what'll happen when something is run for real.

You understand how subjective that is right? Someone might expect that the database doesn't do the last commit step while other people is perfectly happy that the database engine checks that it has enough writing permissions and is running as a user that can start the process without problems.

Sure, where you draw the line will vary between projects. As long as its exact placement doesn't matter too much.

For me personally, I tend to draw the line at write operations. So in your example, I'd want a dry run to verify the permissions that it can (if I expect those to be a problem). But if that can't easily be done without a write, then maybe it's not worth it. There are also situations where you want a dry run to be really fast, so you forego some checks (allowing for more surprises later). Really just depends.

Re: In praise of –dry-run

#84
If you're interacting with stateful systems (which you usually are with this kind of command), --dry-run can still have a race condition.

The tool tells you what it would do in the current situation, you take a look and confirm that that's alright. Then you run it again without --dry-run, in a potentially different situation.

That's why I prefer Terraform's approach of having a "plan" mode. It doesn't just tell you what it would do but does so in the form of a plan it can later execute programmatically. Then, if any of the assumptions made during planning have changed, it can abort and roll back.

As a nice bonus, this pattern gives a good answer to the problem of having "if dry_run:" sprinkled everywhere: You have to separate the planning and execution in code anyway, so you can make the "just apply immediately" mode simply execute(plan()).

Re: In praise of –dry-run

#85
post #77
post #73

I like this pattern a lot, but it's important that the code in the dry path is representative. I've been bitten a few too many times by dry code that just runs `print("would have updated ID: 123")`, but not actually running most of the code in the hot path. Then when I run it for real, some of the prep for the write operation has a bug / error, so my dry run didn't actually reveal much to me. Put another way: your dr…

Doesn’t this conflate dry-running with integration testing? ASAIK the purpose of a dry-run is to understand what will happen, not to test what will happen. For the latter we have testing.

I'd argue the dry run is a form of integration testing: Essentially the writes are mocked, but the reads are still functional.

Re: In praise of –dry-run

#86
post #84

If you're interacting with stateful systems (which you usually are with this kind of command), --dry-run can still have a race condition. The tool tells you what it would do in the current situation, you take a look and confirm that that's alright. Then you run it again without --dry-run, in a potentially different situation. That's why I prefer Terraform's approach of having a "plan" mode. It doesn't just tell you w…

I like that idea! For an application like Terraform, Ansible or the like, it seems ideal.

For something like in the article, I’m pretty sure a plan mode is overkill though.

Planning mode must involve making a domain specific language or data structure of some sort, which the execution mode will interpret and execute. I’m sure it would add a lot of complexity to a reporting tool where data is only collected once per day.

Re: In praise of –dry-run

#88
post #6

In order to make it work without polluting the code-base I find that I have to move the persistence into injectable strategy, which makes it good anyway. If you keep passing in `if dry_run:` everywhere you're screwed. Also, if I'm being honest, it's much better to use `--wet-run` for the production run than to ask people to run `--dry-run` for the test run. Less likely to accidentally fire off the real stuff.

I don't want to have to type rm --wet-run tempfile.tmp every time, or mkdir -p --yes-really-do-it /usr/local/bin The program should default to actually doing whatever thing you're asking it to do. On the other hand it would be great if every tool had an --undo argument that would undo the last thing that program did.

No rule is ironclad. I think matching risk to functionality is usually a good idea. For example, most modern Linuxen carry `rm` protected against root removal with `--no-preserve-root`. That is indeed `rm --wet-run` by a different name in the dangerous case.

Re: In praise of –dry-run

#89
post #86
post #84

If you're interacting with stateful systems (which you usually are with this kind of command), --dry-run can still have a race condition. The tool tells you what it would do in the current situation, you take a look and confirm that that's alright. Then you run it again without --dry-run, in a potentially different situation. That's why I prefer Terraform's approach of having a "plan" mode. It doesn't just tell you w…

I like that idea! For an application like Terraform, Ansible or the like, it seems ideal. For something like in the article, I’m pretty sure a plan mode is overkill though. Planning mode must involve making a domain specific language or data structure of some sort, which the execution mode will interpret and execute. I’m sure it would add a lot of complexity to a reporting tool where data is only collected once per d…

No need to overthink it. In any semi-modern language you can (de)serialize anything to and from JSON, so it's really not that hard. The only thing you need to do is have a representation for the plan in your program. Which I will argue is probably the least error-prone way to implement --dry-run anyway (as opposed to sprinkling branches everywhere).

Re: In praise of –dry-run

#90
post #32

Earlier quoted context omitted.

I've done that, but I hate the term "wet run." I use "live run" now, which I think gets the point across without being sort of uncomfortable.

--with-danger --make-it-so --do-the-thing --go-nuts --safety-off So many fun options.

I find it important to include system information in here as well, so just copy-pasting an invocation from system A to system B does not run.

For example, our database restore script has a parameter `--yes-delete-all-data-in` and it needs to be parametrized with the PostgreSQL cluster name. So a command with `--yes-delete-all-data-in=pg-accounting` works on exactly one system and not on other systems.

Post reply on HN