Repository navigation
fix(search): treat -f/--file as a pattern source, not a positional pa… - #3666
dwin-gharibi wants to merge 1 commit into
Conversation
…ttern grep and rg both read patterns from a file with -f/--file, the file-based twin of -e. extract_pattern_path classified them as generic value-taking flags, so the first positional -- the file to search -- was consumed as the pattern and the path list was left empty, making the engine read stdin. rtk grep -f patterns.txt app.log returned no output and exit 1 where grep returns three matches; with two files it returned matches from the wrong file. Both are silent: nothing in the exit code or stderr distinguishes them from a genuine no-match. Track the flag during the arg scan rather than inspecting flags afterwards, so another option's value cannot be mistaken for it.
|
This also fixes the On grep, Fixture — three files; the question asked is "which lines of Three-way, all four $ rg -f pats.txt hay.txt # real ripgrep 15.2.0
alpha FOO one
gamma FOO three
exit=0
$ rtk rg -f pats.txt hay.txt # v0.48.0
FOO <-- from pats.txt, not searched
alpha FOO one
gamma FOO three
unrelated FOO in another file <-- from sub/, not searched
exit=0
$ rtk rg -f pats.txt hay.txt # this branch
alpha FOO one
gamma FOO three
exit=0The extra lines come from files the caller never named — and note it matched Every form reaches parity with the real engine on this branch, and every one of
Measured on debug builds of The one gap: |
|
Thanks for the precise diagnosis and the four-spelling test table. This landed on develop in #3681 (merged 2026-09-12): extract_pattern_path now tracks a patterns_from_file flag during the scan and, as in your patch, treats every positional as a path when -f or --file is present, with a test covering -f F, --file F, -fF and --file=F. That PR also rebuilt the function on the shared argument tokenizer, so the hand-rolled flag scan your hunks edit is no longer in the file and they can no longer apply. Issue #3665 is still open only because it has not been verified against a release yet. Closing this, but please comment or reopen if you find a form that develop still gets wrong. |
Closes #3665.
Summary
-f/--fileas a pattern source inextract_pattern_path, exactly like-e/--regexp: when one is present every positional is a path, not a pattern.rtk grep -f patterns.txt app.logsilently returning no matches (exit 1) where realgrep returns matches — and, with two files, returning matches from the wrong file.
flagsafterwards, soanother option's value that happens to read
-fcannot be mistaken for it.With no positional pattern left,
run()takes its existingpatterns.is_empty()passthroughbranch and executes the user's command verbatim — correct output, no compression on this form.
Grouping
-fsearches is a follow-up; correctness first.Test plan
cargo fmt --all && cargo clippy --all-targets && cargo testrtk <command>output inspectedUnit tests (added, TDD — red before green)
src/cmds/system/search.rs:pattern_file_flag_leaves_positionals_as_paths— all four spellings (-f F,--file F,--file=F,-fF) yield no positional pattern and keep the search path.Fails on
developwith:["-f", "pats.txt", "hay.txt"]: a pattern file must not turn a positional into the pattern, got ["hay.txt"].pattern_file_flag_is_forwarded_to_the_engine—-fand its value still reach the engine.positional_pattern_still_wins_without_a_pattern_source— guards the ordinary form.Behavioural check against real grep
Every case below now produces byte-identical output and exit code to GNU grep:
grep -f patterns.txt app.loggrep --file patterns.txt app.loggrep --file=patterns.txt app.loggrep -fpatterns.txt app.loggrep -f patterns.txt app.log second.loggrep -n -f patterns.txt app.logControls confirming ordinary grep is untouched:
grep -n ERROR,grep -c ERROR,grep -e ERROR -e WARN,grep ERROR a b— all identical before and after.