mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-21 15:31:46 +02:00
fix: declare optional cross-target install dependencies
Carry forward the final scoped delta of PR #3119 at 60e82f95. Keep required dependency closure and select only modules reachable from successful requests; refresh the unchanged 293-skill registry binding.
This commit is contained in:
@@ -123,6 +123,13 @@ function validateInstallManifests() {
|
||||
}
|
||||
}
|
||||
|
||||
for (const dependency of module.optionalDependencies || []) {
|
||||
if (!module.dependencies.includes(dependency)) {
|
||||
console.error(`ERROR: Module ${module.id} optional dependency ${dependency} is not a declared dependency`);
|
||||
hasErrors = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const relativePath of module.paths) {
|
||||
const normalizedPath = normalizeRelativePath(relativePath);
|
||||
const absolutePath = path.join(REPO_ROOT, normalizedPath);
|
||||
|
||||
@@ -325,6 +325,12 @@ function loadInstallManifests(options = {}) {
|
||||
|
||||
for (const module of modules) {
|
||||
readModuleTargetsOrThrow(module);
|
||||
if (module.optionalDependencies !== undefined && (
|
||||
!Array.isArray(module.optionalDependencies)
|
||||
|| module.optionalDependencies.some(id => !module.dependencies.includes(id))
|
||||
)) {
|
||||
throw new Error(`Install module ${module.id} optionalDependencies must be an array of declared dependency ids`);
|
||||
}
|
||||
}
|
||||
|
||||
const modulesById = new Map(modules.map(module => [module.id, module]));
|
||||
@@ -633,7 +639,7 @@ function resolveInstallPlan(options = {}) {
|
||||
const visitingIds = new Set();
|
||||
const resolvedIds = new Set();
|
||||
|
||||
function resolveModule(moduleId, dependencyOf, rootRequesterId) {
|
||||
function resolveModule(moduleId, dependencyOf, optional = false) {
|
||||
const module = manifests.modulesById.get(moduleId);
|
||||
if (!module) {
|
||||
throw new Error(`Unknown install module: ${moduleId}`);
|
||||
@@ -657,8 +663,9 @@ function resolveInstallPlan(options = {}) {
|
||||
|
||||
if (!supportsTarget) {
|
||||
if (dependencyOf) {
|
||||
skippedTargetIds.add(rootRequesterId || dependencyOf);
|
||||
return false;
|
||||
// Only explicitly optional edges may be omitted for this target.
|
||||
skippedTargetIds.add(moduleId);
|
||||
return optional;
|
||||
}
|
||||
skippedTargetIds.add(moduleId);
|
||||
return false;
|
||||
@@ -677,24 +684,36 @@ function resolveInstallPlan(options = {}) {
|
||||
const dependencyResolved = resolveModule(
|
||||
dependencyId,
|
||||
moduleId,
|
||||
rootRequesterId || moduleId
|
||||
(module.optionalDependencies || []).includes(dependencyId)
|
||||
);
|
||||
if (!dependencyResolved) {
|
||||
visitingIds.delete(moduleId);
|
||||
if (!dependencyOf) {
|
||||
skippedTargetIds.add(moduleId);
|
||||
}
|
||||
skippedTargetIds.add(moduleId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
visitingIds.delete(moduleId);
|
||||
resolvedIds.add(moduleId);
|
||||
selectedIds.add(moduleId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolution may visit supported dependencies before a later required edge fails.
|
||||
// Select only the closure of successful requests, so failed requests leave no
|
||||
// orphan modules while shared dependencies remain available to successful ones.
|
||||
function selectResolvedModule(moduleId) {
|
||||
if (!resolvedIds.has(moduleId) || selectedIds.has(moduleId)) {
|
||||
return;
|
||||
}
|
||||
selectedIds.add(moduleId);
|
||||
for (const dependencyId of manifests.modulesById.get(moduleId).dependencies) {
|
||||
selectResolvedModule(dependencyId);
|
||||
}
|
||||
}
|
||||
|
||||
for (const moduleId of effectiveRequestedIds) {
|
||||
resolveModule(moduleId, null, moduleId);
|
||||
if (resolveModule(moduleId, null)) {
|
||||
selectResolvedModule(moduleId);
|
||||
}
|
||||
}
|
||||
|
||||
const selectedModules = manifests.modules.filter(module => selectedIds.has(module.id));
|
||||
|
||||
Reference in New Issue
Block a user