mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 02:42:43 +00:00
refactor: simplify manifest registry duplicate detection (#16260)
This commit is contained in:
committed by
GitHub
parent
a6fbd0393d
commit
497b060e49
@@ -11,17 +11,25 @@ type SeenIdEntry = {
|
|||||||
recordIndex: number;
|
recordIndex: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
function pluginOriginRank(origin: PluginOrigin): number {
|
// Precedence: config > workspace > global > bundled
|
||||||
// Precedence: config > workspace > global > bundled
|
const PLUGIN_ORIGIN_RANK: Readonly<Record<PluginOrigin, number>> = {
|
||||||
switch (origin) {
|
config: 0,
|
||||||
case "config":
|
workspace: 1,
|
||||||
return 0;
|
global: 2,
|
||||||
case "workspace":
|
bundled: 3,
|
||||||
return 1;
|
};
|
||||||
case "global":
|
|
||||||
return 2;
|
function safeRealpathSync(rootDir: string, cache: Map<string, string>): string | null {
|
||||||
case "bundled":
|
const cached = cache.get(rootDir);
|
||||||
return 3;
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const resolved = fs.realpathSync(rootDir);
|
||||||
|
cache.set(rootDir, resolved);
|
||||||
|
return resolved;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +166,7 @@ export function loadPluginManifestRegistry(params: {
|
|||||||
const candidates: PluginCandidate[] = discovery.candidates;
|
const candidates: PluginCandidate[] = discovery.candidates;
|
||||||
const records: PluginManifestRecord[] = [];
|
const records: PluginManifestRecord[] = [];
|
||||||
const seenIds = new Map<string, SeenIdEntry>();
|
const seenIds = new Map<string, SeenIdEntry>();
|
||||||
|
const realpathCache = new Map<string, string>();
|
||||||
|
|
||||||
for (const candidate of candidates) {
|
for (const candidate of candidates) {
|
||||||
const manifestRes = loadPluginManifest(candidate.rootDir);
|
const manifestRes = loadPluginManifest(candidate.rootDir);
|
||||||
@@ -191,17 +200,13 @@ export function loadPluginManifestRegistry(params: {
|
|||||||
// Check whether both candidates point to the same physical directory
|
// Check whether both candidates point to the same physical directory
|
||||||
// (e.g. via symlinks or different path representations). If so, this
|
// (e.g. via symlinks or different path representations). If so, this
|
||||||
// is a false-positive duplicate and can be silently skipped.
|
// is a false-positive duplicate and can be silently skipped.
|
||||||
let samePlugin = false;
|
const existingReal = safeRealpathSync(existing.candidate.rootDir, realpathCache);
|
||||||
try {
|
const candidateReal = safeRealpathSync(candidate.rootDir, realpathCache);
|
||||||
samePlugin =
|
const samePlugin = Boolean(existingReal && candidateReal && existingReal === candidateReal);
|
||||||
fs.realpathSync(existing.candidate.rootDir) === fs.realpathSync(candidate.rootDir);
|
|
||||||
} catch {
|
|
||||||
// If either path is inaccessible, fall through to duplicate warning
|
|
||||||
}
|
|
||||||
if (samePlugin) {
|
if (samePlugin) {
|
||||||
// Prefer higher-precedence origins even if candidates are passed in
|
// Prefer higher-precedence origins even if candidates are passed in
|
||||||
// an unexpected order (config > workspace > global > bundled).
|
// an unexpected order (config > workspace > global > bundled).
|
||||||
if (pluginOriginRank(candidate.origin) < pluginOriginRank(existing.candidate.origin)) {
|
if (PLUGIN_ORIGIN_RANK[candidate.origin] < PLUGIN_ORIGIN_RANK[existing.candidate.origin]) {
|
||||||
records[existing.recordIndex] = buildRecord({
|
records[existing.recordIndex] = buildRecord({
|
||||||
manifest,
|
manifest,
|
||||||
candidate,
|
candidate,
|
||||||
|
|||||||
Reference in New Issue
Block a user