Thread (93 messages) 93 messages, 10 authors, 2018-08-29

Re: [PATCH v2 01/10] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

From: Eric Sunshine <hidden>
Date: 2018-07-30 21:38:21

On Mon, Jul 30, 2018 at 4:59 PM Jonathan Nieder [off-list ref] wrote:
Eric Sunshine wrote:
quoted
The subshell linter would normally fold out the here-doc content, but
'sed' isn't a proper programming language, so the linter can't
recognize arbitrary here-doc tags. Instead it has hard-coded knowledge
of the tags commonly used in the Git tests, specifically EOF, EOT, and
INPUT_END.
Oh, hmm.  I also see some others (outside subshells, though):

        EXPECT_END
        [...]
Correct. The linter does fold-out top-level EOF here-docs to hedge
against the body of a here-doc containing something that might look
like the start of a subshell (which would activate the more
strict/expensive &&-chain validation). It special-cases top-level EOF
because it's such a common tag name, thus an easy way to avoid
false-positives, in general. I didn't bother trying to recognize
_every_ possible tag since those other here-docs don't trigger any
problems. (It's heuristic-based, after all.)
I wonder if it should look for something like [A-Z][A-Z_]* to catch
all of these.
I considered that, but it doesn't handle nested here-docs, which we
actually have in the test suite. For instance, from t9300-fast-import:

    cat >input <<-INPUT_END &&
    mark :2
    data <<EOF
    $file2_data
    EOF
    ...
    INPUT_END

Nesting could be handled easily enough either by stashing away the
opening tag and matching against it later _or_ by doing recursive
here-doc folding, however, 'sed' isn't a proper programming language
and can't be coerced into doing either of those. (And, it was tricky
enough just getting it to handle the nested case with a limited set of
recognized tag names, without having to explicitly handle every
combination of those names nested inside one another.)
quoted
The linter also deals with multi-line $(...) expressions, however, it
currently only recognizes them when the $( is on its own line.
That's reasonable, especially if "on its own line" means "at end of
line".
It does; sorry for not being clear.
What would help most is if the error message could explain what is
going on, but I understand that that can be hard to do in a sed
script.
Right, unfortunately, it can't be too helpful, but, when fixing all
those broken chains, I did find it useful to dump the result after
'sed' processing in order to identify what it was actually complaining
about. I did so by changing the $1 in this line from test-lib.sh:

error "bug in the test script: broken &&-chain or run-away HERE-DOC: $1"

to print the 'sed' output instead. The linter prepends "??AMP??" and
"??SEMI??" to suspect lines. It also prepends lines with ">" to
indicate where it thinks a subshell ends. This information was quite
helpful when figuring out what was broken in the test (or, for false
positives, where a heuristic had gone wrong).

I considered enabling this output by default instead of $1 but decided
against it since it is only helpful for broken &&-chains in subshells,
thus doesn't aid in the more common case of top-level &&-breakage,
thus might be confusing.
quoted
I could try to update the linter to not trip over this sort of input,
however, this test code is indeed ugly and difficult to understand,
and your rewrite[1] of it makes it far easier to grok, so I'm not sure
the effort would be worthwhile. What do you think?
I'd be happy to look over a change that handles more here-doc
delimiters or produces a clearer message for tests in poor style, but
I agree with you that it's not too important.
I am, for a couple reasons, somewhat hesitant to tweak the heuristic.

First, each tweak has the potential of causing more false-positives or
(perhaps worse) false-negatives. The linter's own test-suite is
supposed to protect against that, but test suite coverage is never
perfect.

Second, ideally, the linter should protect against new broken
&&-chains from entering the codebase, so poorly coded historic tests
such as these aren't necessarily good motivation for tweaking, _and_
it is (hopefully) unlikely that we would allow this sort of ugly shell
code to enter the codebase going forward. (The counterargument is that
this false-positive doesn't help someone coding up a new test who
hasn't yet submitted the patch to the mailing list where more seasoned
eyes would suggest better coding style.)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help