Skip to content

Commit ae0c55a

Browse files
sunshinecogitster
authored andcommitted
chainlint.pl: allow || echo to signal failure upstream of a pipe
The use of `|| return` (or `|| exit`) to signal failure within a loop isn't effective when the loop is upstream of a pipe since the pipe swallows all upstream exit codes and returns only the exit code of the final command in the pipeline. To work around this limitation, tests may adopt an alternative strategy of signaling failure by emitting text which would never be emitted in the non-failing case. For instance: while condition do command1 && command2 || echo "impossible text" done | sort >actual && Such usage indicates deliberate thought about failure cases by the test author, thus flagging them as missing `|| return` (or `|| exit`) is not helpful. Therefore, take this case into consideration when checking for explicit loop termination. Signed-off-by: Eric Sunshine <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fd4094c commit ae0c55a

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

t/chainlint.pl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ sub parse_loop_body {
487487
my @tokens = $self->SUPER::parse_loop_body(@_);
488488
# did loop signal failure via "|| return" or "|| exit"?
489489
return @tokens if !@tokens || grep(/^(?:return|exit|\$\?)$/, @tokens);
490+
# did loop upstream of a pipe signal failure via "|| echo 'impossible
491+
# text'" as the final command in the loop body?
492+
return @tokens if ends_with(\@tokens, [qr/^\|\|$/, "\n", qr/^echo$/, qr/^.+$/]);
490493
# flag missing "return/exit" handling explicit failure in loop body
491494
my $n = find_non_nl(\@tokens);
492495
splice(@tokens, $n + 1, 0, '?!LOOP?!');

t/chainlint/loop-upstream-pipe.expect

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(
2+
git rev-list --objects --no-object-names base..loose |
3+
while read oid
4+
do
5+
path="$objdir/$(test_oid_to_path "$oid")" &&
6+
printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" ||
7+
echo "object list generation failed for $oid"
8+
done |
9+
sort -k1
10+
) >expect &&

t/chainlint/loop-upstream-pipe.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
(
2+
git rev-list --objects --no-object-names base..loose |
3+
while read oid
4+
do
5+
# LINT: "|| echo" signals failure in loop upstream of a pipe
6+
path="$objdir/$(test_oid_to_path "$oid")" &&
7+
printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" ||
8+
echo "object list generation failed for $oid"
9+
done |
10+
sort -k1
11+
) >expect &&

0 commit comments

Comments
 (0)