Skip to content

Commit c320da7

Browse files
committed
fix(test): avoid scanning extension ids
1 parent c8cee2d commit c320da7

2 files changed

Lines changed: 72 additions & 6 deletions

File tree

scripts/lib/changed-extensions.mjs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,19 @@ function listChangedPaths(base, head = "HEAD") {
7070
.filter((line) => line.length > 0);
7171
}
7272

73-
function hasExtensionPackage(extensionId) {
74-
return fs.existsSync(path.join(repoRoot, BUNDLED_PLUGIN_ROOT_DIR, extensionId, "package.json"));
73+
function listAvailableExtensionIdsFromGit() {
74+
const packageFiles = runGit(["ls-files", "--", `:(glob)${BUNDLED_PLUGIN_PATH_PREFIX}*/package.json`])
75+
.split("\n")
76+
.map((line) => normalizeRelative(line.trim()))
77+
.filter((line) => line.length > 0);
78+
return packageFiles
79+
.map((file) => file.match(new RegExp(`^${BUNDLED_PLUGIN_PATH_PREFIX}([^/]+)/package\\.json$`)))
80+
.filter((match) => match)
81+
.map((match) => match[1])
82+
.toSorted((left, right) => left.localeCompare(right));
7583
}
7684

77-
export function listAvailableExtensionIds() {
85+
function listAvailableExtensionIdsFromDirectory() {
7886
const extensionsDir = path.join(repoRoot, BUNDLED_PLUGIN_ROOT_DIR);
7987
if (!fs.existsSync(extensionsDir)) {
8088
return [];
@@ -84,11 +92,22 @@ export function listAvailableExtensionIds() {
8492
.readdirSync(extensionsDir, { withFileTypes: true })
8593
.filter((entry) => entry.isDirectory())
8694
.map((entry) => entry.name)
87-
.filter((extensionId) => hasExtensionPackage(extensionId))
95+
.filter((extensionId) =>
96+
fs.existsSync(path.join(repoRoot, BUNDLED_PLUGIN_ROOT_DIR, extensionId, "package.json")),
97+
)
8898
.toSorted((left, right) => left.localeCompare(right));
8999
}
90100

101+
export function listAvailableExtensionIds() {
102+
try {
103+
return listAvailableExtensionIdsFromGit();
104+
} catch {
105+
return listAvailableExtensionIdsFromDirectory();
106+
}
107+
}
108+
91109
export function detectChangedExtensionIds(changedPaths) {
110+
const availableExtensionIds = new Set(listAvailableExtensionIds());
92111
const extensionIds = new Set();
93112

94113
for (const rawPath of changedPaths) {
@@ -102,14 +121,14 @@ export function detectChangedExtensionIds(changedPaths) {
102121
);
103122
if (extensionMatch) {
104123
const extensionId = extensionMatch[1];
105-
if (hasExtensionPackage(extensionId)) {
124+
if (availableExtensionIds.has(extensionId)) {
106125
extensionIds.add(extensionId);
107126
}
108127
continue;
109128
}
110129

111130
const pairedCoreMatch = relativePath.match(/^src\/([^/]+)(?:\/|$)/);
112-
if (pairedCoreMatch && hasExtensionPackage(pairedCoreMatch[1])) {
131+
if (pairedCoreMatch && availableExtensionIds.has(pairedCoreMatch[1])) {
113132
extensionIds.add(pairedCoreMatch[1]);
114133
}
115134
}

test/scripts/test-extension.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,53 @@ describe("scripts/test-extension.mjs", () => {
252252
);
253253
});
254254

255+
it("lists available extension ids from git without reading extension directories", () => {
256+
const output = execFileSync(
257+
process.execPath,
258+
[
259+
"--input-type=module",
260+
"--eval",
261+
`
262+
import fs from "node:fs";
263+
import { syncBuiltinESMExports } from "node:module";
264+
const counts = { existsSync: 0, readdirSync: 0 };
265+
const originalExistsSync = fs.existsSync;
266+
const originalReaddirSync = fs.readdirSync;
267+
fs.existsSync = (...args) => {
268+
counts.existsSync += 1;
269+
return originalExistsSync(...args);
270+
};
271+
fs.readdirSync = (...args) => {
272+
counts.readdirSync += 1;
273+
return originalReaddirSync(...args);
274+
};
275+
syncBuiltinESMExports();
276+
const { detectChangedExtensionIds, listAvailableExtensionIds } = await import("./scripts/lib/changed-extensions.mjs");
277+
const ids = listAvailableExtensionIds();
278+
const changed = detectChangedExtensionIds([
279+
"extensions/slack/src/channel.ts",
280+
"src/line/message.test.ts",
281+
"extensions/not-real/package.json",
282+
]);
283+
console.log(JSON.stringify({ changed, counts, ids: ids.length }));
284+
`,
285+
],
286+
{
287+
cwd: process.cwd(),
288+
encoding: "utf8",
289+
},
290+
);
291+
292+
const payload = JSON.parse(output) as {
293+
changed: string[];
294+
counts: { existsSync: number; readdirSync: number };
295+
ids: number;
296+
};
297+
expect(payload.changed).toEqual(["line", "slack"]);
298+
expect(payload.ids).toBeGreaterThan(0);
299+
expect(payload.counts).toEqual({ existsSync: 0, readdirSync: 0 });
300+
});
301+
255302
it("can fail safe to all extensions when the base revision is unavailable", () => {
256303
const extensionIds = listChangedExtensionIds({
257304
base: "refs/heads/openclaw-test-missing-base",

0 commit comments

Comments
 (0)