Summary
evo grep is documented/intended to prefer ripgrep and fall back to grep, but the availability check is inverted, so rg is never selected — every evo grep runs grep -rn.
Location
plugins/evo/src/evo/cli.py:2432 (cmd_ws_grep):
which = executor.run(["which", "rg"], cwd=str(base))
if (which.exit_code or 1) == 0 and which.stdout.strip():
cmd = ["rg", "--no-heading", "--line-number", args.pattern, str(base)]
else:
cmd = ["grep", "-rn", args.pattern, str(base)]
Root cause
which rg exits 0 when rg is present. But (which.exit_code or 1) collapses the success value: 0 is falsy, so 0 or 1 → 1, and the test becomes 1 == 0 → False. When rg is absent the exit code is 1, so 1 or 1 → 1, again 1 == 0 → False.
The condition is False in every case → the rg branch is dead code. The or 1 idiom (meant to coerce a None exit code into a failure sentinel) also clobbers the only value that should pass the check.
>>> (0 or 1) == 0 # rg present
False
>>> (1 or 1) == 0 # rg absent
False
Impact
On any machine with rg installed, evo grep <pattern> silently runs grep -rn instead. Because rg and grep differ in:
- regex dialect — a pattern written for
rg (\d, \b, lookarounds) matches differently or errors under BRE grep;
- ignore semantics —
rg respects .gitignore (skips node_modules/, build dirs); grep -rn searches them.
…the tool returns different/wrong results than intended, and the "prefer rg" contract is entirely non-functional.
Proposed fix
if which.exit_code == 0 and which.stdout.strip():
(or, preserving the None-guard intent: if (which.exit_code if which.exit_code is not None else 1) == 0 and which.stdout.strip():).
Verify
Stub executor.run(["which","rg"]) → exit_code=0, stdout="/usr/bin/rg\n" and assert cmd[0] == "rg"; it fails on current code. Or add a trace print of cmd and run evo grep foo in a workspace with rg on PATH — it picks grep.
Summary
evo grepis documented/intended to preferripgrepand fall back togrep, but the availability check is inverted, sorgis never selected — everyevo greprunsgrep -rn.Location
plugins/evo/src/evo/cli.py:2432(cmd_ws_grep):Root cause
which rgexits0whenrgis present. But(which.exit_code or 1)collapses the success value:0is falsy, so0 or 1→1, and the test becomes1 == 0→False. Whenrgis absent the exit code is1, so1 or 1→1, again1 == 0→False.The condition is
Falsein every case → thergbranch is dead code. Theor 1idiom (meant to coerce aNoneexit code into a failure sentinel) also clobbers the only value that should pass the check.Impact
On any machine with
rginstalled,evo grep <pattern>silently runsgrep -rninstead. Becausergandgrepdiffer in:rg(\d,\b, lookarounds) matches differently or errors under BREgrep;rgrespects.gitignore(skipsnode_modules/, build dirs);grep -rnsearches them.…the tool returns different/wrong results than intended, and the "prefer rg" contract is entirely non-functional.
Proposed fix
(or, preserving the
None-guard intent:if (which.exit_code if which.exit_code is not None else 1) == 0 and which.stdout.strip():).Verify
Stub
executor.run(["which","rg"])→exit_code=0, stdout="/usr/bin/rg\n"and assertcmd[0] == "rg"; it fails on current code. Or add a trace print ofcmdand runevo grep fooin a workspace withrgon PATH — it picksgrep.