From d65a4c0f6e3242e7d4f90633ec046553d1caf612 Mon Sep 17 00:00:00 2001 From: Ruddy35 <100517632+Ruddy35@users.noreply.github.com> Date: Sun, 7 Sep 2025 14:15:44 +0300 Subject: [PATCH] fix(core): include dotfiles in ignoreContent patterns --- package.json | 1 + src/core/file/fileCollect.ts | 6 ++++-- tests/core/file/fileCollect.test.ts | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 04bff012e..04cbe0a14 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ }, "bin": "./bin/repomix.cjs", "scripts": { + "prepare": "npm run build", "build": "rimraf lib && tsc -p tsconfig.build.json --sourceMap --declaration", "build-bun": "bun run build", "lint": "node --run lint-biome && node --run lint-oxlint && node --run lint-ts && node --run lint-secretlint", diff --git a/src/core/file/fileCollect.ts b/src/core/file/fileCollect.ts index fbb3f631d..70760b5b6 100644 --- a/src/core/file/fileCollect.ts +++ b/src/core/file/fileCollect.ts @@ -4,6 +4,7 @@ import type { RepomixConfigMerged } from '../../config/configSchema.js'; import { logger } from '../../shared/logger.js'; import { initTaskRunner } from '../../shared/processConcurrency.js'; import type { RepomixProgressCallback } from '../../shared/types.js'; +import { normalizeGlobPattern } from './fileSearch.js'; import type { RawFile } from './fileTypes.js'; import type { FileCollectResult, FileCollectTask, SkippedFileInfo } from './workers/fileCollectWorker.js'; @@ -33,11 +34,12 @@ export const collectFiles = async ( const shouldSkipContent = (filePath: string, patterns: string[]): boolean => { let skip = false; for (const pattern of patterns) { + const normalizedPattern = normalizeGlobPattern(pattern.startsWith('!') ? pattern.slice(1) : pattern); if (pattern.startsWith('!')) { - if (minimatch(filePath, pattern.slice(1))) { + if (minimatch(filePath, normalizedPattern, { dot: true })) { skip = false; } - } else if (minimatch(filePath, pattern)) { + } else if (minimatch(filePath, normalizedPattern, { dot: true })) { skip = true; } } diff --git a/tests/core/file/fileCollect.test.ts b/tests/core/file/fileCollect.test.ts index b2ea60ee7..2a23835dc 100644 --- a/tests/core/file/fileCollect.test.ts +++ b/tests/core/file/fileCollect.test.ts @@ -124,6 +124,27 @@ describe('fileCollect', () => { expect(fs.readFile).toHaveBeenCalledTimes(1); }); + it('should match dotfiles when using ignoreContent patterns', async () => { + const mockFilePaths = ['docs/.env', 'docs/readme.md']; + const mockRootDir = '/root'; + const mockConfig = createMockConfig({ ignoreContent: ['docs/**'] }); + + vi.mocked(isBinary).mockReturnValue(false); + vi.mocked(fs.readFile).mockResolvedValue(Buffer.from('file content')); + vi.mocked(jschardet.detect).mockReturnValue({ encoding: 'utf-8', confidence: 0.99 }); + vi.mocked(iconv.decode).mockReturnValue('decoded content'); + + const result = await collectFiles(mockFilePaths, mockRootDir, mockConfig, () => {}, { + initTaskRunner: mockInitTaskRunner, + }); + + expect(result).toEqual({ + rawFiles: [{ path: 'docs/.env' }, { path: 'docs/readme.md' }], + skippedFiles: [], + }); + expect(fs.readFile).not.toHaveBeenCalled(); + }); + it('should skip binary files', async () => { const mockFilePaths = ['binary.bin', 'text.txt']; const mockRootDir = '/root';