[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.
This commit is contained in:
parent
731594fb40
commit
08966ff933
@ -126,7 +126,6 @@ ModuleManager::doInit()
|
|||||||
}
|
}
|
||||||
// At this point m_availableModules is filled with whatever was found in the
|
// At this point m_availableModules is filled with whatever was found in the
|
||||||
// search paths.
|
// search paths.
|
||||||
checkDependencies();
|
|
||||||
emit initDone();
|
emit initDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +175,13 @@ ModuleManager::loadModules()
|
|||||||
{
|
{
|
||||||
QTimer::singleShot( 0, this, [ this ]()
|
QTimer::singleShot( 0, this, [ this ]()
|
||||||
{
|
{
|
||||||
QStringList failedModules;
|
QStringList failedModules = checkDependencies();
|
||||||
|
if ( !failedModules.isEmpty() )
|
||||||
|
{
|
||||||
|
emit modulesFailed( failedModules );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Settings::InstanceDescriptionList customInstances =
|
Settings::InstanceDescriptionList customInstances =
|
||||||
Settings::instance()->customModuleInstances();
|
Settings::instance()->customModuleInstances();
|
||||||
|
|
||||||
@ -262,6 +267,14 @@ ModuleManager::loadModules()
|
|||||||
failedModules.append( instanceKey );
|
failedModules.append( instanceKey );
|
||||||
continue;
|
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.
|
// If it's a ViewModule, it also appends the ViewStep to the ViewManager.
|
||||||
thisModule->loadSelf();
|
thisModule->loadSelf();
|
||||||
m_loadedModulesByInstanceKey.insert( instanceKey, thisModule );
|
m_loadedModulesByInstanceKey.insert( instanceKey, thisModule );
|
||||||
@ -301,24 +314,29 @@ ModuleManager::loadModules()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
QStringList
|
||||||
ModuleManager::checkDependencies()
|
ModuleManager::checkDependencies()
|
||||||
{
|
{
|
||||||
|
QStringList failed;
|
||||||
|
|
||||||
// This goes through the map of available modules, and deletes those whose
|
// This goes through the map of available modules, and deletes those whose
|
||||||
// dependencies are not met, if any.
|
// dependencies are not met, if any.
|
||||||
bool somethingWasRemovedBecauseOfUnmetDependencies = false;
|
|
||||||
forever
|
forever
|
||||||
{
|
{
|
||||||
|
bool somethingWasRemovedBecauseOfUnmetDependencies = false;
|
||||||
for ( auto it = m_availableDescriptorsByModuleName.begin();
|
for ( auto it = m_availableDescriptorsByModuleName.begin();
|
||||||
it != m_availableDescriptorsByModuleName.end(); ++it )
|
it != m_availableDescriptorsByModuleName.end(); ++it )
|
||||||
{
|
{
|
||||||
foreach ( const QString& depName,
|
foreach ( const QString& depName,
|
||||||
( *it ).value( "requiredModules" ).toStringList() )
|
it->value( "requiredModules" ).toStringList() )
|
||||||
{
|
{
|
||||||
if ( !m_availableDescriptorsByModuleName.contains( depName ) )
|
if ( !m_availableDescriptorsByModuleName.contains( depName ) )
|
||||||
{
|
{
|
||||||
|
QString moduleName = it->value( "name" ).toString();
|
||||||
somethingWasRemovedBecauseOfUnmetDependencies = true;
|
somethingWasRemovedBecauseOfUnmetDependencies = true;
|
||||||
m_availableDescriptorsByModuleName.erase( it );
|
m_availableDescriptorsByModuleName.erase( it );
|
||||||
|
failed << moduleName;
|
||||||
|
cWarning() << "Module" << moduleName << "has unmet requirement" << depName;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,7 +346,33 @@ ModuleManager::checkDependencies()
|
|||||||
if ( !somethingWasRemovedBecauseOfUnmetDependencies )
|
if ( !somethingWasRemovedBecauseOfUnmetDependencies )
|
||||||
break;
|
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();
|
void doInit();
|
||||||
|
|
||||||
private:
|
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, QVariantMap > m_availableDescriptorsByModuleName;
|
||||||
QMap< QString, QString > m_moduleDirectoriesByModuleName;
|
QMap< QString, QString > m_moduleDirectoriesByModuleName;
|
||||||
|
Loading…
Reference in New Issue
Block a user