MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / collectIncludedFiles

Function collectIncludedFiles

src/extraction/index.ts:410–477  ·  view source on GitHub ↗

* Actively discover the source files an `include` whitelist forces in. `git * ls-files` never lists gitignored files, so a filtered filesystem walk of just * the opted-in subtrees (`includeStaticRoots`) is the only way to find them. * Returns project-root-relative, normalized source-file paths.

(
  rootDir: string,
  include: Ignore,
  exclude: Ignore | null,
  roots: string[],
  overrides: Record<string, Language>,
)

Source from the content-addressed store, hash-verified

408 * `.gitignore` is deliberately NOT consulted: overriding it is the whole point.
409 */
410function collectIncludedFiles(
411 rootDir: string,
412 include: Ignore,
413 exclude: Ignore | null,
414 roots: string[],
415 overrides: Record<string, Language>,
416): Set<string> {
417 const out = new Set<string>();
418 const defaults = defaultsOnlyIgnore();
419 const visited = new Set<string>();
420
421 const consider = (abs: string, rel: string, isDir: boolean): void => {
422 if (isDir) {
423 if (defaults.ignores(rel + '/')) return; // never node_modules/dist/… via include
424 // An explicit `exclude` always wins over `include`; prune the whole subtree
425 // here so a large excluded dir (a committed frontend's own vendored deps,
426 // build output, …) is never walked — the per-file guard below still catches
427 // anything a directory pattern doesn't, so this is a pure efficiency win.
428 if (exclude && exclude.ignores(rel + '/')) return;
429 walk(abs);
430 } else {
431 if (defaults.ignores(rel)) return;
432 if (!include.ignores(rel)) return;
433 if (exclude && exclude.ignores(rel)) return;
434 if (!isSourceFile(rel, overrides)) return;
435 out.add(rel);
436 }
437 };
438
439 function walk(absDir: string): void {
440 let realDir: string;
441 try {
442 realDir = fs.realpathSync(absDir);
443 } catch {
444 return;
445 }
446 if (visited.has(realDir)) return; // symlink-cycle guard
447 visited.add(realDir);
448
449 let entries: fs.Dirent[];
450 try {
451 entries = fs.readdirSync(absDir, { withFileTypes: true });
452 } catch {
453 return;
454 }
455 for (const entry of entries) {
456 if (entry.name === '.git' || isCodeGraphDataDir(entry.name)) continue;
457 const abs = path.join(absDir, entry.name);
458 const rel = normalizePath(path.relative(rootDir, abs));
459 if (!rel || rel.startsWith('..')) continue;
460 if (entry.isSymbolicLink()) {
461 try {
462 const st = fs.statSync(fs.realpathSync(abs));
463 consider(abs, rel, st.isDirectory());
464 } catch {
465 // broken symlink — skip
466 }
467 continue;

Callers 1

Calls 3

defaultsOnlyIgnoreFunction · 0.85
walkFunction · 0.70
joinMethod · 0.45

Tested by

no test coverage detected