[libcalamaresui] Check module dependencies

- Module dependency-checking is done in two phases:
   first, catch any unknown modules that are listed
   in *requiredModules* and bail out before loading
   anything. Second, check that the modules required
   by X occur before X in the sequence.
main
Adriaan de Groot 7 years ago
parent 731594fb40
commit 08966ff933

@ -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;
}
}

@ -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;

Loading…
Cancel
Save