|
1 | 1 | import { z } from "zod"; |
2 | | -import globToRegexp from "glob-to-regexp"; |
3 | 2 | import { isServiceError } from "@/lib/utils"; |
4 | 3 | import { search } from "@/features/search"; |
5 | | -import escapeStringRegexp from "escape-string-regexp"; |
6 | 4 | import { Source, ToolDefinition } from "./types"; |
7 | 5 | import { logger } from "./logger"; |
8 | 6 | import description from "./grep.txt"; |
9 | 7 | import { CodeHostType } from "@sourcebot/db"; |
10 | 8 | import { getRepoInfoByName } from "@/actions"; |
| 9 | +import { buildGrepSearchQuery } from "./searchQuery"; |
11 | 10 |
|
12 | 11 | const DEFAULT_LIMIT = 100; |
13 | 12 | const DEFAULT_GROUP_BY_REPO_LIMIT = 10_000; |
14 | 13 | const MAX_LINE_LENGTH = 2000; |
15 | 14 | const MAX_LINE_SUFFIX = `... (line truncated to ${MAX_LINE_LENGTH} chars)`; |
16 | 15 | const TRUNCATION_MESSAGE = `(Results truncated. Consider using a more specific path or pattern, specifying a repo, or increasing the limit.)`; |
17 | 16 |
|
18 | | -function globToFileRegexp(glob: string): string { |
19 | | - const re = globToRegexp(glob, { extended: true, globstar: true }); |
20 | | - return re.source.replace(/^\^/, ''); |
21 | | -} |
22 | | - |
23 | 17 | const grepShape = { |
24 | 18 | pattern: z |
25 | 19 | .string() |
@@ -66,7 +60,6 @@ export type GrepRepoInfo = { |
66 | 60 | export type GrepMetadata = { |
67 | 61 | files: GrepFile[]; |
68 | 62 | pattern: string; |
69 | | - query: string; |
70 | 63 | matchCount: number; |
71 | 64 | repoCount: number; |
72 | 65 | repoInfoMap: Record<string, GrepRepoInfo>; |
@@ -95,35 +88,21 @@ export const grepDefinition: ToolDefinition<'grep', typeof grepShape, GrepMetada |
95 | 88 |
|
96 | 89 | logger.debug('grep', { pattern, path, include, repo, ref, limit, groupByRepo }); |
97 | 90 |
|
98 | | - const quotedPattern = `"${pattern.replace(/"/g, '\\"')}"`; |
99 | | - let query = quotedPattern; |
100 | | - |
101 | | - if (path) { |
102 | | - query += ` file:${escapeStringRegexp(path)}`; |
103 | | - } |
104 | | - |
105 | | - if (include) { |
106 | | - query += ` file:${globToFileRegexp(include)}`; |
107 | | - } |
108 | | - |
109 | | - if (repo) { |
110 | | - query += ` repo:${escapeStringRegexp(repo)}`; |
111 | | - } else if (context.selectedRepos && context.selectedRepos.length > 0) { |
112 | | - query += ` reposet:${context.selectedRepos.join(',')}`; |
113 | | - } |
114 | | - |
115 | | - if (ref) { |
116 | | - query += ` rev:${ref}`; |
117 | | - } |
| 91 | + const query = buildGrepSearchQuery({ |
| 92 | + pattern, |
| 93 | + path, |
| 94 | + include, |
| 95 | + repo, |
| 96 | + ref, |
| 97 | + selectedRepos: context.selectedRepos, |
| 98 | + }); |
118 | 99 |
|
119 | 100 | const response = await search({ |
120 | | - queryType: 'string', |
| 101 | + queryType: 'ir', |
121 | 102 | query, |
122 | 103 | options: { |
123 | 104 | matches: limit, |
124 | 105 | contextLines: 0, |
125 | | - isCaseSensitivityEnabled: true, |
126 | | - isRegexEnabled: true, |
127 | 106 | }, |
128 | 107 | source: context.source, |
129 | 108 | }); |
@@ -161,7 +140,6 @@ export const grepDefinition: ToolDefinition<'grep', typeof grepShape, GrepMetada |
161 | 140 | const metadata: GrepMetadata = { |
162 | 141 | files, |
163 | 142 | pattern, |
164 | | - query, |
165 | 143 | matchCount: response.stats.actualMatchCount, |
166 | 144 | repoCount: new Set(files.map((f) => f.repo)).size, |
167 | 145 | repoInfoMap, |
|
0 commit comments