@masuidrive/bloom-local-rag
Version:
RAG (Retrieval-Augmented Generation) system for local directories - Index and search your documents with AI-powered answers
88 lines • 3 kB
JavaScript
import { readFile, access } from 'fs/promises';
import { join, dirname, relative } from 'path';
import ignore from 'ignore';
/**
* Find the root of a git repository by looking for .git directory
*/
async function findGitRoot(startPath) {
let currentPath = startPath;
while (currentPath !== dirname(currentPath)) { // Stop at filesystem root
try {
await access(join(currentPath, '.git'));
return currentPath;
}
catch {
// .git not found, continue searching
}
currentPath = dirname(currentPath);
}
return null;
}
/**
* Load all .gitignore files from startPath up to git root (or filesystem root)
* Returns them in order from root to startPath (parent to child)
*/
async function loadGitignoreHierarchy(startPath) {
const gitignores = [];
const gitRoot = await findGitRoot(startPath);
const stopPath = gitRoot || dirname(startPath); // Stop at git root or parent of startPath
// Collect all paths from startPath to stopPath
const paths = [];
let currentPath = startPath;
while (currentPath.startsWith(stopPath) && currentPath !== dirname(currentPath)) {
paths.push(currentPath);
if (currentPath === stopPath)
break;
currentPath = dirname(currentPath);
}
// Load .gitignore files in reverse order (root to child)
for (const path of paths.reverse()) {
try {
const gitignorePath = join(path, '.gitignore');
const content = await readFile(gitignorePath, 'utf-8');
const ig = ignore();
ig.add(content);
gitignores.push({ path, ig });
}
catch {
// No .gitignore in this directory, continue
}
}
return gitignores;
}
/**
* Create a combined gitignore checker that respects the hierarchy
*/
export async function createGitignoreChecker(directory) {
const gitignores = await loadGitignoreHierarchy(directory);
return (filePath) => {
// Check each .gitignore from root to child
for (const { path: gitignorePath, ig } of gitignores) {
// Calculate the relative path from the .gitignore location
const relativeFromGitignore = relative(gitignorePath, join(directory, filePath));
// Only check if the file is within or below the .gitignore's directory
if (!relativeFromGitignore.startsWith('..')) {
if (ig.ignores(relativeFromGitignore)) {
return true;
}
}
}
return false;
};
}
/**
* Legacy function for backward compatibility
*/
export async function loadGitignore(directory) {
try {
const gitignorePath = join(directory, '.gitignore');
const content = await readFile(gitignorePath, 'utf-8');
const ig = ignore();
ig.add(content);
return ig;
}
catch {
return null;
}
}
//# sourceMappingURL=gitignore.js.map