Intermediate still contains errors, but an attempt to solve filtering as per .gitignore

This commit is contained in:
2025-03-12 15:05:52 +00:00
parent c18e4dac10
commit 2df0dc666b
5 changed files with 629 additions and 345 deletions

View File

@@ -1,6 +1,26 @@
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
// Use require for ignore package with proper fallback
let ignoreFunc: () => any;
try {
const ignoreModule = require('ignore');
if (typeof ignoreModule === 'function') {
ignoreFunc = ignoreModule;
} else if (ignoreModule && typeof ignoreModule.default === 'function') {
ignoreFunc = ignoreModule.default;
} else {
throw new Error('Ignore module is neither a function nor has a default function');
}
console.log('Successfully loaded ignore function in FileSelectionManager');
} catch (error) {
console.error('Error loading ignore package in FileSelectionManager:', error);
ignoreFunc = () => ({
add: () => {},
ignores: () => false
});
}
/**
* Manages file selection state for the Prompter extension
@@ -11,40 +31,114 @@ export class FileSelectionManager {
constructor() {}
/**
* Add a file to the selection
* Get the path relative to the workspace root
* @param filePath Absolute file path
* @param rootPath Workspace root path
* @returns Relative path
*/
private getRelativePath(filePath: string, rootPath: string): string {
if (filePath.startsWith(rootPath)) {
const relativePath = filePath.substring(rootPath.length);
return relativePath.startsWith('/') ? relativePath.substring(1) : relativePath;
}
return filePath;
}
/**
* Check if a path or any of its parent directories are ignored
* @param pathToCheck The path to check
* @param ig The ignore instance
* @param workspaceRoot The workspace root path
* @returns True if the path or any parent is ignored
*/
private isPathIgnored(pathToCheck: string, ig: any, workspaceRoot: string): boolean {
let currentPath = pathToCheck;
while (currentPath !== workspaceRoot) {
const relativePath = this.getRelativePath(currentPath, workspaceRoot);
const normalizedPath = relativePath.split(path.sep).join('/');
const isIgnored = ig.ignores(normalizedPath);
console.log(`Checking ${normalizedPath}: ignored = ${isIgnored}`);
if (isIgnored) {
console.log(`Path ${pathToCheck} ignored because parent ${normalizedPath} is ignored`);
return true;
}
currentPath = path.dirname(currentPath);
if (currentPath === workspaceRoot) {
break;
}
}
return false;
}
/**
* Add a file to the selection if it's not ignored
*/
addFile(filePath: string): void {
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath || '';
const ig = ignoreFunc();
try {
const gitignorePath = path.join(workspaceRoot, '.gitignore');
if (fs.existsSync(gitignorePath)) {
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
ig.add(gitignoreContent);
console.log('Loaded .gitignore patterns for file selection');
}
} catch (error) {
console.error('Error loading .gitignore for file selection:', error);
}
if (this.isPathIgnored(filePath, ig, workspaceRoot)) {
console.log(`Ignoring file ${filePath} because it or a parent directory is ignored`);
return;
}
this.selectedFiles.add(filePath);
console.log(`Added ${filePath} to selection`);
}
/**
* Add a directory and all its contents to the selection
* Add a directory and all its non-ignored contents to the selection
*/
async addDirectory(dirPath: string): Promise<void> {
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath || '';
const ig = ignoreFunc();
try {
const gitignorePath = path.join(workspaceRoot, '.gitignore');
if (fs.existsSync(gitignorePath)) {
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
ig.add(gitignoreContent);
console.log('Loaded .gitignore patterns:', gitignoreContent.split('\n').filter(Boolean));
}
} catch (error) {
console.error('Error loading .gitignore:', error);
}
const relativeDirPath = this.getRelativePath(dirPath, workspaceRoot);
const normalizedDirPath = relativeDirPath.split(path.sep).join('/');
if (ig.ignores(normalizedDirPath)) {
console.log(`Directory ${dirPath} is ignored, skipping its contents`);
return;
}
this.selectedFiles.add(dirPath);
console.log(`Added directory ${dirPath} to selection`);
try {
// Add the directory itself
this.selectedFiles.add(dirPath);
console.log(`Added directory ${dirPath} to selection`);
// Read directory contents
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath));
// Process each item
for (const [name, type] of files) {
const filePath = path.join(dirPath, name);
const relativeFilePath = this.getRelativePath(filePath, workspaceRoot);
const normalizedFilePath = relativeFilePath.split(path.sep).join('/');
if (type === vscode.FileType.Directory) {
// Recursively process subdirectories
await this.addDirectory(filePath);
} else {
// Add files
} else if (!ig.ignores(normalizedFilePath)) {
this.selectedFiles.add(filePath);
console.log(`Added ${filePath} to selection (from directory)`);
console.log(`Added ${filePath} to selection`);
} else {
console.log(`Ignoring ${filePath} due to ignore patterns`);
}
}
} catch (error) {
console.error(`Error adding directory to selection: ${dirPath}`, error);
console.error(`Error adding directory ${dirPath}:`, error);
}
}
@@ -61,22 +155,14 @@ export class FileSelectionManager {
*/
async removeDirectory(dirPath: string): Promise<void> {
try {
// Remove the directory itself
this.selectedFiles.delete(dirPath);
console.log(`Removed directory ${dirPath} from selection`);
// Read directory contents
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath));
// Process each item
for (const [name, type] of files) {
const filePath = path.join(dirPath, name);
if (type === vscode.FileType.Directory) {
// Recursively process subdirectories
await this.removeDirectory(filePath);
} else {
// Remove files
this.selectedFiles.delete(filePath);
console.log(`Removed ${filePath} from selection (from directory)`);
}