]> git.ipfire.org Git - thirdparty/git.git/commit
t: add greplint to detect bare grep assertions
authorMichael Montalbo <mmontalbo@gmail.com>
Mon, 6 Jul 2026 05:01:58 +0000 (05:01 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 6 Jul 2026 20:27:00 +0000 (13:27 -0700)
commitbe7112d1bb97a0f4c4d724484e8940193ab5366d
treea3e9d1b74bea7e1256d2d86f4214a60cdfac9044
parent47f79f619834acdd39d39bd1d3b33bf57f80d0a2
t: add greplint to detect bare grep assertions

Without a lint guard, bare grep assertions will creep back into
tests over time, defeating the previous commit's conversion.

Add greplint.pl to catch bare 'grep' used as a test assertion
(where 'test_grep' should be used) and '! test_grep' (where
'test_grep !' should be used).

greplint.pl reuses the shared shell parser from lib-shell-parser.pl
to tokenize test bodies.  The Lexer collapses heredocs, command
substitutions, and quoted strings into single tokens, so 'grep'
appearing inside these contexts is not flagged.  A flat walk over
the token stream tracks command position and pipeline state to
distinguish assertion greps from filter greps.

For double-quoted test bodies, a source-line walk counts
backslash-continuation lines that the Lexer consumes without
emitting into the body text, adjusting the reported line number
accordingly.

Add test fixtures in greplint/ (modeled on chainlint/) covering
detection of bare grep assertions, correct skipping of filters,
pipelines, redirects, command substitutions, and lint-ok annotations.

Wire into the Makefile as:
  - test-greplint: runs greplint.pl on $(T) $(THELPERS) $(TPERF)
  - check-greplint: runs greplint.pl on fixtures, diffs against expected
  - clean-greplint: removes temp dir

Add eol=lf entries in t/.gitattributes for greplint fixtures,
matching chainlint, so that check-greplint passes on Windows
where core.autocrlf would otherwise cause CRLF mismatches
between expected and actual output.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
44 files changed:
t/.gitattributes
t/Makefile
t/greplint-cat.pl [new file with mode: 0644]
t/greplint.pl [new file with mode: 0644]
t/greplint/bare-grep-after-and.expect [new file with mode: 0644]
t/greplint/bare-grep-after-and.test [new file with mode: 0644]
t/greplint/bare-grep-after-semicolon.expect [new file with mode: 0644]
t/greplint/bare-grep-after-semicolon.test [new file with mode: 0644]
t/greplint/bare-grep-compound-body.expect [new file with mode: 0644]
t/greplint/bare-grep-compound-body.test [new file with mode: 0644]
t/greplint/bare-grep-count-mode.expect [new file with mode: 0644]
t/greplint/bare-grep-count-mode.test [new file with mode: 0644]
t/greplint/bare-grep-explicit-pattern.expect [new file with mode: 0644]
t/greplint/bare-grep-explicit-pattern.test [new file with mode: 0644]
t/greplint/bare-grep-flags.expect [new file with mode: 0644]
t/greplint/bare-grep-flags.test [new file with mode: 0644]
t/greplint/bare-grep-lint-ok.expect [new file with mode: 0644]
t/greplint/bare-grep-lint-ok.test [new file with mode: 0644]
t/greplint/bare-grep-negated.expect [new file with mode: 0644]
t/greplint/bare-grep-negated.test [new file with mode: 0644]
t/greplint/bare-grep-pattern-file.expect [new file with mode: 0644]
t/greplint/bare-grep-pattern-file.test [new file with mode: 0644]
t/greplint/bare-grep-simple.expect [new file with mode: 0644]
t/greplint/bare-grep-simple.test [new file with mode: 0644]
t/greplint/bare-grep-subshell.expect [new file with mode: 0644]
t/greplint/bare-grep-subshell.test [new file with mode: 0644]
t/greplint/dqstring-continuation-offset.expect [new file with mode: 0644]
t/greplint/dqstring-continuation-offset.test [new file with mode: 0644]
t/greplint/filter-command-substitution.expect [new file with mode: 0644]
t/greplint/filter-command-substitution.test [new file with mode: 0644]
t/greplint/filter-pipe-input.expect [new file with mode: 0644]
t/greplint/filter-pipe-input.test [new file with mode: 0644]
t/greplint/filter-pipe-output.expect [new file with mode: 0644]
t/greplint/filter-pipe-output.test [new file with mode: 0644]
t/greplint/filter-redirect-output.expect [new file with mode: 0644]
t/greplint/filter-redirect-output.test [new file with mode: 0644]
t/greplint/filter-stdin-redirect.expect [new file with mode: 0644]
t/greplint/filter-stdin-redirect.test [new file with mode: 0644]
t/greplint/grep-as-argument.expect [new file with mode: 0644]
t/greplint/grep-as-argument.test [new file with mode: 0644]
t/greplint/grep-as-value.expect [new file with mode: 0644]
t/greplint/grep-as-value.test [new file with mode: 0644]
t/greplint/wrong-negation.expect [new file with mode: 0644]
t/greplint/wrong-negation.test [new file with mode: 0644]