check / scan: project walks skip dot folders, worktrees and git-ignored output, no stat per entry (244 s -> 46 s on a big game repo)

This commit is contained in:
CRTkafa 2026-10-29 17:29:28 +07:00
parent f2d7beb7ce
commit 164ba390dd
6 changed files with 106 additions and 30 deletions

View file

@ -3,8 +3,9 @@
// folders (package.json "workspaces", npm / yarn / pnpm-style array or { packages }, as Bun reads them) and local
// SwiftPM packages (`.package(path:)` in a Package.swift, e.g. Capacitor 8's CapApp-SPM). Used by `privacy-manifest`
// and `scan`. Read-only; never throws.
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from 'node:fs';
import { type Dirent, existsSync, readdirSync, readFileSync, realpathSync, statSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { skipDir } from './walk-skip';
interface PkgJson { name?: string; dependencies?: Record<string, string>; workspaces?: string[] | { packages?: string[] } }
const readJson = (p: string): PkgJson | null => { try { return JSON.parse(readFileSync(p, 'utf8')) as PkgJson; } catch { return null; } };
@ -67,9 +68,10 @@ export function localSwiftPackages(dir: string): string[] {
const skip = new Set(['Pods', 'build', 'DerivedData', 'node_modules', '.build', 'SourcePackages', '.git', 'xcuserdata']);
const walk = (d: string, depth: number) => {
if (depth > 4) return;
let names: string[] = [];
try { names = readdirSync(d); } catch { return; }
for (const n of names) {
let ents: Dirent[] = [];
try { ents = readdirSync(d, { withFileTypes: true }); } catch { return; }
for (const e of ents) {
const n = e.name;
if (skip.has(n)) continue;
const p = join(d, n);
if (n === 'Package.swift') {
@ -79,7 +81,7 @@ export function localSwiftPackages(dir: string): string[] {
const target = resolve(d, m[1]!);
if (isDir(target)) out.push(target);
}
} else if (isDir(p) && !/\.(xc)?framework$|\.xcassets$/.test(n)) walk(p, depth + 1);
} else if ((e.isDirectory() || (e.isSymbolicLink() && isDir(p))) && !/\.(xc)?framework$|\.xcassets$/.test(n) && !skipDir(dir, p, n)) walk(p, depth + 1);
}
};
walk(dir, 0);