diff options
| author | Anas H. Sulaiman <[email protected]> | 2025-06-14 10:25:34 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-06-14 14:25:34 +0000 |
| commit | 4873fce7919b4d74cee183a91fa8a3af58aef993 (patch) | |
| tree | c08502c1e4592667160cb006528f868fd6283294 /packages/cli/src/utils | |
| parent | e6d54771686b3f9537a5a05c9f9101afad3ffdcd (diff) | |
centralize file filtering in `FileDiscoveryService` (#1039)
Diffstat (limited to 'packages/cli/src/utils')
| -rw-r--r-- | packages/cli/src/utils/loadIgnorePatterns.test.ts | 150 | ||||
| -rw-r--r-- | packages/cli/src/utils/loadIgnorePatterns.ts | 56 |
2 files changed, 0 insertions, 206 deletions
diff --git a/packages/cli/src/utils/loadIgnorePatterns.test.ts b/packages/cli/src/utils/loadIgnorePatterns.test.ts deleted file mode 100644 index 5ff89c4d..00000000 --- a/packages/cli/src/utils/loadIgnorePatterns.test.ts +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { - vi, - describe, - it, - expect, - beforeEach, - afterEach, - Mock, - beforeAll, -} from 'vitest'; -import * as path from 'node:path'; -import { loadGeminiIgnorePatterns } from './loadIgnorePatterns.js'; -import os from 'node:os'; - -// Define the type for our mock function explicitly. -type ReadFileSyncMockType = Mock< - (path: string, encoding: string) => string | Buffer ->; - -// Declare a variable to hold our mock function instance. -let mockedFsReadFileSync: ReadFileSyncMockType; - -vi.mock('node:fs', async () => { - const actualFsModule = - await vi.importActual<typeof import('node:fs')>('node:fs'); - return { - ...actualFsModule, - readFileSync: vi.fn(), // The factory creates and returns the vi.fn() instance. - }; -}); - -let actualFs: typeof import('node:fs'); - -describe('loadGeminiIgnorePatterns', () => { - let tempDir: string; - let consoleLogSpy: Mock< - (message?: unknown, ...optionalParams: unknown[]) => void - >; - - beforeAll(async () => { - actualFs = await vi.importActual<typeof import('node:fs')>('node:fs'); - const mockedFsModule = await import('node:fs'); - mockedFsReadFileSync = - mockedFsModule.readFileSync as unknown as ReadFileSyncMockType; - }); - - beforeEach(() => { - tempDir = actualFs.mkdtempSync( - path.join(os.tmpdir(), 'gemini-ignore-test-'), - ); - consoleLogSpy = vi - .spyOn(console, 'log') - .mockImplementation(() => {}) as Mock< - (message?: unknown, ...optionalParams: unknown[]) => void - >; - mockedFsReadFileSync.mockReset(); - }); - - afterEach(() => { - if (actualFs.existsSync(tempDir)) { - actualFs.rmSync(tempDir, { recursive: true, force: true }); - } - vi.restoreAllMocks(); - }); - - it('should load and parse patterns from .geminiignore, ignoring comments and empty lines', async () => { - const ignoreContent = [ - '# This is a comment', - 'pattern1', - ' pattern2 ', // Should be trimmed - '', // Empty line - 'pattern3 # Inline comment', // Handled by trim - '*.log', - '!important.file', - ].join('\n'); - const ignoreFilePath = path.join(tempDir, '.geminiignore'); - actualFs.writeFileSync(ignoreFilePath, ignoreContent); - - const patterns = await loadGeminiIgnorePatterns(tempDir); - - expect(patterns).toEqual([ - 'pattern1', - 'pattern2', - 'pattern3 # Inline comment', - '*.log', - '!important.file', - ]); - expect(consoleLogSpy).toHaveBeenCalledWith( - expect.stringContaining('Loaded 5 patterns from .geminiignore'), - ); - }); - - it('should return an empty array and log info if .geminiignore is not found', async () => { - const patterns = await loadGeminiIgnorePatterns(tempDir); - expect(patterns).toEqual([]); - expect(consoleLogSpy).not.toHaveBeenCalled(); - }); - - it('should return an empty array if .geminiignore is empty', async () => { - const ignoreFilePath = path.join(tempDir, '.geminiignore'); - actualFs.writeFileSync(ignoreFilePath, ''); - - const patterns = await loadGeminiIgnorePatterns(tempDir); - expect(patterns).toEqual([]); - expect(consoleLogSpy).not.toHaveBeenCalledWith( - expect.stringContaining('Loaded 0 patterns from .geminiignore'), - ); - expect(consoleLogSpy).not.toHaveBeenCalledWith( - expect.stringContaining('No .geminiignore file found'), - ); - }); - - it('should return an empty array if .geminiignore contains only comments and empty lines', async () => { - const ignoreContent = [ - '# Comment 1', - ' # Comment 2 with leading spaces', - '', - ' ', // Whitespace only line - ].join('\n'); - const ignoreFilePath = path.join(tempDir, '.geminiignore'); - actualFs.writeFileSync(ignoreFilePath, ignoreContent); - - const patterns = await loadGeminiIgnorePatterns(tempDir); - expect(patterns).toEqual([]); - expect(consoleLogSpy).not.toHaveBeenCalledWith( - expect.stringContaining('Loaded 0 patterns from .geminiignore'), - ); - expect(consoleLogSpy).not.toHaveBeenCalledWith( - expect.stringContaining('No .geminiignore file found'), - ); - }); - - it('should correctly handle patterns with inline comments if not starting with #', async () => { - const ignoreContent = 'src/important # but not this part'; - const ignoreFilePath = path.join(tempDir, '.geminiignore'); - actualFs.writeFileSync(ignoreFilePath, ignoreContent); - - const patterns = await loadGeminiIgnorePatterns(tempDir); - expect(patterns).toEqual(['src/important # but not this part']); - expect(consoleLogSpy).toHaveBeenCalledWith( - expect.stringContaining('Loaded 1 patterns from .geminiignore'), - ); - }); -}); diff --git a/packages/cli/src/utils/loadIgnorePatterns.ts b/packages/cli/src/utils/loadIgnorePatterns.ts deleted file mode 100644 index 34efc8c8..00000000 --- a/packages/cli/src/utils/loadIgnorePatterns.ts +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import * as path from 'node:path'; -import { GitIgnoreParser } from '@gemini-cli/core'; - -const GEMINI_IGNORE_FILE_NAME = '.geminiignore'; - -/** - * Loads and parses a .geminiignore file from the given workspace root. - * The .geminiignore file follows a format similar to .gitignore. - * - * @param workspaceRoot The absolute path to the workspace root where the .geminiignore file is expected. - * @returns An array of glob patterns extracted from the .geminiignore file. Returns an empty array - * if the file does not exist or contains no valid patterns. - */ -export async function loadGeminiIgnorePatterns( - workspaceRoot: string, -): Promise<string[]> { - const parser = new GitIgnoreParser(workspaceRoot); - - try { - await parser.loadPatterns(GEMINI_IGNORE_FILE_NAME); - } catch (error: unknown) { - const ignoreFilePath = path.join(workspaceRoot, GEMINI_IGNORE_FILE_NAME); - if ( - error instanceof Error && - 'code' in error && - typeof error.code === 'string' - ) { - if (error.code === 'ENOENT') { - // .geminiignore not found, which is fine. - } else { - // Other error reading the file (e.g., permissions) - console.warn( - `[WARN] Could not read .geminiignore file at ${ignoreFilePath}: ${error.message}`, - ); - } - } else { - // For other types of errors, or if code is not available - console.warn( - `[WARN] An unexpected error occurred while trying to read ${ignoreFilePath}: ${String(error)}`, - ); - } - } - const loadedPatterns = parser.getPatterns(); - if (loadedPatterns.length > 0) { - console.log( - `[INFO] Loaded ${loadedPatterns.length} patterns from .geminiignore`, - ); - } - return loadedPatterns; -} |
