diff --git a/src/libcalamaresui/modulesystem/ModuleManager.cpp b/src/libcalamaresui/modulesystem/ModuleManager.cpp index ed1e52f9f..24bc6bc53 100644 --- a/src/libcalamaresui/modulesystem/ModuleManager.cpp +++ b/src/libcalamaresui/modulesystem/ModuleManager.cpp @@ -126,7 +126,6 @@ ModuleManager::doInit() } // At this point m_availableModules is filled with whatever was found in the // search paths. - checkDependencies(); emit initDone(); } @@ -176,7 +175,13 @@ ModuleManager::loadModules() { QTimer::singleShot( 0, this, [ this ]() { - QStringList failedModules; + QStringList failedModules = checkDependencies(); + if ( !failedModules.isEmpty() ) + { + emit modulesFailed( failedModules ); + return; + } + Settings::InstanceDescriptionList customInstances = Settings::instance()->customModuleInstances(); @@ -262,6 +267,14 @@ ModuleManager::loadModules() failedModules.append( instanceKey ); continue; } + + if ( !checkDependencies( *thisModule ) ) + { + // Error message is already printed + failedModules.append( instanceKey ); + continue; + } + // If it's a ViewModule, it also appends the ViewStep to the ViewManager. thisModule->loadSelf(); m_loadedModulesByInstanceKey.insert( instanceKey, thisModule ); @@ -301,24 +314,29 @@ ModuleManager::loadModules() } -void +QStringList ModuleManager::checkDependencies() { + QStringList failed; + // This goes through the map of available modules, and deletes those whose // dependencies are not met, if any. - bool somethingWasRemovedBecauseOfUnmetDependencies = false; forever { + bool somethingWasRemovedBecauseOfUnmetDependencies = false; for ( auto it = m_availableDescriptorsByModuleName.begin(); it != m_availableDescriptorsByModuleName.end(); ++it ) { foreach ( const QString& depName, - ( *it ).value( "requiredModules" ).toStringList() ) + it->value( "requiredModules" ).toStringList() ) { if ( !m_availableDescriptorsByModuleName.contains( depName ) ) { + QString moduleName = it->value( "name" ).toString(); somethingWasRemovedBecauseOfUnmetDependencies = true; m_availableDescriptorsByModuleName.erase( it ); + failed << moduleName; + cWarning() << "Module" << moduleName << "has unmet requirement" << depName; break; } } @@ -328,7 +346,33 @@ ModuleManager::checkDependencies() if ( !somethingWasRemovedBecauseOfUnmetDependencies ) break; } + + return failed; } +bool +ModuleManager::checkDependencies( const Module& m ) +{ + bool allRequirementsFound = true; + QStringList requiredModules = m_availableDescriptorsByModuleName[ m.name() ].value( "requiredModules" ).toStringList(); + + for ( const QString& required : requiredModules ) + { + bool requirementFound = false; + for( const Module* v : m_loadedModulesByInstanceKey ) + if ( required == v->name() ) + { + requirementFound = true; + break; + } + if ( !requirementFound ) + { + cError() << "Module" << m.name() << "requires" << required << "before it in sequence."; + allRequirementsFound = false; + } + } + + return allRequirementsFound; +} } diff --git a/src/libcalamaresui/modulesystem/ModuleManager.h b/src/libcalamaresui/modulesystem/ModuleManager.h index eff09b321..a0edc2528 100644 --- a/src/libcalamaresui/modulesystem/ModuleManager.h +++ b/src/libcalamaresui/modulesystem/ModuleManager.h @@ -90,7 +90,25 @@ private slots: void doInit(); private: - void checkDependencies(); + /** + * Check in a general sense whether the dependencies between + * modules are valid. Returns a list of module names that + * do **not** have their requirements met. + * + * Returns an empty list on success. + * + * Also modifies m_availableDescriptorsByModuleName to remove + * all the entries that fail. + */ + QStringList checkDependencies(); + + /** + * Check for this specific module if its required modules have + * already been loaded (i.e. are in sequence before it). + * + * Returns true if the requirements are met. + */ + bool checkDependencies( const Module& ); QMap< QString, QVariantMap > m_availableDescriptorsByModuleName; QMap< QString, QString > m_moduleDirectoriesByModuleName;