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

2018-08-23 Thread Eric Sunshine
On Thu, Aug 23, 2018 at 2:02 PM Ævar Arnfjörð Bjarmason
 wrote:
> Found in some 2.19 testing on AIX:

Thanks for reporting these issues.

> > + /^[ ]*EOF[  ]*$/!bhereslurp
>
> AIX sed doesn't like this, and will yell:
> :hereslurp is greater than eight characters
> This on top fixes it:

Fix make sense, and checking POSIX[1] , I see that it says that
behavior is unspecified for labels longer than 8 bytes.

[1]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html

> > +# bare "(" line?
> > +/^[  ]*([]*$/ {
> > + # stash for later printing
>
> AIX sed doesn't like this either, and prints:
> sed:# stash for later printing is not a recognized function.
> I have no idea what the fix is for that one.

That's the only indented comment in the entire script, so it's almost
certainly that. How about we move the indented comment up to the
comment for the enclosing block, so it reads:

# bare "(" line? -- stash for later printing
/^[  ]*([]*$/ {
h
bnextline
}

I could prepare such a patch, although perhaps it would be better for
you to do so since you are in a position to test it (and because you
discovered the problems)?


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

2018-08-23 Thread Ævar Arnfjörð Bjarmason


On Wed, Jul 11 2018, Eric Sunshine wrote:

Found in some 2.19 testing on AIX:

> +# here-doc -- swallow it to avoid false hits within its body (but keep the
> +# command to which it was attached)
> +/<<[ ]*[-\\]*EOF[]*/ {
> + s/[ ]*<<[   ]*[-\\]*EOF//
> + h
> + :hereslurp
> + N
> + s/.*\n//
> + /^[ ]*EOF[  ]*$/!bhereslurp
> + x
> +}

AIX sed doesn't like this, and will yell:

:hereslurp is greater than eight characters

This on top fixes it:

diff --git a/t/chainlint.sed b/t/chainlint.sed
index 8544df38df..2333705b27 100644
--- a/t/chainlint.sed
+++ b/t/chainlint.sed
@@ -100 +100 @@
-   :hereslurp
+   :hered
@@ -104 +104 @@
-   bhereslurp
+   bhered
@@ -286 +286 @@ s/[ ]*< +:subshell
> +# bare "(" line?
> +/^[  ]*([]*$/ {
> + # stash for later printing
> + h
> + bnextline
> +}
> +# "(..." line -- split off and stash "(", then process "..." as its own line

AIX sed doesn't like this either, and prints:

sed:# stash for later printing is not a recognized function.

I have no idea what the fix is for that one.


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

2018-07-31 Thread Jeff King
On Tue, Jul 31, 2018 at 02:55:51PM -0400, Eric Sunshine wrote:

> > I hesitate to make any suggestion here, as I think we may have passed
> > a point of useful cost/benefit in sinking more time into this script.
> > But...is switching to awk or perl an option? Our test suite already
> > depends on having a vanilla perl, so I don't think it would be a new
> > dependency. And it would give you actual data structures.
> 
> It would, and I did consider it, however, I was very concerned about
> startup cost (launch time) with heavyweight perl considering that it
> would have to be run for _every_ test. With 13000+ tests, that cost
> was a very real concern, especially for Windows users, but even for
> MacOS users (such as myself, for which the full test suite already
> takes probably close to 30 minutes to run, even on a ram drive). So, I
> wanted something very lightweight (and deliberately used that word in
> the commit message), and 'sed' seemed the lightest-weight of the
> bunch.

Both perl and sed seem about the same on my system (sometimes one is
faster than the other, and sometimes vice versa). However, I expect for
Windows the problem is not how big the child executable is, but running
a child process at all. I might be wrong, though.

> 'awk' might be about as lightweight as 'sed', and it may even be
> possible to coerce it into handling the task (since the linter's job
> is primarily just a bunch of regex matching with very little
> "manipulating"). v1 of the linter was somewhat simpler and didn't deal
> with these more complex cases, such as nested here-docs. v1 also did
> rather more "manipulating" of the script since the result was meant to
> be run by the shell. When it came time to implement v2, which detects
> broken &&-chains itself by textual inspection, most of the
> functionality (coming from v1) was already implemented in 'sed', so
> 'awk' never really came up as a candidate since rewriting the script
> from scratch in 'awk' didn't seem like a good idea. (And, at the time
> v2 was started, I didn't know that these more complex cases would
> arise.) So, 'awk' might be a viable alternative, and perhaps I'll take
> a stab at it for fun at some point (or not), but I don't think there's
> a pressing need right now.

Yeah, I agree with that.

-Peff


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

2018-07-31 Thread Eric Sunshine
On Tue, Jul 31, 2018 at 8:50 AM Jeff King  wrote:
> On Mon, Jul 30, 2018 at 05:38:06PM -0400, Eric Sunshine wrote:
> > 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:
> > [...]
> > 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.)
>
> I hesitate to make any suggestion here, as I think we may have passed
> a point of useful cost/benefit in sinking more time into this script.
> But...is switching to awk or perl an option? Our test suite already
> depends on having a vanilla perl, so I don't think it would be a new
> dependency. And it would give you actual data structures.

It would, and I did consider it, however, I was very concerned about
startup cost (launch time) with heavyweight perl considering that it
would have to be run for _every_ test. With 13000+ tests, that cost
was a very real concern, especially for Windows users, but even for
MacOS users (such as myself, for which the full test suite already
takes probably close to 30 minutes to run, even on a ram drive). So, I
wanted something very lightweight (and deliberately used that word in
the commit message), and 'sed' seemed the lightest-weight of the
bunch.

'awk' might be about as lightweight as 'sed', and it may even be
possible to coerce it into handling the task (since the linter's job
is primarily just a bunch of regex matching with very little
"manipulating"). v1 of the linter was somewhat simpler and didn't deal
with these more complex cases, such as nested here-docs. v1 also did
rather more "manipulating" of the script since the result was meant to
be run by the shell. When it came time to implement v2, which detects
broken &&-chains itself by textual inspection, most of the
functionality (coming from v1) was already implemented in 'sed', so
'awk' never really came up as a candidate since rewriting the script
from scratch in 'awk' didn't seem like a good idea. (And, at the time
v2 was started, I didn't know that these more complex cases would
arise.) So, 'awk' might be a viable alternative, and perhaps I'll take
a stab at it for fun at some point (or not), but I don't think there's
a pressing need right now.


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

2018-07-31 Thread Jeff King
On Mon, Jul 30, 2018 at 05:38:06PM -0400, Eric Sunshine wrote:

> > 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 < $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.)

