Hi Peff, On Thu, 26 Mar 2020, Jeff King wrote: > On Wed, Mar 25, 2020 at 05:41:19AM +0000, Johannes Schindelin via GitGitGadget wrote: > > > In preparation for fixing that, let's move all of this code into lazy > > prereqs. > > OK. This looks good, even if I cannot help feel that my earlier patch > was perfectly sufficient. ;) The mistake is all mine. I had totally missed that you turned GPG into a lazy prereq. So I had my patch finalized already before you pointed my nose at that fact. Sorry about that. > > Side note: it was quite tempting to use a hack that is possible because > > we do not validate what is passed to `test_lazy_prereq` (and it is > > therefore possible to "break out" of the lazy_prereq subshell: > > > > test_lazy_prereq GPG '...) && GNUPGHOME=... && (...' > > No, it is not tempting at all to me to do something so gross. :) Well, maybe it was not tempting to _you_, but to _me_, it was so tempting that I had implemented and committed it before I made up my mind and changed it again. > > +test_lazy_prereq GPG ' > > + gpg_version=$(gpg --version 2>&1) > > One thing I observed while doing my patch is that lazy_prereq blocks do > not get run through the &&-chain linter. So this is OK, but I wonder if > we should be future-proofing with braces. I don't care _too_ much either > way, though. I actually like that the prereq blocks are exempt from this && chain linting, and would like to refrain from adding braces "just because". > > + test $? != 127 || exit 1 > > I have a slight preference for "return 1" here. The "exit 1" works > because test_lazy_prereq puts us in an implicit subshell. But I think > this sets a bad example for people writing regular tests, where there is > no such subshell (and "return 1" is the only correct way to do it). There are two reasons why I did not use `return` here: - To me, prereq code is very distinct from writing tests. Just like we do not &&-chain all the shell functions that live outside of tests, I don't want to &&-chain all the prereq code. The point of the tests' commands is not to fail. The point of prereq's code is to fail if the prereq is not met. - Since this code is outside of a function, `return` felt like the wrong semantic concept to me. And indeed, I see this (rather scary) part in Bash's documentation of `return` (I did not even bother to look at the POSIX semantics, it scared me so much): The return status is non-zero if `return` is supplied a non-numeric argument, or is used outside a function and not during execution of a script by `.` or `source`. So: the `1` is totally ignored in this context. That alone is reason enough for me to completely avoid it, and use `exit` instead. > > case "$gpg_version" in > > - 'gpg (GnuPG) 1.0.6'*) > > + "gpg (GnuPG) 1.0.6"*) > > say "Your version of gpg (1.0.6) is too buggy for testing" > > + exit 1 > > Ditto here. > > > @@ -25,55 +38,54 @@ then > > # To export ownertrust: > > # gpg --homedir /tmp/gpghome --export-ownertrust \ > > # > lib-gpg/ownertrust > > - mkdir ./gpghome && > > - chmod 0700 ./gpghome && > > - GNUPGHOME="$PWD/gpghome" && > > - export GNUPGHOME && > > + mkdir "$GNUPGHOME" && > > + chmod 0700 "$GNUPGHOME" && > > Compared to mine this keeps the mkdir in the prereq. That seems fine to > me. Other prereqs do depend on the directory existing, but they all > depend on GPG itself, so they'd be fine. Yes. And conceptually, I like that the prereq is responsible for creating that directory. > > +test_lazy_prereq GPGSM ' > > + test_have_prereq GPG && > > In mine I put the test_have_prereq outside the lazy prereq. That makes it essentially a non-lazy prereq. > I don't think it really matters either way (when we later ask if GPGSM > is set, there is no difference between nobody having defined it, and > having a lazy definition that said "no"). The difference is when running a test with `--run=<n>` where `<n>` refers to a test case that requires neither GPG nor GPGSM or RFC1991. My version will not evaluate the GPG prereq, yours still will. Ciao, Dscho