Skip to content

Commit 2ca160a

Browse files
frankieyanclaude
andcommitted
feat: Add filterByGlob to validate file paths against sourceGlob
Explicit file lists from --stage-record-file and --check-files are now filtered against the sourceGlob config, ensuring only matching files are processed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 87978e0 commit 2ca160a

3 files changed

Lines changed: 47 additions & 4 deletions

File tree

src/index.mts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ async function main() {
4343
switch (flag) {
4444
case STAGE_RECORD_FILE_FLAG: {
4545
const filePathParams = process.argv.slice(3)
46-
const filePaths = sourceFiles.normalizeFilePaths(filePathParams)
46+
const filePaths = sourceFiles.filterByGlob({
47+
filePaths: sourceFiles.normalizeFilePaths(filePathParams),
48+
globPattern: config.sourceGlob,
49+
})
4750

4851
return await runStageRecords({
4952
filePaths,
@@ -58,7 +61,10 @@ async function main() {
5861
}
5962
case CHECK_FILES_FLAG: {
6063
const filePathParams = process.argv.slice(3)
61-
const filePaths = sourceFiles.normalizeFilePaths(filePathParams)
64+
const filePaths = sourceFiles.filterByGlob({
65+
filePaths: sourceFiles.normalizeFilePaths(filePathParams),
66+
globPattern: config.sourceGlob,
67+
})
6268

6369
return await runCheckFiles({ filePaths, recordsFilePath: config.recordsFile })
6470
}

src/source-files.mts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { execSync } from 'node:child_process'
22
import { relative } from 'node:path'
33
import { glob } from 'glob'
4+
import { minimatch } from 'minimatch'
45

56
function getAll({ globPattern }: { globPattern: string }) {
67
return glob.sync(globPattern, {
@@ -63,4 +64,11 @@ function normalizeFilePaths(filePaths: string[]) {
6364
})
6465
}
6566

66-
export { getAll, normalizeFilePaths }
67+
/**
68+
* Filters file paths to only include those matching the glob pattern.
69+
*/
70+
function filterByGlob({ filePaths, globPattern }: { filePaths: string[]; globPattern: string }) {
71+
return filePaths.filter((filePath) => minimatch(filePath, globPattern))
72+
}
73+
74+
export { getAll, normalizeFilePaths, filterByGlob }

src/source-files.test.mts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { execSync } from 'node:child_process'
22
import { glob } from 'glob'
33
import { afterEach, describe, expect, it, vi } from 'vitest'
4-
import { getAll, normalizeFilePaths } from './source-files.mjs'
4+
import { filterByGlob, getAll, normalizeFilePaths } from './source-files.mjs'
55

66
vi.mock('node:child_process', () => ({
77
execSync: vi.fn(),
@@ -123,3 +123,32 @@ describe('normalizeFilePaths', () => {
123123
expect(result).toEqual(['src/App.tsx', 'src/local.ts'])
124124
})
125125
})
126+
127+
describe('filterByGlob', () => {
128+
it('filters paths matching the glob pattern', () => {
129+
const result = filterByGlob({
130+
filePaths: ['src/App.tsx', 'src/utils.ts', 'package.json', 'README.md'],
131+
globPattern: 'src/**/*.{ts,tsx}',
132+
})
133+
134+
expect(result).toEqual(['src/App.tsx', 'src/utils.ts'])
135+
})
136+
137+
it('returns empty array when no paths match', () => {
138+
const result = filterByGlob({
139+
filePaths: ['package.json', 'README.md'],
140+
globPattern: 'src/**/*.{ts,tsx}',
141+
})
142+
143+
expect(result).toEqual([])
144+
})
145+
146+
it('returns all paths when all match', () => {
147+
const result = filterByGlob({
148+
filePaths: ['src/a.ts', 'src/b.tsx'],
149+
globPattern: 'src/**/*.{ts,tsx}',
150+
})
151+
152+
expect(result).toEqual(['src/a.ts', 'src/b.tsx'])
153+
})
154+
})

0 commit comments

Comments
 (0)