chainlint: don't be fooled by "?!...?!" in test body
As originally implemented, chainlint did not collect structured information about detected problems. Instead, it merely emitted raw parse tokens (not the original test text), along with a "?!...?!" annotation directly into the output stream each time a problem was discovered. In order to report statistics (in --stats mode) and to adjust its exit code to indicate success or failure, it merely counts the number of times "?!...?!" appears in the output stream. An obvious shortcoming of this approach is that it can be fooled by a legitimate "?!...?!" sequence in the body of a test (though, only if an actual problem is detected in the test). The situation did not improve when7c04aa7390
(chainlint: colorize problem annotations and test delimiters, 2022-09-13) colored the annotations after-the-fact by searching for "?!...?!" in the output stream and inserting color codes. As above, a shortcoming is that this approach can incorrectly color a legitimate "?!...?!" sequence in a test body as if it is an error. However, when73c768dae9
(chainlint: annotate original test definition rather than token stream, 2022-11-08) taught chainlint to output the original test text verbatim, it started collecting structured information about detected problems. Now that it is available, take advantage of the structured problem information to deterministically count the number of problems detected and to color the annotations directly, rather than scanning the output stream for "?!...?!" and performing these operations after-the-fact. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
17d4b10aea
commit
588ef84ece
@ -587,6 +587,7 @@ sub new {
|
||||
my $class = shift @_;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->{ntests} = 0;
|
||||
$self->{nerrs} = 0;
|
||||
return $self;
|
||||
}
|
||||
|
||||
@ -634,6 +635,7 @@ sub check_test {
|
||||
my $parser = TestParser->new(\$body);
|
||||
my @tokens = $parser->parse();
|
||||
my $problems = $parser->{problems};
|
||||
$self->{nerrs} += @$problems;
|
||||
return unless $emit_all || @$problems;
|
||||
my $c = main::fd_colors(1);
|
||||
my $start = 0;
|
||||
@ -641,15 +643,16 @@ sub check_test {
|
||||
for (sort {$a->[1]->[2] <=> $b->[1]->[2]} @$problems) {
|
||||
my ($label, $token) = @$_;
|
||||
my $pos = $token->[2];
|
||||
$checked .= substr($body, $start, $pos - $start) . " ?!$label?! ";
|
||||
$checked .= substr($body, $start, $pos - $start);
|
||||
$checked .= ' ' unless $checked =~ /\s$/;
|
||||
$checked .= "$c->{rev}$c->{red}?!$label?!$c->{reset}";
|
||||
$checked .= ' ' unless $pos >= length($body) ||
|
||||
substr($body, $pos, 1) =~ /^\s/;
|
||||
$start = $pos;
|
||||
}
|
||||
$checked .= substr($body, $start);
|
||||
$checked =~ s/^/$lineno++ . ' '/mge;
|
||||
$checked =~ s/^\d+ \n//;
|
||||
$checked =~ s/(\s) \?!/$1?!/mg;
|
||||
$checked =~ s/\?! (\s)/?!$1/mg;
|
||||
$checked =~ s/(\?![^?]+\?!)/$c->{rev}$c->{red}$1$c->{reset}/mg;
|
||||
$checked =~ s/^\d+/$c->{dim}$&$c->{reset}/mg;
|
||||
$checked .= "\n" unless $checked =~ /\n$/;
|
||||
push(@{$self->{output}}, "$c->{blue}# chainlint: $title$c->{reset}\n$checked");
|
||||
@ -791,9 +794,9 @@ sub check_script {
|
||||
my $c = fd_colors(1);
|
||||
my $s = join('', @{$parser->{output}});
|
||||
$emit->("$c->{bold}$c->{blue}# chainlint: $path$c->{reset}\n" . $s);
|
||||
$nerrs += () = $s =~ /\?![^?]+\?!/g;
|
||||
}
|
||||
$ntests += $parser->{ntests};
|
||||
$nerrs += $parser->{nerrs};
|
||||
}
|
||||
return [$id, $nscripts, $ntests, $nerrs];
|
||||
}
|
||||
|
Reference in New Issue
Block a user