fix(grep): keep rg on the ripgrep path — split the rg/grep rewrite rule#2460
Open
alex-mextner wants to merge 1 commit into
Open
fix(grep): keep rg on the ripgrep path — split the rg/grep rewrite rule#2460alex-mextner wants to merge 1 commit into
alex-mextner wants to merge 1 commit into
Conversation
The single `^(rg|grep)\s+` rule routed BOTH tools to `rtk grep`, whose argument translation is grep-flavored: it strips `-r`/`-R`/`--recursive`, rewrites BRE `\|` to PCRE `|`, defaults empty paths to `.`, and forwards only a curated allowlist of rg flags. That silently corrupts genuine ripgrep invocations: - ripgrep-only flags (`--hidden`, `-g`/`--glob`, `--stats`, `-uu`, `-P`, `--json`) are dropped or rejected; - the short-flag collision `-r` (grep recursive vs ripgrep `--replace`) changes intent; - path-less `rg PATTERN` (ripgrep recurses CWD) is mishandled. Split the rule in two: `grep` keeps routing to `rtk grep` (unchanged), `rg` now routes to `rtk rg`. `rtk rg` is not a Clap subcommand, so it falls through `run_fallback` in `main.rs`, which executes the real `rg` binary with every argument forwarded verbatim (still metrics-tracked). This keeps ripgrep semantics faithful with no crossover in either direction. `rtk rg` does no output filtering, so its rule carries `savings_pct: 0.0`. Docs (rewrite table, savings table, `rtk grep` section) and the Claude hook rewrite regression test are updated so `rg` is documented and tested as rewriting to `rtk rg`, not `rtk grep`. Closes rtk-ai#1824, rtk-ai#2167, rtk-ai#2301, rtk-ai#2338. Signed-off-by: Alex Ultra <invntrm@icloud.com>
76a1234 to
00c5c0f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The single rewrite rule
^(rg|grep)\s+insrc/discover/rules.rscollapses bothtools onto
rtk grep.rtk grepruns ripgrep as its backend but appliesgrep-flavored argument translation (
src/cmds/system/grep_cmd.rs): it strips-r/-R/--recursive, rewrites BRE\|to PCRE|, defaults empty paths to.,and forwards only a curated allowlist of rg flags. That translation is correct for
grep, but it silently corrupts genuine ripgrep invocations:--hidden,-g/--glob,--stats,-uu,-P,--json)are dropped or rejected;
-ris recursive in grep but--replacein ripgrep, so a grep-flavored wrapper that strips
-rchanges whatrgmeans;rg PATTERN(ripgrep recurses CWD) is mishandled.This PR keeps each tool on its own backend by splitting the one rule into two:
grepkeeps routing tortk grep(unchanged), andrgnow routes tortk rg.rtk rgis intentionally not a Clap subcommand, so it falls throughrun_fallbackinmain.rs, which executes the realrgbinary with every argumentforwarded verbatim (still metrics-tracked). No crossover in either direction;
ripgrep semantics stay faithful.
This is the minimal, conflict-free version of what the larger #2183 attempted.
It does not change
grep's backend and adds no new filtered subcommand, so it avoidsthe conflicts/pushback #2183 hit while still resolving the
rgcorrectness issues.A real filtered
rtk rgsubcommand can come later as a separate, additive change.Changes
src/discover/rules.rs^(rg|grep)\s+rule into^rg\s+→rtk rgand^grep\s+→rtk grep.rgrule carriessavings_pct: 0.0becausertk rgis a verbatimpassthrough (no output filtering). Keeping the inherited 75% would make
rtk discoverfalsely reportrgas a high-value missed optimization.src/discover/registry.rstest_rewrite_rg_patternto expectrtk rg(wasrtk grep).rgandgrepeach route to their own target; ripgrep-only flags,flag ordering, the
-r=--replacecase, and path-lessrg PATTERNare forwardedverbatim to
rtk rg; classify reportsrtk rgat 0% andrtk grepat 75%.Docs (
README.md,docs/usage/FEATURES.md)rtk grepsection sorgis documented asrewriting to
rtk rg(verbatim ripgrep passthrough), notrtk grep.Issues fixed
--glob,-g,--version)rtk hook clauderewritesrg→rtk grepso path-less ripgrep searches silently return 0 matches / hang on stdinKnown limitations / follow-ups (out of scope here)
rtk rgis intentionally not a Clap subcommand — it relies onrun_fallback,which is the generic path for any unknown
rtk <cmd>. That path has two pre-existingwarts that now also apply to the (newly intentional)
rgroute:.rtk/filters.tomlexists and is untrusted,run_fallbackprints[rtk] WARNING: untrusted project filters …(and runs TOML-filter lookup) beforethe ripgrep output — so it is not byte-for-byte clean passthrough in that case.
record_parse_failure_silent(.., true), solegitimate
rgusage shows up underrtk gain --failuresas a parse failure.These are broader
run_fallbackbehaviors (true for every unknown command today), notneeded to fix the
rgcorrectness bugs this PR targets. The minimal, safe follow-up isto make declared passthrough tools first-class — e.g. special-case
args[0] == "rg"inrun_fallbackto skip the TOML/trust-warning path and the parse-failure accounting — oradd a real filtered
rtk rgsubcommand (the #2183 direction). I kept that out of this PRto stay minimal and conflict-free; happy to send it as a focused follow-up.
Relation to #2183
#2183 ("respect the invoked tool — grep runs grep, rg runs ripgrep") is still OPEN
and CONFLICTING. It took a bigger approach: a real filtered
rtk rgsubcommand andswitching
rtk grepto system grep. This PR does not supersede that design wholesale —it lands the smallest slice that fixes the open
rgissues (the rewrite-rule split)without touching
grep's backend or adding a subcommand, so it rebases cleanly on thecurrent
developand stays in scope. If maintainers prefer #2183's larger direction,this can be closed; otherwise this unblocks the
rgcorrectness issues now.Test plan
cargo fmt --all -- --check— cleancargo clippy --all-targets -- -D warnings— cleancargo test --all— 2198 passed (the 2 local failures inhooks::rewrite_cmd::tests::unattestable_passthrough::{test_plain_command_still_rewrites, test_fd_dup_redirect_still_rewrites}are pre-existing ondevelopand depend on thedeveloper's local Claude Code permission allow-list for
git status; with a clean$HOME— as on CI — all of them pass, and they are unrelated to this diff)