fix(test): avoid scanning extension ids

This commit is contained in:
Vincent Koc
2026-05-16 09:08:14 +08:00
parent c8cee2dce4
commit c320da79ed
2 changed files with 72 additions and 6 deletions

View File

@@ -70,11 +70,19 @@ function listChangedPaths(base, head = "HEAD") {
.filter((line) => line.length > 0);
}
function hasExtensionPackage(extensionId) {
return fs.existsSync(path.join(repoRoot, BUNDLED_PLUGIN_ROOT_DIR, extensionId, "package.json"));
function listAvailableExtensionIdsFromGit() {
const packageFiles = runGit(["ls-files", "--", `:(glob)${BUNDLED_PLUGIN_PATH_PREFIX}*/package.json`])
.split("\n")
.map((line) => normalizeRelative(line.trim()))
.filter((line) => line.length > 0);
return packageFiles
.map((file) => file.match(new RegExp(`^${BUNDLED_PLUGIN_PATH_PREFIX}([^/]+)/package\\.json$`)))
.filter((match) => match)
.map((match) => match[1])
.toSorted((left, right) => left.localeCompare(right));
}
export function listAvailableExtensionIds() {
function listAvailableExtensionIdsFromDirectory() {
const extensionsDir = path.join(repoRoot, BUNDLED_PLUGIN_ROOT_DIR);
if (!fs.existsSync(extensionsDir)) {
return [];
@@ -84,11 +92,22 @@ export function listAvailableExtensionIds() {
.readdirSync(extensionsDir, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.filter((extensionId) => hasExtensionPackage(extensionId))
.filter((extensionId) =>
fs.existsSync(path.join(repoRoot, BUNDLED_PLUGIN_ROOT_DIR, extensionId, "package.json")),
)
.toSorted((left, right) => left.localeCompare(right));
}
export function listAvailableExtensionIds() {
try {
return listAvailableExtensionIdsFromGit();
} catch {
return listAvailableExtensionIdsFromDirectory();
}
}
export function detectChangedExtensionIds(changedPaths) {
const availableExtensionIds = new Set(listAvailableExtensionIds());
const extensionIds = new Set();
for (const rawPath of changedPaths) {
@@ -102,14 +121,14 @@ export function detectChangedExtensionIds(changedPaths) {
);
if (extensionMatch) {
const extensionId = extensionMatch[1];
if (hasExtensionPackage(extensionId)) {
if (availableExtensionIds.has(extensionId)) {
extensionIds.add(extensionId);
}
continue;
}
const pairedCoreMatch = relativePath.match(/^src\/([^/]+)(?:\/|$)/);
if (pairedCoreMatch && hasExtensionPackage(pairedCoreMatch[1])) {
if (pairedCoreMatch && availableExtensionIds.has(pairedCoreMatch[1])) {
extensionIds.add(pairedCoreMatch[1]);
}
}

View File

@@ -252,6 +252,53 @@ describe("scripts/test-extension.mjs", () => {
);
});
it("lists available extension ids from git without reading extension directories", () => {
const output = execFileSync(
process.execPath,
[
"--input-type=module",
"--eval",
`
import fs from "node:fs";
import { syncBuiltinESMExports } from "node:module";
const counts = { existsSync: 0, readdirSync: 0 };
const originalExistsSync = fs.existsSync;
const originalReaddirSync = fs.readdirSync;
fs.existsSync = (...args) => {
counts.existsSync += 1;
return originalExistsSync(...args);
};
fs.readdirSync = (...args) => {
counts.readdirSync += 1;
return originalReaddirSync(...args);
};
syncBuiltinESMExports();
const { detectChangedExtensionIds, listAvailableExtensionIds } = await import("./scripts/lib/changed-extensions.mjs");
const ids = listAvailableExtensionIds();
const changed = detectChangedExtensionIds([
"extensions/slack/src/channel.ts",
"src/line/message.test.ts",
"extensions/not-real/package.json",
]);
console.log(JSON.stringify({ changed, counts, ids: ids.length }));
`,
],
{
cwd: process.cwd(),
encoding: "utf8",
},
);
const payload = JSON.parse(output) as {
changed: string[];
counts: { existsSync: number; readdirSync: number };
ids: number;
};
expect(payload.changed).toEqual(["line", "slack"]);
expect(payload.ids).toBeGreaterThan(0);
expect(payload.counts).toEqual({ existsSync: 0, readdirSync: 0 });
});
it("can fail safe to all extensions when the base revision is unavailable", () => {
const extensionIds = listChangedExtensionIds({
base: "refs/heads/openclaw-test-missing-base",