feat: grep tool - #13
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds a built-in ChangesGrep tool
Sequence Diagram(s)sequenceDiagram
participant RunnerContext
participant GrepTool
participant FilesystemWalker
participant OutputHelpers
RunnerContext->>GrepTool: provide runner cwd
GrepTool->>FilesystemWalker: scan filtered files
FilesystemWalker-->>GrepTool: return regex matches
GrepTool->>OutputHelpers: serialize or spill output
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
crates/dch-tools/src/output.rs (1)
202-217: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest doesn't exercise the actual boundary-backup path.
Both assertions use content shorter than
PREVIEW_BYTES, sofloor_char_boundaryalways hits thei == s.len()short-circuit and never walks back over a continuation byte. The comment's claim that this "asserts the function is boundary-safe at the const limit" doesn't hold — the interesting case (target landing mid-character) is never constructed, and themultihalf discards its result entirely.✅ Suggested addition: directly test the backward-scan branch
+ #[test] + fn floor_char_boundary_backs_up_over_continuation_bytes() { + let s = "ééééé"; // 5 chars, 2 bytes each = 10 bytes total + // Byte 1 is a continuation byte of the first 'é'; must back up to 0. + assert_eq!(floor_char_boundary(s, 1), 0); + // Byte 3 is a continuation byte of the second 'é'; must back up to 2. + assert_eq!(floor_char_boundary(s, 3), 2); + // An exact boundary should be returned unchanged. + assert_eq!(floor_char_boundary(s, 4), 4); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/dch-tools/src/output.rs` around lines 202 - 217, Update the test preview_slice_respects_char_boundary to use input longer than PREVIEW_BYTES with a multibyte character crossing the cutoff, so preview_slice must back up over continuation bytes. Assert the returned value explicitly equals the input prefix ending at the preceding valid character boundary, and remove the discarded-result assertion and inaccurate commentary.crates/dch-tools/src/grep.rs (1)
238-264: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winNo cap on total matches across files or on individual file size read into memory.
The per-file
max_matchescap bounds a single file's contribution, butjob::runaccumulates matches across an unbounded number of files with no overall ceiling, and each file is read fully into memory regardless of size. On a large repo or a huge matched text file this can spike memory/CPU on the blocking thread well before the 50 KiB output-spill kicks in.♻️ Suggested: bound total matches across the walk
pub(super) fn run(job: &SearchJob) -> ToolOutput { let mut matches = Vec::new(); + const MAX_TOTAL_MATCHES: usize = 10_000; for entry in walk::walk_files(&job.base, &job.include, &job.exclude) { + if matches.len() >= MAX_TOTAL_MATCHES { + break; + } let path = entry.path(); if walk::likely_binary(path) { continue; } let Ok(content) = std::fs::read_to_string(path) else { continue; }; let file_matches = search_file(&job.regex, &content, path, &job.base, job.max_matches); matches.extend(file_matches); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/dch-tools/src/grep.rs` around lines 238 - 264, Update job::run to enforce a total match limit across all files, stopping or truncating collection once the cap is reached while preserving the per-file job.max_matches behavior. Replace the unbounded read_to_string call with bounded file reading or an explicit size guard so oversized files are skipped or processed without loading them fully into memory, and keep the existing output truncation flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/dch-tools/src/grep.rs`:
- Around line 444-458: Update the match-collection loop in the grep result
function to check whether results has reached max_matches before testing or
pushing a matching line, so max_matches = 0 returns no results while positive
limits retain the existing cap behavior.
In `@crates/dch-tools/src/regex_cache.rs`:
- Around line 141-142: Serialize the cache-size-sensitive tests, including
clear_cache_empties_state and the tests around cache_hit_returns_matching_regex
and the additional affected ranges, so they cannot run concurrently with other
REGEX_CACHE-mutating tests. Use the module’s existing test-serialization
mechanism if available, or add a shared synchronization guard around each
affected test while preserving their current assertions and behavior.
---
Nitpick comments:
In `@crates/dch-tools/src/grep.rs`:
- Around line 238-264: Update job::run to enforce a total match limit across all
files, stopping or truncating collection once the cap is reached while
preserving the per-file job.max_matches behavior. Replace the unbounded
read_to_string call with bounded file reading or an explicit size guard so
oversized files are skipped or processed without loading them fully into memory,
and keep the existing output truncation flow.
In `@crates/dch-tools/src/output.rs`:
- Around line 202-217: Update the test preview_slice_respects_char_boundary to
use input longer than PREVIEW_BYTES with a multibyte character crossing the
cutoff, so preview_slice must back up over continuation bytes. Assert the
returned value explicitly equals the input prefix ending at the preceding valid
character boundary, and remove the discarded-result assertion and inaccurate
commentary.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d049e366-b473-4248-8461-2af97044dddc
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
Cargo.tomlcrates/dch-tools/Cargo.tomlcrates/dch-tools/src/grep.rscrates/dch-tools/src/lib.rscrates/dch-tools/src/output.rscrates/dch-tools/src/regex_cache.rscrates/dch-tools/src/registry.rs
No description provided.