diff options
author | Eric Sunshine <sunshine@sunshineco.com> | 2022-09-01 02:29:50 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-09-01 19:07:41 +0200 |
commit | fd4094c3cad7c62adb0b7080e0dca37f66bf0c6e (patch) | |
tree | b83ea76c26940ea812ffc4b768f02e6f9ea5d434 /t/chainlint.pl | |
parent | chainlint.pl: don't flag broken &&-chain if failure indicated explicitly (diff) | |
download | git-fd4094c3cad7c62adb0b7080e0dca37f66bf0c6e.tar.xz git-fd4094c3cad7c62adb0b7080e0dca37f66bf0c6e.zip |
chainlint.pl: complain about loops lacking explicit failure handling
Shell `for` and `while` loops do not terminate automatically just
because a command fails within the loop body. Instead, the loop
continues to iterate and eventually returns the exit status of the final
command of the final iteration, which may not be the command which
failed, thus it is possible for failures to go undetected. Consequently,
it is important for test authors to explicitly handle failure within the
loop body by terminating the loop manually upon failure. This can be
done by returning a non-zero exit code from within the loop body
(i.e. `|| return 1`) or exiting (i.e. `|| exit 1`) if the loop is within
a subshell, or by manually checking `$?` and taking some appropriate
action. Therefore, add logic to detect and complain about loops which
lack explicit `return` or `exit`, or `$?` check.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't/chainlint.pl')
-rwxr-xr-x | t/chainlint.pl | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/t/chainlint.pl b/t/chainlint.pl index a76a09ecf5..674b3ddf69 100755 --- a/t/chainlint.pl +++ b/t/chainlint.pl @@ -482,6 +482,17 @@ sub match_ending { return undef; } +sub parse_loop_body { + my $self = shift @_; + my @tokens = $self->SUPER::parse_loop_body(@_); + # did loop signal failure via "|| return" or "|| exit"? + return @tokens if !@tokens || grep(/^(?:return|exit|\$\?)$/, @tokens); + # flag missing "return/exit" handling explicit failure in loop body + my $n = find_non_nl(\@tokens); + splice(@tokens, $n + 1, 0, '?!LOOP?!'); + return @tokens; +} + my @safe_endings = ( [qr/^(?:&&|\|\||\||&)$/], [qr/^(?:exit|return)$/, qr/^(?:\d+|\$\?)$/], |