perf(test): reuse unit-fast discovery analysis
Some checks are pending
CI / runner-admission (push) Waiting to run
CI / preflight (push) Blocked by required conditions
CI / security-fast (push) Blocked by required conditions
CI / pnpm-store-warmup (push) Blocked by required conditions
CI / build-artifacts (push) Blocked by required conditions
CI / native-i18n (push) Blocked by required conditions
CI / (push) Blocked by required conditions
CI / -1 (push) Blocked by required conditions
CI / -2 (push) Blocked by required conditions
CI / checks-node-compat-node22 (push) Blocked by required conditions
CI / -3 (push) Blocked by required conditions
CI / check-bundled-channel-config-metadata (push) Blocked by required conditions
CI / check-dependencies (push) Blocked by required conditions
CI / check-guards (push) Blocked by required conditions
CI / check-lint (push) Blocked by required conditions
CI / check-prod-types (push) Blocked by required conditions
CI / check-shrinkwrap (push) Blocked by required conditions
CI / check-test-types (push) Blocked by required conditions
CI / check-additional-boundaries-a (push) Blocked by required conditions
CI / check-additional-boundaries-bcd (push) Blocked by required conditions
CI / check-additional-extension-bundled (push) Blocked by required conditions
CI / check-additional-extension-channels (push) Blocked by required conditions
CI / check-additional-extension-package-boundary (push) Blocked by required conditions
CI / check-additional-runtime-topology-architecture (push) Blocked by required conditions
CI / check-session-accessor-boundary (push) Blocked by required conditions
CI / check-session-transcript-reader-boundary (push) Blocked by required conditions
CI / check-docs (push) Blocked by required conditions
CI / skills-python (push) Blocked by required conditions
CI / -4 (push) Blocked by required conditions
CI / -5 (push) Blocked by required conditions
CI / macos-swift (push) Blocked by required conditions
CI / ios-build (push) Blocked by required conditions
CI / -6 (push) Blocked by required conditions
CI / ci-timings-summary (push) Blocked by required conditions
ClawSweeper Dispatch / dispatch (push) Waiting to run
CodeQL / Security High (actions) (push) Waiting to run
CodeQL / Security High (channel-runtime-boundary) (push) Waiting to run
CodeQL / Security High (core-auth-secrets) (push) Waiting to run
CodeQL / Security High (mcp-process-tool-boundary) (push) Waiting to run
CodeQL / Security High (network-ssrf-boundary) (push) Waiting to run
CodeQL / Security High (plugin-trust-boundary) (push) Waiting to run
CodeQL / Security High (process-exec-boundary) (push) Waiting to run
Control UI Locale Refresh / plan (push) Waiting to run
Control UI Locale Refresh / Refresh (push) Blocked by required conditions
Control UI Locale Refresh / Commit control UI locale refresh (push) Blocked by required conditions
Docs Sync Publish Repo / sync-publish-repo (push) Waiting to run
Docs / docs (push) Waiting to run
Native App Locale Refresh / Refresh native ar (push) Waiting to run
Native App Locale Refresh / Refresh native de (push) Waiting to run
Native App Locale Refresh / Refresh native es (push) Waiting to run
Native App Locale Refresh / Refresh native fa (push) Waiting to run
Native App Locale Refresh / Refresh native fr (push) Waiting to run
Native App Locale Refresh / Refresh native hi (push) Waiting to run
Native App Locale Refresh / Refresh native id (push) Waiting to run
Native App Locale Refresh / Refresh native it (push) Waiting to run
Native App Locale Refresh / Refresh native ja-JP (push) Waiting to run
Native App Locale Refresh / Refresh native ko (push) Waiting to run
Native App Locale Refresh / Refresh native nl (push) Waiting to run
Native App Locale Refresh / Refresh native pl (push) Waiting to run
Native App Locale Refresh / Refresh native pt-BR (push) Waiting to run
Native App Locale Refresh / Refresh native ru (push) Waiting to run
Native App Locale Refresh / Refresh native sv (push) Waiting to run
Native App Locale Refresh / Refresh native th (push) Waiting to run
Native App Locale Refresh / Refresh native tr (push) Waiting to run
Native App Locale Refresh / Refresh native uk (push) Waiting to run
Native App Locale Refresh / Refresh native vi (push) Waiting to run
Native App Locale Refresh / Refresh native zh-CN (push) Waiting to run
Native App Locale Refresh / Refresh native zh-TW (push) Waiting to run
Native App Locale Refresh / Commit native locale refresh (push) Blocked by required conditions
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Waiting to run
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Blocked by required conditions
Plugin Init Scaffold Validation / Validate provider scaffold (push) Waiting to run
Plugin NPM Release / preview_plugins_npm (push) Waiting to run
Plugin NPM Release / Validate release publish approval (push) Blocked by required conditions
Plugin NPM Release / preview_plugin_pack (push) Blocked by required conditions
Plugin NPM Release / publish_plugins_npm (push) Blocked by required conditions
Plugin NPM Release / verify_plugins_npm (push) Blocked by required conditions
Workflow Sanity / no-tabs (push) Waiting to run
Workflow Sanity / actionlint (push) Waiting to run
Workflow Sanity / generated-doc-baselines (push) Waiting to run

This commit is contained in:
Peter Steinberger 2026-07-06 02:15:32 -04:00
parent d83ee4c44f
commit 2559c92a25

View file

