FIXME, TODO: decouple dependency resolution from loading FIXME: This works directly with the PackProfile internals. It shouldn't! It needs richer data types than PackProfile uses. FIXME: throw all this away and use a graph
| 499 | // FIXME: This works directly with the PackProfile internals. It shouldn't! It needs richer data types than PackProfile uses. |
| 500 | // FIXME: throw all this away and use a graph |
| 501 | void ComponentUpdateTask::resolveDependencies(bool checkOnly) |
| 502 | { |
| 503 | qDebug() << "Resolving dependencies"; |
| 504 | /* |
| 505 | * this is a naive dependency resolving algorithm. all it does is check for following conditions and react in simple ways: |
| 506 | * 1. There are conflicting dependencies on the same uid with different exact version numbers |
| 507 | * -> hard error |
| 508 | * 2. A dependency has non-matching exact version number |
| 509 | * -> hard error |
| 510 | * 3. A dependency is entirely missing and needs to be injected before the dependee(s) |
| 511 | * -> requirements are injected |
| 512 | * |
| 513 | * NOTE: this is a placeholder and should eventually be replaced with something 'serious' |
| 514 | */ |
| 515 | auto & components = d->m_list->d->components; |
| 516 | auto & componentIndex = d->m_list->d->componentIndex; |
| 517 | |
| 518 | RequireExSet allRequires; |
| 519 | QStringList toRemove; |
| 520 | do |
| 521 | { |
| 522 | allRequires.clear(); |
| 523 | toRemove.clear(); |
| 524 | if(!gatherRequirementsFromComponents(components, allRequires)) |
| 525 | { |
| 526 | emitFailed(tr("Conflicting requirements detected during dependency checking!")); |
| 527 | return; |
| 528 | } |
| 529 | getTrivialRemovals(components, allRequires, toRemove); |
| 530 | if(!toRemove.isEmpty()) |
| 531 | { |
| 532 | qDebug() << "Removing obsolete components..."; |
| 533 | for(auto & remove : toRemove) |
| 534 | { |
| 535 | qDebug() << "Removing" << remove; |
| 536 | d->m_list->remove(remove); |
| 537 | } |
| 538 | } |
| 539 | } while (!toRemove.isEmpty()); |
| 540 | RequireExSet toAdd; |
| 541 | RequireExSet toChange; |
| 542 | bool succeeded = getTrivialComponentChanges(componentIndex, allRequires, toAdd, toChange); |
| 543 | if(!succeeded) |
| 544 | { |
| 545 | emitFailed(tr("Instance has conflicting dependencies.")); |
| 546 | return; |
| 547 | } |
| 548 | if(checkOnly) |
| 549 | { |
| 550 | if(toAdd.size() || toChange.size()) |
| 551 | { |
| 552 | emitFailed(tr("Instance has unresolved dependencies while loading/checking for launch.")); |
| 553 | } |
| 554 | else |
| 555 | { |
| 556 | emitSucceeded(); |
| 557 | } |
| 558 | return; |
nothing calls this directly
no test coverage detected