[libcalamaresui] Refactor moduleFromDescriptor

- this function lives in Module -- and is the only thing typing
  Module to the ViewSteps and JobTypes. Split it out into its
  own funciton. Nothing else in Module needs to befriend the
  ViewSteps, so we move the friend declaration around a bit
  as well.
- while here, apply coding style.

This is prep-work for moving module to libcalamares.
This commit is contained in:
Adriaan de Groot 2020-03-31 22:44:02 +02:00
parent 4ddd1ecceb
commit e04f87fe95
12 changed files with 249 additions and 131 deletions

View File

@ -183,7 +183,7 @@ load_module( const ModuleConfig& moduleConfig )
cDebug() << "Module" << moduleName << "job-configuration:" << configFile; cDebug() << "Module" << moduleName << "job-configuration:" << configFile;
Calamares::Module* module = Calamares::Module::fromDescriptor( descriptor, name, configFile, moduleDirectory ); Calamares::Module* module = Calamares::moduleFromDescriptor( descriptor, name, configFile, moduleDirectory );
return module; return module;
} }

View File

@ -7,6 +7,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/libcalamares ${CMAKE_BINARY_DIR}/sr
set( calamaresui_SOURCES set( calamaresui_SOURCES
modulesystem/CppJobModule.cpp modulesystem/CppJobModule.cpp
modulesystem/Module.cpp modulesystem/Module.cpp
modulesystem/ModuleFactory.cpp
modulesystem/ModuleManager.cpp modulesystem/ModuleManager.cpp
modulesystem/ProcessJobModule.cpp modulesystem/ProcessJobModule.cpp
modulesystem/RequirementsChecker.cpp modulesystem/RequirementsChecker.cpp

View File

@ -21,8 +21,8 @@
#ifndef CALAMARES_CPPJOBMODULE_H #ifndef CALAMARES_CPPJOBMODULE_H
#define CALAMARES_CPPJOBMODULE_H #define CALAMARES_CPPJOBMODULE_H
#include "Module.h"
#include "DllMacro.h" #include "DllMacro.h"
#include "Module.h"
class QPluginLoader; class QPluginLoader;
@ -42,12 +42,16 @@ protected:
void initFrom( const QVariantMap& moduleDescriptor ) override; void initFrom( const QVariantMap& moduleDescriptor ) override;
private: private:
friend class Module; //so only the superclass can instantiate
explicit CppJobModule(); explicit CppJobModule();
virtual ~CppJobModule() override; virtual ~CppJobModule() override;
QPluginLoader* m_loader; QPluginLoader* m_loader;
job_ptr m_job; job_ptr m_job;
friend Module* Calamares::moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
}; };
} // namespace Calamares } // namespace Calamares

View File

