

















@@ -33,6 +33,10 @@ function readJson(relativePath) {
3333return JSON.parse(fs.readFileSync(path.join(ROOT, relativePath), "utf8"));
3434}
353536+function readJsonPath(filePath) {
37+return JSON.parse(fs.readFileSync(filePath, "utf8"));
38+}
39+3640function fileExists(relativePath) {
3741return fs.existsSync(path.join(ROOT, relativePath));
3842}
@@ -416,11 +420,8 @@ ${renderTable(records)}
416420`;
417421}
418422419-function collectPluginRecords() {
420-const rootPackageJson = readJson("package.json");
421-const excludedDirs = collectExcludedPackagedExtensionDirs(rootPackageJson);
422-const records = [];
423-423+function collectPluginSourceEntries() {
424+const entries = [];
424425for (const dirName of fs
425426.readdirSync(EXTENSIONS_DIR)
426427.toSorted((left, right) => left.localeCompare(right))) {
@@ -429,9 +430,45 @@ function collectPluginRecords() {
429430if (!fs.existsSync(packagePath) || !fs.existsSync(manifestPath)) {
430431continue;
431432}
432-const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
433-const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
433+const packageJson = readJsonPath(packagePath);
434+const manifest = readJsonPath(manifestPath);
434435const id = typeof manifest.id === "string" && manifest.id ? manifest.id : dirName;
436+entries.push({ dirName, id, manifest, packageJson });
437+}
438+return entries;
439+}
440+441+function validatePluginCoverage(records, sourceEntries) {
442+const expectedIds = sourceEntries
443+.map((entry) => entry.id)
444+.toSorted((left, right) => left.localeCompare(right));
445+const actualIds = records
446+.map((record) => record.id)
447+.toSorted((left, right) => left.localeCompare(right));
448+const missing = expectedIds.filter((id) => !actualIds.includes(id));
449+const extra = actualIds.filter((id) => !expectedIds.includes(id));
450+const duplicateIds = actualIds.filter((id, index) => actualIds.indexOf(id) !== index);
451+if (missing.length > 0 || extra.length > 0 || duplicateIds.length > 0) {
452+throw new Error(
453+[
454+"plugin inventory coverage mismatch",
455+missing.length > 0 ? `missing: ${missing.join(", ")}` : null,
456+extra.length > 0 ? `extra: ${extra.join(", ")}` : null,
457+duplicateIds.length > 0 ? `duplicates: ${duplicateIds.join(", ")}` : null,
458+]
459+.filter(Boolean)
460+.join("; "),
461+);
462+}
463+}
464+465+function collectPluginRecords() {
466+const rootPackageJson = readJson("package.json");
467+const excludedDirs = collectExcludedPackagedExtensionDirs(rootPackageJson);
468+const sourceEntries = collectPluginSourceEntries();
469+const records = [];
470+471+for (const { dirName, id, manifest, packageJson } of sourceEntries) {
435472const status = resolveStatus({ dirName, packageJson, excludedDirs });
436473records.push({
437474description: resolveDescription({ manifest, packageJson }),
@@ -445,6 +482,7 @@ function collectPluginRecords() {
445482});
446483}
447484485+validatePluginCoverage(records, sourceEntries);
448486return records.toSorted((left, right) => left.id.localeCompare(right.id));
449487}
450488此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。