summaryrefslogtreecommitdiff
path: root/packages/core/src/utils/getFolderStructure.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/core/src/utils/getFolderStructure.ts')
-rw-r--r--packages/core/src/utils/getFolderStructure.ts45
1 files changed, 41 insertions, 4 deletions
diff --git a/packages/core/src/utils/getFolderStructure.ts b/packages/core/src/utils/getFolderStructure.ts
index 6d921811..419a9769 100644
--- a/packages/core/src/utils/getFolderStructure.ts
+++ b/packages/core/src/utils/getFolderStructure.ts
@@ -8,6 +8,8 @@ import * as fs from 'fs/promises';
import { Dirent } from 'fs';
import * as path from 'path';
import { getErrorMessage, isNodeError } from './errors.js';
+import { GitIgnoreParser, GitIgnoreFilter } from './gitIgnoreParser.js';
+import { isGitRepository } from './gitUtils.js';
const MAX_ITEMS = 200;
const TRUNCATION_INDICATOR = '...';
@@ -23,13 +25,18 @@ interface FolderStructureOptions {
ignoredFolders?: Set<string>;
/** Optional regex to filter included files by name. */
fileIncludePattern?: RegExp;
+ /** Whether to respect .gitignore patterns. Defaults to true. */
+ respectGitIgnore?: boolean;
+ /** The root of the project, used for gitignore resolution. */
+ projectRoot?: string;
}
// Define a type for the merged options where fileIncludePattern remains optional
type MergedFolderStructureOptions = Required<
- Omit<FolderStructureOptions, 'fileIncludePattern'>
+ Omit<FolderStructureOptions, 'fileIncludePattern' | 'projectRoot'>
> & {
fileIncludePattern?: RegExp;
+ projectRoot?: string;
};
/** Represents the full, unfiltered information about a folder and its contents. */
@@ -52,6 +59,7 @@ interface FullFolderInfo {
async function readFullStructure(
rootPath: string,
options: MergedFolderStructureOptions,
+ gitIgnoreFilter: GitIgnoreFilter | null,
): Promise<FullFolderInfo | null> {
const rootName = path.basename(rootPath);
const rootNode: FullFolderInfo = {
@@ -119,6 +127,12 @@ async function readFullStructure(
break;
}
const fileName = entry.name;
+ const filePath = path.join(currentPath, fileName);
+ if (gitIgnoreFilter) {
+ if (gitIgnoreFilter.isIgnored(filePath)) {
+ continue;
+ }
+ }
if (
!options.fileIncludePattern ||
options.fileIncludePattern.test(fileName)
@@ -148,7 +162,14 @@ async function readFullStructure(
const subFolderName = entry.name;
const subFolderPath = path.join(currentPath, subFolderName);
- if (options.ignoredFolders.has(subFolderName)) {
+ let isIgnoredByGit = false;
+ if (gitIgnoreFilter) {
+ if (gitIgnoreFilter.isIgnored(subFolderPath)) {
+ isIgnoredByGit = true;
+ }
+ }
+
+ if (options.ignoredFolders.has(subFolderName) || isIgnoredByGit) {
const ignoredSubFolder: FullFolderInfo = {
name: subFolderName,
path: subFolderPath,
@@ -275,11 +296,26 @@ export async function getFolderStructure(
maxItems: options?.maxItems ?? MAX_ITEMS,
ignoredFolders: options?.ignoredFolders ?? DEFAULT_IGNORED_FOLDERS,
fileIncludePattern: options?.fileIncludePattern,
+ respectGitIgnore: options?.respectGitIgnore ?? true,
+ projectRoot: options?.projectRoot ?? resolvedPath,
};
+ let gitIgnoreFilter: GitIgnoreFilter | null = null;
+ if (mergedOptions.respectGitIgnore && mergedOptions.projectRoot) {
+ if (isGitRepository(mergedOptions.projectRoot)) {
+ const parser = new GitIgnoreParser(mergedOptions.projectRoot);
+ await parser.initialize();
+ gitIgnoreFilter = parser;
+ }
+ }
+
try {
// 1. Read the structure using BFS, respecting maxItems
- const structureRoot = await readFullStructure(resolvedPath, mergedOptions);
+ const structureRoot = await readFullStructure(
+ resolvedPath,
+ mergedOptions,
+ gitIgnoreFilter,
+ );
if (!structureRoot) {
return `Error: Could not read directory "${resolvedPath}". Check path and permissions.`;
@@ -317,7 +353,8 @@ export async function getFolderStructure(
const summary =
`Showing up to ${mergedOptions.maxItems} items (files + folders). ${disclaimer}`.trim();
- return `${summary}\n\n${displayPath}/\n${structureLines.join('\n')}`;
+ const output = `${summary}\n\n${displayPath}/\n${structureLines.join('\n')}`;
+ return output;
} catch (error: unknown) {
console.error(`Error getting folder structure for ${resolvedPath}:`, error);
return `Error processing directory "${resolvedPath}": ${getErrorMessage(error)}`;