I hesitate to make any suggestion here, as I think we may have passed
a point of useful cost/benefit in sinking more time into this script.
But...is switching to awk or perl an option? Our test suite already
depends on having a vanilla perl, so I don't think it would be a new
dependency. And it would give you actual data structures.

But like I said, it may not be worth it. I'd be OK just adjusting the
false positive and moving on.

> 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.)

Right, I think the real cost is somebody who adds "<

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

2018-07-30 Thread Eric Sunshine
On Mon, Jul 30, 2018 at 4:59 PM Jonathan Nieder  wrote:
> Eric Sunshine wrote:
> > 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 < > 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.

> > 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.)


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

2018-07-30 Thread Jonathan Nieder
Eric Sunshine wrote:
> On Mon, Jul 30, 2018 at 2:14 PM Jonathan Nieder  wrote:

>> (
>> chks_sub=$(cat <> $chks
>> TXT
>> ) &&
>>
>> Ugly quoting, useless use of "cat", etc, aside, I don't think it's
>> missing any &&.  Hints?
>
> Yes, it's a false positive.
>
> 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
FRONTEND_END
END_PART1
SETUP_END
EOF2
EXPECTED
END_OF_LOG
INPUT_END
END_EXPECT

I wonder if it should look for something like [A-Z][A-Z_]* to catch
all of these.

> 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".

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.

[...]
> 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.

Thanks for looking it over.

Sincerely,
Jonathan

> [1]: 
> https://public-inbox.org/git/20180730190738.gd156...@aiede.svl.corp.google.com/


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

2018-07-30 Thread Eric Sunshine
On Mon, Jul 30, 2018 at 2:14 PM Jonathan Nieder  wrote:
> Eric Sunshine wrote:
> > Address this shortcoming by feeding the body of the test to a
> > lightweight "linter" which can peer inside subshells and identify broken
> > &&-chains by pure textual inspection.
>
> This is causing contrib/subtree tests to fail for me: running "make -C
> contrib/subtree test" produces

Thanks, I forgot that some of 'contrib' had bundled tests. (In fact, I
just checked the other 'contrib' tests and found that a MediaWiki test
has a broken top-level &&-chain.)

> The problematic test code looks like this:
>
> (
> chks_sub=$(cat < $chks
> TXT
> ) &&
>
> Ugly quoting, useless use of "cat", etc, aside, I don't think it's
> missing any &&.  Hints?

Yes, it's a false positive.

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.

The linter also deals with multi-line $(...) expressions, however, it
currently only recognizes them when the $( is on its own line.

Had this test used one of the common here-doc tags _or_ had it
formatted the $(...) as described, then it wouldn't have misfired.

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?

[1]: 
https://public-inbox.org/git/20180730190738.gd156...@aiede.svl.corp.google.com/


[PATCH 0/2] subtree: fix &&-chain and simplify tests (Re: [PATCH v2 01/10] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells)

2018-07-30 Thread Jonathan Nieder
(resetting cc list)
Jonathan Nieder wrote:

> This is causing contrib/subtree tests to fail for me: running "make -C
> contrib/subtree test" produces
[...]
>   error: bug in the test script: broken &&-chain or run-away HERE-DOC:
[...]
> Ugly quoting, useless use of "cat", etc, aside, I don't think it's
> missing any &&.  Hints?

Turns out it was missing a && too. :)

These patches are against "master".  Ideally this would have come
before es/chain-lint-in-subshell.  Since this is contrib/, I'm okay
with losing bisectability and having it come after, though.

Thoughts of all kinds welcome.

Jonathan Nieder (2):
  subtree: add missing && to &&-chain
  subtree: simplify preparation of expected results

 contrib/subtree/t/t7900-subtree.sh | 121 -
 1 file changed, 31 insertions(+), 90 deletions(-)


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

2018-07-30 Thread Jonathan Nieder
Hi,

Eric Sunshine wrote:

> The --chain-lint option detects broken &&-chains by forcing the test to
> exit early (as the very first step) with a sentinel value. If that
> sentinel is the test's overall exit code, then the &&-chain is intact;
> if not, then the chain is broken. Unfortunately, this detection does not
> extend to &&-chains within subshells even when the subshell itself is
> properly linked into the outer &&-chain.
>
> Address this shortcoming by feeding the body of the test to a
> lightweight "linter" which can peer inside subshells and identify broken
> &&-chains by pure textual inspection.

Interesting.

>Although the linter does not
> actually parse shell scripts, it has enough knowledge of shell syntax to
> reliably deal with formatting style variations (as evolved over the
> years) and to avoid being fooled by non-shell content (such as inside
> here-docs and multi-line strings).

This is causing contrib/subtree tests to fail for me: running "make -C
contrib/subtree test" produces

[...]
*** t7900-subtree.sh ***
ok 1 - no merge from non-existent subtree
ok 2 - no pull from non-existent subtree
ok 3 - add subproj as subtree into sub dir/ with --prefix
ok 4 - add subproj as subtree into sub dir/ with --prefix and --message
ok 5 - add subproj as subtree into sub dir/ with --prefix as -P and 
--message as -m
ok 6 - add subproj as subtree into sub dir/ with --squash and --prefix 
and --message
ok 7 - merge new subproj history into sub dir/ with --prefix
ok 8 - merge new subproj history into sub dir/ with --prefix and 
--message
ok 9 - merge new subproj history into sub dir/ with --squash and 
--prefix and --message
ok 10 - merge the added subproj again, should do nothing
ok 11 - merge new subproj history into subdir/ with a slash appended to 
the argument of --prefix
ok 12 - split requires option --prefix
ok 13 - split requires path given by option --prefix must exist
ok 14 - split sub dir/ with --rejoin
ok 15 - split sub dir/ with --rejoin from scratch
ok 16 - split sub dir/ with --rejoin and --message
ok 17 - split "sub dir"/ with --branch
ok 18 - check hash of split
ok 19 - split "sub dir"/ with --branch for an existing branch
ok 20 - split "sub dir"/ with --branch for an incompatible branch
error: bug in the test script: broken &&-chain or run-away HERE-DOC: 
subtree_test_create_repo "$subtree_test_count" &&
[...]
)

Makefile:44: recipe for target 't7900-subtree.sh' failed

The problematic test code looks like this:

(
cd "$subtree_test_count/sub proj" &&
git fetch .. subproj-br &&
git merge FETCH_HEAD &&

chks="sub1
sub2
sub3
sub4" &&
chks_sub=$(cat <

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

2018-07-12 Thread Junio C Hamano
Eric Sunshine  writes:

> However, existing tests aside, the more important goal is detecting
> problems in new or updated tests hiding genuine bugs in changes to Git
> itself, so it may have some value.

Yes, indeed.


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

2018-07-12 Thread Eric Sunshine
On Thu, Jul 12, 2018 at 12:56 PM Jeff King  wrote:
> Like Junio, I'm a little nervous that this is going to end up being a
> maintenance burden. People may hit false positives and then be
> confronted with this horrible mass of sed to try to figure out what went
> wrong [...]

A very valid concern.

> But I came around to thinking:
>   - this found and fixed real problems in the test suite, with minimal
> false positives across the existing code

The counterargument (and arguing against my own case) is that, while
it found 3 or 4 genuine test bugs hidden by &&-breakage, they were
just that: bugs in the tests; they weren't hiding any bugs in Git
itself, which is pretty measly return for the effort invested in the
linter.

However, existing tests aside, the more important goal is detecting
problems in new or updated tests hiding genuine bugs in changes to Git
itself, so it may have some value.

>   - worst case is that relief is only a "git revert" away

Right. It's just a developer aid, not a user-facing feature which has
to be maintained in perpetuity, so retiring it is easy.


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

2018-07-12 Thread Jeff King
On Thu, Jul 12, 2018 at 06:50:20AM -0400, Eric Sunshine wrote:

> And, perhaps most important: We're not tied indefinitely to the
> "subset" implemented by the current linter. If it is indeed found to
> be too strict or limiting, it can always be loosened or retired
> altogether.

Yeah, I agree this is the key point.

Like Junio, I'm a little nervous that this is going to end up being a
maintenance burden. People may hit false positives and then be
confronted with this horrible mass of sed to try to figure out what went
wrong (which isn't to bust on your sed in particular; I think you made a
heroic effort in commenting).

But I came around to thinking:

  - this found and fixed real problems in the test suite, with minimal
false positives across the existing code

  - it's being done by a long-time contributor, not somebody who is
going to dump sed on us and leave

  - worst case is that relief is only a "git revert" away

So I'm OK with merging it, and even running it by default.

-Peff


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

2018-07-12 Thread Eric Sunshine
On Wed, Jul 11, 2018 at 5:37 PM Junio C Hamano  wrote:
> As with the previous "transform the script and feed the result to
> shell" approach, this risks to force us into writing our tests in a
> subset of valid shell language, which is the primary reason why I
> was not enthused when I saw the previous round.  The worst part of
> it is that the subset is not strictly defined based on the shell
> language syntax or features (e.g. we allow this and that feature but
> not that other feature) but "whatever that does not cause the linter
> script to trigger false positives".

Some observations perhaps worth considering:

The linter is happy (no false positives) with the 13000+ existing
tests (though, of course, not all of them use subshells). Those tests,
written over many years, vary quite wildly in style and implementation
approach, so the "subset" of shell language accepted by the linter is
quite broad.

The original --chain-lint series (jk/test-chain-lint) had to make some
changes, such as wrapping code in a {...} block[1], merely to pacify
the linter. v2 of the subshell linter required no such changes.

The subshell linter was crafted to be on par with the existing
--chain-lint in terms of strictness (and looseness), so the subshell
linter is not more strict than the existing implementation. (For
instance, one can escape the strict &&-chain requirement in the
existing --chain-lint by wrapping code in a {...} block. The subshell
linter intentionally allows that escape, as well.)

And, perhaps most important: We're not tied indefinitely to the
"subset" implemented by the current linter. If it is indeed found to
be too strict or limiting, it can always be loosened or retired
altogether.

Thanks for the feedback.

[1]: bfe998fc9b (t0050: appease --chain-lint, 2015-03-20)


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

2018-07-11 Thread Junio C Hamano
Eric Sunshine  writes:

> The --chain-lint option detects broken &&-chains by forcing the test to
> exit early (as the very first step) with a sentinel value. If that
> sentinel is the test's overall exit code, then the &&-chain is intact;
> if not, then the chain is broken. Unfortunately, this detection does not
> extend to &&-chains within subshells even when the subshell itself is
> properly linked into the outer &&-chain.
>
> Address this shortcoming by feeding the body of the test to a
> lightweight "linter" which can peer inside subshells and identify broken
> &&-chains by pure textual inspection. Although the linter does not
> ...
> Heuristics are employed to properly identify the extent of a subshell
> formatted in the old-style since a number of legitimate constructs may
> superficially appear to close the subshell even though they don't. For
> example, it understands that neither "x=$(command)" nor "case $x in *)"
> end a subshell, despite the ")" at the end of line.
>
> Due to limitations of the tool used ('sed') and its inherent
> line-by-line processing, only subshells one level deep are handled, as
> well as one-liner subshells one level below that. Subshells deeper than
> that or multi-line subshells at level two are passed through as-is, thus
> &&-chains in their bodies are not checked.
>
> Signed-off-by: Eric Sunshine 
> ---

As with the previous "transform the script and feed the result to
shell" approach, this risks to force us into writing our tests in a
subset of valid shell language, which is the primary reason why I
was not enthused when I saw the previous round.  The worst part of
it is that the subset is not strictly defined based on the shell
language syntax or features (e.g. we allow this and that feature but
not that other feature) but "whatever that does not cause the linter
script to trigger false positives".

So I dunno.  I haven't spent enough time to carefully look at the
actual scripts to access how serious the "problem" I perceive
actually is with this series to form a firm opinion yet.  Let me
come back to the topic after doing so.