@ -66,111 +66,6 @@ Module::initFrom( const Calamares::ModuleSystem::Descriptor& moduleDescriptor, c
} }
} }
Module*
Module::fromDescriptor( const Calamares::ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory )
{
std::unique_ptr< Module > m;
QString typeString = moduleDescriptor.value( "type" ).toString();
QString intfString = moduleDescriptor.value( "interface" ).toString();
if ( typeString.isEmpty() || intfString.isEmpty() )
{
cError() << "Bad module descriptor format" << instanceId;
return nullptr;
}
if ( ( typeString == "view" ) || ( typeString == "viewmodule" ) )
{
if ( intfString == "qtplugin" )
{
m.reset( new ViewModule() );
}
else if ( intfString == "pythonqt" )
{
#ifdef WITH_PYTHONQT
m.reset( new PythonQtViewModule() );
#else
cError() << "PythonQt view modules are not supported in this version of Calamares.";
#endif
}
else
{
cError() << "Bad interface" << intfString << "for module type" << typeString;
}
}
else if ( typeString == "job" )
{
if ( intfString == "qtplugin" )
{
m.reset( new CppJobModule() );
}
else if ( intfString == "process" )
{
m.reset( new ProcessJobModule() );
}
else if ( intfString == "python" )
{
#ifdef WITH_PYTHON
m.reset( new PythonJobModule() );
#else
cError() << "Python modules are not supported in this version of Calamares.";
#endif
}
else
{
cError() << "Bad interface" << intfString << "for module type" << typeString;
}
}
else
{
cError() << "Bad module type" << typeString;
}
if ( !m )
{
cError() << "Bad module type (" << typeString << ") or interface string (" << intfString << ") for module "
<< instanceId;
return nullptr;
}
QDir moduleDir( moduleDirectory );
if ( moduleDir.exists() && moduleDir.isReadable() )
{
m->m_directory = moduleDir.absolutePath();
}
else
{
cError() << "Bad module directory" << moduleDirectory << "for" << instanceId;
return nullptr;
}
m->initFrom( moduleDescriptor, instanceId );
if ( !m->m_key.isValid() )
{
cError() << "Module" << instanceId << "invalid ID";
return nullptr;
}
m->initFrom( moduleDescriptor );
if ( !configFileName.isEmpty() )
{
try
{
m->loadConfigurationFile( configFileName );
}
catch ( YAML::Exception& e )
{
cError() << "YAML parser error " << e.what();
return nullptr;
}
}
return m.release();
}
static QStringList static QStringList
moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, const QString& configFileName ) moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, const QString& configFileName )
{ {
@ -211,7 +106,8 @@ moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, c
return paths; return paths;
} }
void Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception void
Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception
{ {
QStringList configCandidates QStringList configCandidates
= moduleConfigurationCandidates( Settings::instance()->debugMode(), name(), configFileName ); = moduleConfigurationCandidates( Settings::instance()->debugMode(), name(), configFileName );

View File

@ -33,6 +33,12 @@
namespace Calamares namespace Calamares
{ {
class Module;
Module* moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
/** /**
* @brief The Module class is a common supertype for Calamares modules. * @brief The Module class is a common supertype for Calamares modules.
@ -68,18 +74,6 @@ public:
PythonQt // Views only, available as enum even if PythonQt isn't used PythonQt // Views only, available as enum even if PythonQt isn't used
}; };
/**
* @brief fromDescriptor creates a new Module object of the correct type.
* @param moduleDescriptor a module descriptor, already parsed into a variant map.
* @param instanceId the instance id of the new module instance.
* @param configFileName the name of the configuration file to read.
* @param moduleDirectory the path to the directory with this module's files.
* @return a pointer to an object of a subtype of Module.
*/
static Module* fromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
virtual ~Module(); virtual ~Module();
/** /**
@ -193,6 +187,11 @@ private:
QString m_directory; QString m_directory;
ModuleSystem::InstanceKey m_key; ModuleSystem::InstanceKey m_key;
friend Module* Calamares::moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
}; };
} // namespace Calamares } // namespace Calamares

View File

@ -0,0 +1,154 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ModuleFactory.h"
#include "CalamaresConfig.h"
#include "CppJobModule.h"
#include "ProcessJobModule.h"
#include "ViewModule.h"
#include "utils/Dirs.h"
#include "utils/Logger.h"
#include "utils/NamedEnum.h"
#include "utils/Yaml.h"
#ifdef WITH_PYTHON
#include "PythonJobModule.h"
#endif
#ifdef WITH_PYTHONQT
#include "PythonQtViewModule.h"
#endif
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QString>
namespace Calamares
{
Module*
moduleFromDescriptor( const Calamares::ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory )
{
std::unique_ptr< Module > m;
QString typeString = moduleDescriptor.value( "type" ).toString();
QString intfString = moduleDescriptor.value( "interface" ).toString();
if ( typeString.isEmpty() || intfString.isEmpty() )
{
cError() << "Bad module descriptor format" << instanceId;
return nullptr;
}
if ( ( typeString == "view" ) || ( typeString == "viewmodule" ) )
{
if ( intfString == "qtplugin" )
{
m.reset( new ViewModule() );
}
else if ( intfString == "pythonqt" )
{
#ifdef WITH_PYTHONQT
m.reset( new PythonQtViewModule() );
#else
cError() << "PythonQt view modules are not supported in this version of Calamares.";
#endif
}
else
{
cError() << "Bad interface" << intfString << "for module type" << typeString;
}
}
else if ( typeString == "job" )
{
if ( intfString == "qtplugin" )
{
m.reset( new CppJobModule() );
}
else if ( intfString == "process" )
{
m.reset( new ProcessJobModule() );
}
else if ( intfString == "python" )
{
#ifdef WITH_PYTHON
m.reset( new PythonJobModule() );
#else
cError() << "Python modules are not supported in this version of Calamares.";
#endif
}
else
{
cError() << "Bad interface" << intfString << "for module type" << typeString;
}
}
else
{
cError() << "Bad module type" << typeString;
}
if ( !m )
{
cError() << "Bad module type (" << typeString << ") or interface string (" << intfString << ") for module "
<< instanceId;
return nullptr;
}
QDir moduleDir( moduleDirectory );
if ( moduleDir.exists() && moduleDir.isReadable() )
{
m->m_directory = moduleDir.absolutePath();
}
else
{
cError() << "Bad module directory" << moduleDirectory << "for" << instanceId;
return nullptr;
}
m->initFrom( moduleDescriptor, instanceId );
if ( !m->m_key.isValid() )
{
cError() << "Module" << instanceId << "invalid ID";
return nullptr;
}
m->initFrom( moduleDescriptor );
if ( !configFileName.isEmpty() )
{
try
{
m->loadConfigurationFile( configFileName );
}
catch ( YAML::Exception& e )
{
cError() << "YAML parser error " << e.what();
return nullptr;
}
}
return m.release();
}
} // namespace Calamares

View File

@ -0,0 +1,47 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2017, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALAMARES_MODULEFACTORY_H
#define CALAMARES_MODULEFACTORY_H
#include "DllMacro.h"
#include "modulesystem/Descriptor.h"
#include "modulesystem/Module.h"
#include <QString>
namespace Calamares
{
/**
* @brief fromDescriptor creates a new Module object of the correct type.
* @param moduleDescriptor a module descriptor, already parsed into a variant map.
* @param instanceId the instance id of the new module instance.
* @param configFileName the name of the configuration file to read.
* @param moduleDirectory the path to the directory with this module's files.
* @return a pointer to an object of a subtype of Module.
*/
UIDLLEXPORT Module* moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
} // namespace Calamares
#endif // CALAMARES_MODULEFACTORY_H

View File

@ -285,10 +285,11 @@ ModuleManager::loadModules()
} }
else else
{ {
thisModule = Module::fromDescriptor( descriptor, thisModule
instanceKey.id(), = Calamares::moduleFromDescriptor( descriptor,
configFileName, instanceKey.id(),
m_moduleDirectoriesByModuleName.value( instanceKey.module() ) ); configFileName,
m_moduleDirectoriesByModuleName.value( instanceKey.module() ) );
if ( !thisModule ) if ( !thisModule )
{ {
cError() << "Module" << instanceKey.toString() << "cannot be created from descriptor" cError() << "Module" << instanceKey.toString() << "cannot be created from descriptor"

View File

@ -42,7 +42,6 @@ protected:
void initFrom( const QVariantMap& moduleDescriptor ) override; void initFrom( const QVariantMap& moduleDescriptor ) override;
private: private:
friend class Module;
explicit ProcessJobModule(); explicit ProcessJobModule();
virtual ~ProcessJobModule() override; virtual ~ProcessJobModule() override;
@ -51,6 +50,11 @@ private:
std::chrono::seconds m_secondsTimeout; std::chrono::seconds m_secondsTimeout;
bool m_runInChroot; bool m_runInChroot;
job_ptr m_job; job_ptr m_job;
friend Module* Calamares::moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
}; };
} // namespace Calamares } // namespace Calamares

View File

@ -39,13 +39,17 @@ protected:
void initFrom( const QVariantMap& moduleDescriptor ) override; void initFrom( const QVariantMap& moduleDescriptor ) override;
private: private:
friend class Module;
explicit PythonJobModule(); explicit PythonJobModule();
virtual ~PythonJobModule() override; virtual ~PythonJobModule() override;
QString m_scriptFileName; QString m_scriptFileName;
QString m_workingPath; QString m_workingPath;
job_ptr m_job; job_ptr m_job;
friend Module* Calamares::moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
}; };
} // namespace Calamares } // namespace Calamares

