/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { GitIgnoreParser, GitIgnoreFilter } from '../utils/gitIgnoreParser.js'; import { isGitRepository } from '../utils/gitUtils.js'; import * as path from 'path'; const GEMINI_IGNORE_FILE_NAME = '.geminiignore'; export interface FilterFilesOptions { respectGitIgnore?: boolean; respectGeminiIgnore?: boolean; } export class FileDiscoveryService { private gitIgnoreFilter: GitIgnoreFilter | null = null; private geminiIgnoreFilter: GitIgnoreFilter | null = null; private projectRoot: string; constructor(projectRoot: string) { this.projectRoot = path.resolve(projectRoot); if (isGitRepository(this.projectRoot)) { const parser = new GitIgnoreParser(this.projectRoot); try { parser.loadGitRepoPatterns(); } catch (_error) { // ignore file not found } this.gitIgnoreFilter = parser; } const gParser = new GitIgnoreParser(this.projectRoot); try { gParser.loadPatterns(GEMINI_IGNORE_FILE_NAME); } catch (_error) { // ignore file not found } this.geminiIgnoreFilter = gParser; } /** * Filters a list of file paths based on git ignore rules */ filterFiles( filePaths: string[], options: FilterFilesOptions = { respectGitIgnore: true, respectGeminiIgnore: true, }, ): string[] { return filePaths.filter((filePath) => { if (options.respectGitIgnore && this.shouldGitIgnoreFile(filePath)) { return false; } if ( options.respectGeminiIgnore && this.shouldGeminiIgnoreFile(filePath) ) { return false; } return true; }); } /** * Checks if a single file should be git-ignored */ shouldGitIgnoreFile(filePath: string): boolean { if (this.gitIgnoreFilter) { return this.gitIgnoreFilter.isIgnored(filePath); } return false; } /** * Checks if a single file should be gemini-ignored */ shouldGeminiIgnoreFile(filePath: string): boolean { if (this.geminiIgnoreFilter) { return this.geminiIgnoreFilter.isIgnored(filePath); } return false; } /** * Returns loaded patterns from .geminiignore */ getGeminiIgnorePatterns(): string[] { return this.geminiIgnoreFilter?.getPatterns() ?? []; } }