EnigmaCurry / d.rymcg.tech

A collection of self-hosted docker-compose projects with Traefik reverse proxy, integrated auth, and administrative Makefiles for easy maintainance
MIT License
46 stars 9 forks source link

Can't respond "No" to `${BIN}/confirm` #208

Closed mcmikemn closed 1 month ago

mcmikemn commented 1 month ago

There seems to be a problem in funcs.sh where responding "N" to a request to confirm exits the script with an error.

EnigmaCurry commented 1 month ago

Can you show an example? This is actually what confirm is supposed to do. Yes means to exit code 0, No means to exit code 1 (which in a script with set -e set, means the script will abort). Confirm is not expecting a binary answer, it is only expecting a "Yes" answer. If it gets a "No" answer that usually means to abort everything.

Confirm can be used programmatically to check for No responses and not exit, for example, but you have to write an if block with it to handle the non-zero exit code https://github.com/enigmaCurry/script-wizard?tab=readme-ov-file#confirm

mcmikemn commented 1 month ago

When dealing with make switch before any .env files have been made for the Docker context, I could have had the script simply say "there are no instances" and exit, but I thought it would be nice to also ask "do you want to create an instance now?". So I did this.

But before I added the && call="instance" I was struggling to figure out how to make it work since responding "No" returned an error.

I think it's likely that I don't know how to deal with the exit code of 1 (and I don't really know set -e), so this probably isn't a code issue, it's more of a learning issue for me.

EnigmaCurry commented 1 month ago

normally bash scripts run to the end, even if there are errors along the way. That's insane. So I (almost) always put set -e at the top of my scripts to change that default behaviour. Now the script will stop executation at the first error. A confirm is meant to be a last confirmation, are you sure you want to do what this script was intended to do? If it gets error code 1 we know the user wants to stop doing it, and so it quits because of set -e.

EnigmaCurry commented 1 month ago

Consider this example:

confirm yes "This will do the thing" && echo "Doing the thing" || echo "Did NOT do the thing"

$ ./confirm yes "This will do the thing" && echo "Doing the thing"
> This will do the thing. Proceed? Yes
Doing the thing

$ ./confirm yes "This will do the thing" && echo "Doing the thing" || echo "Did NOT do the thing"
> This will do the thing. Proceed? No
Did NOT do the thing

Now in both of these cases there was an if/else statement. Because both cases were handled, the final return code back to the shell is sent back as 0. (Because that's the the exit code of either echo command, which neither can fail)

As long as the final return code is 0 (even though confirm did return a 1, it was "handled"), then the set -e rule does not trigger and the script continues on.

Its only when you have a naked unhandled exit code 1 that will abort the script:

# This aborts the script:
set -e; ./confirm no "do the thing"
mcmikemn commented 1 month ago

Thanks for that explanation!