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