




















@@ -1,4 +1,5 @@
11#!/usr/bin/env node
2+import { spawnSync } from "node:child_process";
23import fs from "node:fs";
34import path from "node:path";
45import { fileURLToPath } from "node:url";
@@ -64,13 +65,83 @@ function walkFiles(rootDir) {
6465}
65666667export function collectAllLiveTestFiles(repoRoot = process.cwd()) {
68+const externalFiles = listExternalLiveTestFiles(repoRoot);
69+if (externalFiles) {
70+return externalFiles;
71+}
6772return ["src", "test", "extensions"]
6873.flatMap((dir) => walkFiles(path.join(repoRoot, dir)))
6974.map((file) => path.relative(repoRoot, file).split(path.sep).join("/"))
7075.filter((file) => file.endsWith(LIVE_TEST_SUFFIX))
7176.toSorted((a, b) => a.localeCompare(b));
7277}
737879+function listExternalLiveTestFiles(repoRoot) {
80+return listGitLiveTestFiles(repoRoot) ?? listFindLiveTestFiles(repoRoot);
81+}
82+83+function listGitLiveTestFiles(repoRoot) {
84+const result = spawnSync("git", ["ls-files", "--", "src", "test", "extensions"], {
85+cwd: repoRoot,
86+encoding: "utf8",
87+maxBuffer: 1024 * 1024 * 4,
88+stdio: ["ignore", "pipe", "ignore"],
89+});
90+if (result.status !== 0) {
91+return null;
92+}
93+return result.stdout
94+.split("\n")
95+.map((line) => line.trim())
96+.filter((file) => file.endsWith(LIVE_TEST_SUFFIX))
97+.toSorted((a, b) => a.localeCompare(b));
98+}
99+100+function listFindLiveTestFiles(repoRoot) {
101+const roots = ["src", "test", "extensions"].map((dir) => path.join(repoRoot, dir));
102+const result = spawnSync(
103+"find",
104+[
105+ ...roots,
106+"(",
107+"-name",
108+"node_modules",
109+"-o",
110+"-name",
111+"dist",
112+"-o",
113+"-name",
114+"vendor",
115+"-o",
116+"-name",
117+"fixtures",
118+")",
119+"-prune",
120+"-o",
121+"-type",
122+"f",
123+"-name",
124+`*${LIVE_TEST_SUFFIX}`,
125+"-print",
126+],
127+{
128+cwd: repoRoot,
129+encoding: "utf8",
130+maxBuffer: 1024 * 1024 * 4,
131+stdio: ["ignore", "pipe", "ignore"],
132+},
133+);
134+if (result.status !== 0) {
135+return null;
136+}
137+return result.stdout
138+.split("\n")
139+.map((line) => line.trim())
140+.filter((file) => file.length > 0)
141+.map((file) => path.relative(repoRoot, file).split(path.sep).join("/"))
142+.toSorted((a, b) => a.localeCompare(b));
143+}
144+74145function extensionKey(file) {
75146const relative = file.slice("extensions/".length);
76147return relative.split("/", 1)[0]?.toLowerCase() ?? "";
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。