mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 08:47:44 +00:00
feat: use .geminiignore in grep tool (#349)
* feat: use .geminiignore in grep tool
This commit is contained in:
@@ -11,6 +11,7 @@ import fs from 'fs/promises';
|
|||||||
import os from 'os';
|
import os from 'os';
|
||||||
import { Config } from '../config/config.js';
|
import { Config } from '../config/config.js';
|
||||||
import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
|
import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
|
||||||
|
import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
||||||
|
|
||||||
// Mock the child_process module to control grep/git grep behavior
|
// Mock the child_process module to control grep/git grep behavior
|
||||||
vi.mock('child_process', () => ({
|
vi.mock('child_process', () => ({
|
||||||
@@ -32,9 +33,14 @@ describe('GrepTool', () => {
|
|||||||
let grepTool: GrepTool;
|
let grepTool: GrepTool;
|
||||||
const abortSignal = new AbortController().signal;
|
const abortSignal = new AbortController().signal;
|
||||||
|
|
||||||
|
const mockFileService = {
|
||||||
|
getGeminiIgnorePatterns: () => [],
|
||||||
|
} as unknown as FileDiscoveryService;
|
||||||
|
|
||||||
const mockConfig = {
|
const mockConfig = {
|
||||||
getTargetDir: () => tempRootDir,
|
getTargetDir: () => tempRootDir,
|
||||||
getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
|
getWorkspaceContext: () => createMockWorkspaceContext(tempRootDir),
|
||||||
|
getFileService: () => mockFileService,
|
||||||
} as unknown as Config;
|
} as unknown as Config;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -220,6 +226,43 @@ describe('GrepTool', () => {
|
|||||||
"Model provided invalid parameters. Error: params must have required property 'pattern'",
|
"Model provided invalid parameters. Error: params must have required property 'pattern'",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should exclude files matching geminiIgnorePatterns', async () => {
|
||||||
|
// Create a file that should be ignored
|
||||||
|
await fs.writeFile(
|
||||||
|
path.join(tempRootDir, 'ignored-file.txt'),
|
||||||
|
'this file should be ignored\nit contains the word world',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update the mock file service to return ignore patterns
|
||||||
|
mockFileService.getGeminiIgnorePatterns = () => ['ignored-file.txt'];
|
||||||
|
|
||||||
|
// Re-create the grep tool with the updated mock
|
||||||
|
const grepToolWithIgnore = new GrepTool(mockConfig);
|
||||||
|
|
||||||
|
// Search for 'world' which exists in both the regular file and the ignored file
|
||||||
|
const params: GrepToolParams = { pattern: 'world' };
|
||||||
|
const result = await grepToolWithIgnore.execute(params, abortSignal);
|
||||||
|
|
||||||
|
// Should only find matches in the non-ignored files (3 matches)
|
||||||
|
expect(result.llmContent).toContain(
|
||||||
|
'Found 3 matches for pattern "world" in the workspace directory',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should find matches in the regular files
|
||||||
|
expect(result.llmContent).toContain('File: fileA.txt');
|
||||||
|
expect(result.llmContent).toContain('L1: hello world');
|
||||||
|
expect(result.llmContent).toContain('L2: second line with world');
|
||||||
|
expect(result.llmContent).toContain(
|
||||||
|
`File: ${path.join('sub', 'fileC.txt')}`,
|
||||||
|
);
|
||||||
|
expect(result.llmContent).toContain('L1: another world in sub dir');
|
||||||
|
|
||||||
|
// Should NOT find matches in the ignored file
|
||||||
|
expect(result.llmContent).not.toContain('ignored-file.txt');
|
||||||
|
|
||||||
|
expect(result.returnDisplay).toBe('Found 3 matches');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('multi-directory workspace', () => {
|
describe('multi-directory workspace', () => {
|
||||||
@@ -238,10 +281,15 @@ describe('GrepTool', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Create a mock config with multiple directories
|
// Create a mock config with multiple directories
|
||||||
|
const multiDirFileService = {
|
||||||
|
getGeminiIgnorePatterns: () => [],
|
||||||
|
};
|
||||||
|
|
||||||
const multiDirConfig = {
|
const multiDirConfig = {
|
||||||
getTargetDir: () => tempRootDir,
|
getTargetDir: () => tempRootDir,
|
||||||
getWorkspaceContext: () =>
|
getWorkspaceContext: () =>
|
||||||
createMockWorkspaceContext(tempRootDir, [secondDir]),
|
createMockWorkspaceContext(tempRootDir, [secondDir]),
|
||||||
|
getFileService: () => multiDirFileService,
|
||||||
} as unknown as Config;
|
} as unknown as Config;
|
||||||
|
|
||||||
const multiDirGrepTool = new GrepTool(multiDirConfig);
|
const multiDirGrepTool = new GrepTool(multiDirConfig);
|
||||||
@@ -287,10 +335,15 @@ describe('GrepTool', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Create a mock config with multiple directories
|
// Create a mock config with multiple directories
|
||||||
|
const multiDirFileService = {
|
||||||
|
getGeminiIgnorePatterns: () => [],
|
||||||
|
};
|
||||||
|
|
||||||
const multiDirConfig = {
|
const multiDirConfig = {
|
||||||
getTargetDir: () => tempRootDir,
|
getTargetDir: () => tempRootDir,
|
||||||
getWorkspaceContext: () =>
|
getWorkspaceContext: () =>
|
||||||
createMockWorkspaceContext(tempRootDir, [secondDir]),
|
createMockWorkspaceContext(tempRootDir, [secondDir]),
|
||||||
|
getFileService: () => multiDirFileService,
|
||||||
} as unknown as Config;
|
} as unknown as Config;
|
||||||
|
|
||||||
const multiDirGrepTool = new GrepTool(multiDirConfig);
|
const multiDirGrepTool = new GrepTool(multiDirConfig);
|
||||||
|
|||||||
@@ -536,12 +536,18 @@ export class GrepTool extends BaseTool<GrepToolParams, ToolResult> {
|
|||||||
);
|
);
|
||||||
strategyUsed = 'javascript fallback';
|
strategyUsed = 'javascript fallback';
|
||||||
const globPattern = include ? include : '**/*';
|
const globPattern = include ? include : '**/*';
|
||||||
|
|
||||||
|
// Get the file discovery service to check ignore patterns
|
||||||
|
const fileDiscovery = this.config.getFileService();
|
||||||
|
|
||||||
|
// Basic ignore patterns
|
||||||
const ignorePatterns = [
|
const ignorePatterns = [
|
||||||
'.git/**',
|
'.git/**',
|
||||||
'node_modules/**',
|
'node_modules/**',
|
||||||
'bower_components/**',
|
'bower_components/**',
|
||||||
'.svn/**',
|
'.svn/**',
|
||||||
'.hg/**',
|
'.hg/**',
|
||||||
|
...fileDiscovery.getGeminiIgnorePatterns(),
|
||||||
]; // Use glob patterns for ignores here
|
]; // Use glob patterns for ignores here
|
||||||
|
|
||||||
const filesIterator = globIterate(globPattern, {
|
const filesIterator = globIterate(globPattern, {
|
||||||
|
|||||||
Reference in New Issue
Block a user