View File

@ -19,8 +19,8 @@
#ifndef CALAMARES_PYTHONQTVIEWMODULE_H #ifndef CALAMARES_PYTHONQTVIEWMODULE_H
#define CALAMARES_PYTHONQTVIEWMODULE_H #define CALAMARES_PYTHONQTVIEWMODULE_H
#include "Module.h"
#include "DllMacro.h" #include "DllMacro.h"
#include "Module.h"
namespace Calamares namespace Calamares
{ {
@ -40,7 +40,6 @@ protected:
void initFrom( const QVariantMap& moduleDescriptor ) override; void initFrom( const QVariantMap& moduleDescriptor ) override;
private: private:
friend class Module; //so only the superclass can instantiate
explicit PythonQtViewModule(); explicit PythonQtViewModule();
virtual ~PythonQtViewModule(); virtual ~PythonQtViewModule();
@ -48,6 +47,11 @@ private:
QString m_scriptFileName; QString m_scriptFileName;
QString m_workingPath; QString m_workingPath;
friend Module* Calamares::moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
}; };
} // namespace Calamares } // namespace Calamares

View File

@ -20,8 +20,8 @@
#ifndef CALAMARES_VIEWMODULE_H #ifndef CALAMARES_VIEWMODULE_H
#define CALAMARES_VIEWMODULE_H #define CALAMARES_VIEWMODULE_H
#include "Module.h"
#include "DllMacro.h" #include "DllMacro.h"
#include "Module.h"
class QPluginLoader; class QPluginLoader;
@ -45,12 +45,16 @@ protected:
void initFrom( const QVariantMap& moduleDescriptor ) override; void initFrom( const QVariantMap& moduleDescriptor ) override;
private: private:
friend class Module; //so only the superclass can instantiate
explicit ViewModule(); explicit ViewModule();
virtual ~ViewModule() override; virtual ~ViewModule() override;
QPluginLoader* m_loader; QPluginLoader* m_loader;
ViewStep* m_viewStep = nullptr; ViewStep* m_viewStep = nullptr;
friend Module* Calamares::moduleFromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId,
const QString& configFileName,
const QString& moduleDirectory );
}; };
} // namespace Calamares } // namespace Calamares