fix(test): avoid scanning bundled plugin naming guardrails

This commit is contained in:
Vincent Koc
2026-05-16 14:04:14 +08:00
parent c98ccbe513
commit ae42768e5f

View File

@@ -1,6 +1,7 @@
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
type PluginManifestShape = {
id?: unknown;
@@ -54,10 +55,100 @@ function normalizeText(value: unknown): string | undefined {
return trimmed || undefined;
}
function listBundledPluginDirs(): string[] {
const externalDirs = listExternalBundledPluginDirs();
if (externalDirs) {
return externalDirs;
}
return fs.readdirSync(EXTENSIONS_ROOT).toSorted();
}
function listExternalBundledPluginDirs(): string[] | null {
const files =
listGitPluginMetadataFiles() ??
listFindPluginMetadataFiles();
if (!files) {
return null;
}
const metadataByDir = new Map<string, Set<string>>();
for (const file of files) {
const match = /^extensions\/([^/]+)\/(openclaw\.plugin\.json|package\.json)$/u.exec(file);
if (!match) {
continue;
}
const [, dirName, fileName] = match;
const metadataFiles = metadataByDir.get(dirName) ?? new Set<string>();
metadataFiles.add(fileName);
metadataByDir.set(dirName, metadataFiles);
}
return [...metadataByDir.entries()]
.filter(([, metadataFiles]) =>
metadataFiles.has("package.json") && metadataFiles.has("openclaw.plugin.json"),
)
.map(([dirName]) => dirName)
.toSorted();
}
function listGitPluginMetadataFiles(): string[] | null {
const result = spawnSync(
"git",
["ls-files", "--", "extensions/*/package.json", "extensions/*/openclaw.plugin.json"],
{
cwd: process.cwd(),
encoding: "utf8",
maxBuffer: 1024 * 1024,
stdio: ["ignore", "pipe", "ignore"],
},
);
if (result.status !== 0) {
return null;
}
return result.stdout
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0)
.toSorted();
}
function listFindPluginMetadataFiles(): string[] | null {
const result = spawnSync(
"find",
[
EXTENSIONS_ROOT,
"-maxdepth",
"2",
"-type",
"f",
"(",
"-name",
"package.json",
"-o",
"-name",
"openclaw.plugin.json",
")",
],
{
cwd: process.cwd(),
encoding: "utf8",
maxBuffer: 1024 * 1024,
stdio: ["ignore", "pipe", "ignore"],
},
);
if (result.status !== 0) {
return null;
}
return result.stdout
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0)
.map((file) => path.relative(process.cwd(), file).split(path.sep).join("/"))
.toSorted();
}
function readBundledPluginRecords(): BundledPluginRecord[] {
return fs
.readdirSync(EXTENSIONS_ROOT)
.toSorted()
return listBundledPluginDirs()
.flatMap((dirName) => {
const rootDir = path.join(EXTENSIONS_ROOT, dirName);
const packagePath = path.join(rootDir, "package.json");
@@ -108,6 +199,19 @@ function expectNoBundledPluginNamingMismatches(params: {
}
describe("bundled plugin naming guardrails", () => {
it("lists bundled plugin metadata without scanning extension directories in-process", () => {
const readDir = vi.spyOn(fs, "readdirSync");
try {
const records = readBundledPluginRecords();
expect(records.length).toBeGreaterThan(0);
expect(records.every((record) => record.dirName.length > 0)).toBe(true);
expect(readDir).not.toHaveBeenCalled();
} finally {
readDir.mockRestore();
}
});
it.each([
{
name: "keeps bundled workspace package names anchored to the plugin id",