( root: string, limits: ScanCodebaseLimits, signal?: AbortSignal, )
| 79 | } |
| 80 | |
| 81 | async function scanWithGit( |
| 82 | root: string, |
| 83 | limits: ScanCodebaseLimits, |
| 84 | signal?: AbortSignal, |
| 85 | ): Promise<CollectedFiles> { |
| 86 | const { stdout } = await execFileAsync( |
| 87 | 'git', |
| 88 | ['-C', root, 'ls-files', '-co', '--exclude-standard', '-z'], |
| 89 | { encoding: 'buffer', maxBuffer: 1024 * 1024 * 64, signal }, |
| 90 | ); |
| 91 | |
| 92 | throwIfAborted(signal); |
| 93 | const relativePaths = splitNull(stdout); |
| 94 | const files: FeedbackCodebaseFile[] = []; |
| 95 | let exceedsLimit: FeedbackCodebaseLimitExceeded | undefined; |
| 96 | let totalSize = 0; |
| 97 | |
| 98 | for (const relativePath of relativePaths) { |
| 99 | throwIfAborted(signal); |
| 100 | if (files.length >= limits.maxFiles) { |
| 101 | exceedsLimit = { reason: 'file-count', limit: limits.maxFiles }; |
| 102 | break; |
| 103 | } |
| 104 | if (isSensitivePath(relativePath)) continue; |
| 105 | const file = await statFile(root, relativePath); |
| 106 | if (file) { |
| 107 | if (file.size > limits.maxFileSize) continue; |
| 108 | if (totalSize + file.size > limits.maxArchiveSize) { |
| 109 | exceedsLimit = { reason: 'total-size', limit: limits.maxArchiveSize }; |
| 110 | break; |
| 111 | } |
| 112 | files.push(file); |
| 113 | totalSize += file.size; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | return { files, exceedsLimit }; |
| 118 | } |
| 119 | |
| 120 | async function scanWithoutFilter( |
| 121 | root: string, |
no test coverage detected