resolve method
Resolve dependencies and return load order Uses topological sort to determine correct order
Implementation
DependencyResolutionResult resolve({
required Map<String, List<ModuleDependency>> modules,
required Map<String, String> moduleVersions,
}) {
final errors = <String>[];
final warnings = <String>[];
final resolved = <String>[];
final unresolved = <String>{};
// Flag to stop resolution immediately when circular dependency is found
bool hasCircularDependency = false;
void resolveModule(String moduleId) {
// Stop immediately if circular dependency was detected
if (hasCircularDependency) return;
if (resolved.contains(moduleId)) return;
if (unresolved.contains(moduleId)) {
errors.add('Circular dependency detected: $moduleId');
hasCircularDependency = true;
return;
}
unresolved.add(moduleId);
final deps = modules[moduleId] ?? [];
for (final dep in deps) {
// Check before processing each dependency to exit early
if (hasCircularDependency) return;
// Check if dependency exists
if (!modules.containsKey(dep.moduleId)) {
if (dep.isOptional) {
warnings.add('Optional dependency ${dep.moduleId} not found');
} else {
errors.add('Missing required dependency: ${dep.moduleId}');
}
continue;
}
// Check version compatibility
final depVersion = moduleVersions[dep.moduleId];
if (depVersion != null && !dep.isSatisfiedBy(depVersion)) {
errors.add(
'Version mismatch: ${dep.moduleId} requires ${dep.versionRequirement}, '
'got $depVersion',
);
continue;
}
resolveModule(dep.moduleId);
}
unresolved.remove(moduleId);
if (!hasCircularDependency) {
resolved.add(moduleId);
}
}
// Resolve all modules
for (final moduleId in modules.keys) {
if (hasCircularDependency) break;
resolveModule(moduleId);
}
return DependencyResolutionResult(
success: errors.isEmpty,
resolvedOrder: resolved,
errors: errors,
warnings: warnings,
);
}