diff --git a/src/test-utils/runtime-source-guardrail-scan.ts b/src/test-utils/runtime-source-guardrail-scan.ts index a870259fbb0..cb100372682 100644 --- a/src/test-utils/runtime-source-guardrail-scan.ts +++ b/src/test-utils/runtime-source-guardrail-scan.ts @@ -1,3 +1,4 @@ +import { execFileSync } from "node:child_process"; import fs from "node:fs/promises"; import path from "node:path"; import { listRuntimeSourceFiles } from "./repo-scan.js"; @@ -63,21 +64,42 @@ async function readRuntimeSourceFiles( return output.filter((entry): entry is RuntimeSourceGuardrailFile => entry !== undefined); } +function tryListTrackedRuntimeSourceFiles(repoRoot: string): string[] | null { + try { + const stdout = execFileSync("git", ["-C", repoRoot, "ls-files", "--", "src", "extensions"], { + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"], + }); + return stdout + .split(/\r?\n/u) + .filter(Boolean) + .filter((relativePath) => relativePath.endsWith(".ts") || relativePath.endsWith(".tsx")) + .filter((relativePath) => !shouldSkipGuardrailRuntimeSource(relativePath)) + .map((relativePath) => path.join(repoRoot, relativePath)); + } catch { + return null; + } +} + export async function loadRuntimeSourceFilesForGuardrails( repoRoot: string, ): Promise { let pending = runtimeSourceGuardrailCache.get(repoRoot); if (!pending) { pending = (async () => { - const files = await listRuntimeSourceFiles(repoRoot, { - roots: ["src", "extensions"], - extensions: [".ts", ".tsx"], - }); - const filtered = files.filter((absolutePath) => { - const relativePath = path.relative(repoRoot, absolutePath); - return !shouldSkipGuardrailRuntimeSource(relativePath); - }); - return await readRuntimeSourceFiles(repoRoot, filtered); + const trackedFiles = tryListTrackedRuntimeSourceFiles(repoRoot); + const sourceFiles = + trackedFiles ?? + ( + await listRuntimeSourceFiles(repoRoot, { + roots: ["src", "extensions"], + extensions: [".ts", ".tsx"], + }) + ).filter((absolutePath) => { + const relativePath = path.relative(repoRoot, absolutePath); + return !shouldSkipGuardrailRuntimeSource(relativePath); + }); + return await readRuntimeSourceFiles(repoRoot, sourceFiles); })(); runtimeSourceGuardrailCache.set(repoRoot, pending); }