@ -375,29 +375,69 @@ export function classifyUnitFastTestFileContent(source) {
return reasons;
}
export function collectUnitFastTestCandidates(cwd = process.cwd()) {
const unitFastCandidatesByKey = new Map();
function collectUnitFastCandidates(cwd, scope) {
const cacheKey = `${normalizeRepoPath(cwd)}\0${scope}`;
const cached = unitFastCandidatesByKey.get(cacheKey);
if (cached) {
return cached;
}
const broad = scope === "broad";
const discovered = collectRepoTestFiles(cwd).filter(
(file) =>
matchesAnyGlob(file, unitFastCandidateGlobs) &&
matchesAnyGlob(file, broad ? broadUnitFastCandidateGlobs : unitFastCandidateGlobs) &&
!matchesAnyGlob(file, broadUnitFastCandidateSkipGlobs),
);
return [
const candidates = [
...new Set([...discovered, ...unitFastCandidateExactFiles, ...forcedUnitFastTestFiles]),
].toSorted((a, b) => a.localeCompare(b));
// Candidate discovery is immutable for the lifetime of a Vitest/audit process.
unitFastCandidatesByKey.set(cacheKey, candidates);
return candidates;
}
export function collectUnitFastTestCandidates(cwd = process.cwd()) {
return collectUnitFastCandidates(cwd, "default");
}
export function collectBroadUnitFastTestCandidates(cwd = process.cwd()) {
const discovered = collectRepoTestFiles(cwd).filter(
(file) =>
matchesAnyGlob(file, broadUnitFastCandidateGlobs) &&
!matchesAnyGlob(file, broadUnitFastCandidateSkipGlobs),
);
return [
...new Set([...discovered, ...unitFastCandidateExactFiles, ...forcedUnitFastTestFiles]),
].toSorted((a, b) => a.localeCompare(b));
return collectUnitFastCandidates(cwd, "broad");
}
const unitFastAnalysisByKey = new Map();
const unitFastFileAnalysisByKey = new Map();
function analyzeUnitFastTestFile(cwd, file) {
const cacheKey = `${normalizeRepoPath(cwd)}\0${file}`;
const cached = unitFastFileAnalysisByKey.get(cacheKey);
if (cached) {
return cached;
}
let analysis;
try {
const source = fs.readFileSync(path.join(cwd, file), "utf8");
const reasons = classifyUnitFastTestFileContent(source);
const forced = forcedUnitFastTestFileSet.has(file);
analysis = {
file,
unitFast: forced || reasons.length === 0,
forced,
reasons,
};
} catch {
analysis = {
file,
unitFast: false,
reasons: ["missing-file"],
};
}
// Discovery is a process-start snapshot; default and broad audits overlap heavily.
unitFastFileAnalysisByKey.set(cacheKey, analysis);
return analysis;
}
export function collectUnitFastTestFileAnalysis(cwd = process.cwd(), options = {}) {
const cacheKey = `${normalizeRepoPath(cwd)}\0${options.scope ?? "default"}`;
@ -409,27 +449,7 @@ export function collectUnitFastTestFileAnalysis(cwd = process.cwd(), options = {
options.scope === "broad"
? collectBroadUnitFastTestCandidates(cwd)
: collectUnitFastTestCandidates(cwd);
const analysis = candidates.map((file) => {
const absolutePath = path.join(cwd, file);
let source;
try {
source = fs.readFileSync(absolutePath, "utf8");
} catch {
return {
file,
unitFast: false,
reasons: ["missing-file"],
};
}
const reasons = classifyUnitFastTestFileContent(source);
const forced = forcedUnitFastTestFileSet.has(file);
return {
file,
unitFast: forced || reasons.length === 0,
forced,
reasons,
};
});
const analysis = candidates.map((file) => analyzeUnitFastTestFile(cwd, file));
unitFastAnalysisByKey.set(cacheKey, analysis);
return analysis;
}
@ -438,7 +458,6 @@ let cachedUnitFastTestFiles = null;
let cachedUnitFastTestFileSet = null;
let cachedUnitFastTimerTestFiles = null;
let cachedUnitFastTimerTestFileSet = null;
const cachedSingleUnitFastTestFileResults = new Map();
export function getUnitFastTestFiles() {
if (cachedUnitFastTestFiles !== null) {
@ -478,29 +497,10 @@ function getUnitFastTimerTestFileSet() {
function isUnitFastTestFileOnDemand(file, cwd = process.cwd()) {
const normalized = normalizeRepoPath(file);
const cacheKey = `${normalizeRepoPath(cwd)}\0${normalized}`;
if (cachedSingleUnitFastTestFileResults.has(cacheKey)) {
return cachedSingleUnitFastTestFileResults.get(cacheKey);
}
if (!isUnitFastCandidateFile(normalized)) {
cachedSingleUnitFastTestFileResults.set(cacheKey, false);
return false;
}
let source;
try {
source = fs.readFileSync(path.join(cwd, normalized), "utf8");
} catch {
cachedSingleUnitFastTestFileResults.set(cacheKey, false);
return false;
}
const result =
forcedUnitFastTestFileSet.has(normalized) ||
classifyUnitFastTestFileContent(source).length === 0;
cachedSingleUnitFastTestFileResults.set(cacheKey, result);
return result;
return analyzeUnitFastTestFile(cwd, normalized).unitFast;
}
export function isUnitFastTestFile(file) {