Merge branch 'master' of https://github.com/calamares/calamares into development

This commit is contained in:
Philip Müller 2019-08-06 13:02:38 +02:00
commit 1d8938cc28
61 changed files with 1325 additions and 1151 deletions

View File

@ -2,6 +2,7 @@
BasedOnStyle: WebKit BasedOnStyle: WebKit
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignEscapedNewlines: Left
AllowAllParametersOfDeclarationOnNextLine: 'false' AllowAllParametersOfDeclarationOnNextLine: 'false'
AllowShortFunctionsOnASingleLine: Inline AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: 'false' AllowShortIfStatementsOnASingleLine: 'false'

View File

@ -35,7 +35,7 @@
# One special target is "show-version", which can be built # One special target is "show-version", which can be built
# to obtain the version number from here. # to obtain the version number from here.
cmake_minimum_required( VERSION 3.2 FATAL_ERROR ) cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
project( CALAMARES project( CALAMARES
VERSION 3.2.12 VERSION 3.2.12
LANGUAGES C CXX ) LANGUAGES C CXX )
@ -96,10 +96,10 @@ set( CALAMARES_DESCRIPTION_SUMMARY
# (sr@latin in particular) may need special handling in CalamaresUtils.cpp. # (sr@latin in particular) may need special handling in CalamaresUtils.cpp.
# #
# TODO: drop the es_ES translation from Transifex # TODO: drop the es_ES translation from Transifex
# TODO: move eo (Esperanto) to _ok once Qt can actually create a
# locale for it.
# #
# NOTE: when updating the list from Transifex, copy these four lines # NOTE: move eo (Esperanto) to _ok once Qt can actually create a
# locale for it. (Qt 5.12.2 can, see check later on).
# NOTE: update these lines by running txstats.py, or copy these four lines
# and prefix each variable name with "p", so that the automatic # and prefix each variable name with "p", so that the automatic
# checks for new languages and misspelled ones are done (that is, # checks for new languages and misspelled ones are done (that is,
# copy these four lines to four backup lines, add "p", and then update # copy these four lines to four backup lines, add "p", and then update
@ -128,6 +128,10 @@ set( BOOSTPYTHON_VERSION 1.55.0 )
# #
set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules" ) set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules" )
# Enable IN_LIST
if( POLICY CMP0057 )
cmake_policy( SET CMP0057 NEW )
endif()
# CMake 3.9, 3.10 compatibility # CMake 3.9, 3.10 compatibility
if( POLICY CMP0071 ) if( POLICY CMP0071 )
cmake_policy( SET CMP0071 NEW ) cmake_policy( SET CMP0071 NEW )
@ -249,6 +253,15 @@ include( CMakeColors )
### DEPENDENCIES ### DEPENDENCIES
# #
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui Widgets LinguistTools Svg Quick QuickWidgets ) find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui Widgets LinguistTools Svg Quick QuickWidgets )
if( Qt5_VERSION VERSION_GREATER 5.12.1 )
# At least Qt 5.12.2 seems to support Esperanto in QLocale
if( "eo" IN_LIST _tx_incomplete )
message(STATUS "Esperanto support since Qt 5.12.2, enabling Esperanto locale")
list( REMOVE_ITEM _tx_incomplete "eo" )
list( APPEND _tx_ok "eo" )
endif()
endif()
find_package( YAMLCPP ${YAMLCPP_VERSION} REQUIRED ) find_package( YAMLCPP ${YAMLCPP_VERSION} REQUIRED )
if( INSTALL_POLKIT ) if( INSTALL_POLKIT )
find_package( PolkitQt5-1 REQUIRED ) find_package( PolkitQt5-1 REQUIRED )

View File

@ -37,7 +37,7 @@ style_some()
if test "x$any_dirs" = "xyes" ; then if test "x$any_dirs" = "xyes" ; then
for d in "$@" for d in "$@"
do do
if test -d "$@" ; then if test -d "$d" ; then
style_some $( find "$d" -maxdepth 1 -type f -name '*.cpp' -o -name '*.h' ) style_some $( find "$d" -maxdepth 1 -type f -name '*.cpp' -o -name '*.h' )
else else
style_some "$d" style_some "$d"

View File

@ -24,11 +24,11 @@ namespace Calamares
CppJob::CppJob( QObject* parent ) CppJob::CppJob( QObject* parent )
: Job( parent ) : Job( parent )
{} {
}
CppJob::~CppJob() CppJob::~CppJob() {}
{}
void void
@ -44,4 +44,4 @@ CppJob::setConfigurationMap( const QVariantMap& configurationMap )
Q_UNUSED( configurationMap ) Q_UNUSED( configurationMap )
} }
} } // namespace Calamares

View File

@ -45,6 +45,6 @@ protected:
QString m_instanceKey; QString m_instanceKey;
}; };
} } // namespace Calamares
#endif // CALAMARES_CPPJOB_H #endif // CALAMARES_CPPJOB_H

View File

@ -22,11 +22,11 @@
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#ifndef DLLEXPORT #ifndef DLLEXPORT
# if defined (DLLEXPORT_PRO) #if defined( DLLEXPORT_PRO )
# define DLLEXPORT Q_DECL_EXPORT #define DLLEXPORT Q_DECL_EXPORT
# else #else
# define DLLEXPORT Q_DECL_IMPORT #define DLLEXPORT Q_DECL_IMPORT
# endif #endif
#endif #endif
#endif #endif

View File

@ -21,8 +21,8 @@
#include "JobQueue.h" #include "JobQueue.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "utils/Yaml.h"
#include "utils/Units.h" #include "utils/Units.h"
#include "utils/Yaml.h"
#include <QFile> #include <QFile>
#include <QJsonDocument> #include <QJsonDocument>
@ -40,7 +40,8 @@ namespace bp = boost::python;
using CalamaresUtils::operator""_MiB; using CalamaresUtils::operator""_MiB;
namespace Calamares { namespace Calamares
{
GlobalStorage::GlobalStorage() GlobalStorage::GlobalStorage()
: QObject( nullptr ) : QObject( nullptr )
@ -102,13 +103,15 @@ GlobalStorage::debugDump() const
} }
bool bool
GlobalStorage::save(const QString& filename) GlobalStorage::save( const QString& filename )
{ {
QFile f( filename ); QFile f( filename );
if ( !f.open( QFile::WriteOnly ) ) if ( !f.open( QFile::WriteOnly ) )
{
return false; return false;
}
f.write( QJsonDocument::fromVariant( m ).toJson() ) ; f.write( QJsonDocument::fromVariant( m ).toJson() );
f.close(); f.close();
return true; return true;
} }
@ -118,18 +121,24 @@ GlobalStorage::load( const QString& filename )
{ {
QFile f( filename ); QFile f( filename );
if ( !f.open( QFile::ReadOnly ) ) if ( !f.open( QFile::ReadOnly ) )
{
return false; return false;
}
QJsonParseError e; QJsonParseError e;
QJsonDocument d = QJsonDocument::fromJson( f.read( 1_MiB ), &e ); QJsonDocument d = QJsonDocument::fromJson( f.read( 1_MiB ), &e );
if ( d.isNull() ) if ( d.isNull() )
{
cWarning() << filename << e.errorString(); cWarning() << filename << e.errorString();
}
else if ( !d.isObject() ) else if ( !d.isObject() )
{
cWarning() << filename << "Not suitable JSON."; cWarning() << filename << "Not suitable JSON.";
}
else else
{ {
auto map = d.toVariant().toMap(); auto map = d.toVariant().toMap();
for( auto i = map.constBegin() ; i != map.constEnd() ; ++i ) for ( auto i = map.constBegin(); i != map.constEnd(); ++i )
{ {
insert( i.key(), *i ); insert( i.key(), *i );
} }
@ -150,7 +159,9 @@ GlobalStorage::loadYaml( const QString& filename )
bool ok = false; bool ok = false;
auto gs = CalamaresUtils::loadYaml( filename, &ok ); auto gs = CalamaresUtils::loadYaml( filename, &ok );
if ( ok ) if ( ok )
{
m = gs; m = gs;
}
return ok; return ok;
} }
@ -172,7 +183,7 @@ Calamares::GlobalStorage* GlobalStoragePythonWrapper::s_gs_instance = nullptr;
GlobalStoragePythonWrapper::GlobalStoragePythonWrapper( Calamares::GlobalStorage* gs ) GlobalStoragePythonWrapper::GlobalStoragePythonWrapper( Calamares::GlobalStorage* gs )
: m_gs( gs ? gs : s_gs_instance ) : m_gs( gs ? gs : s_gs_instance )
{ {
if (!m_gs) if ( !m_gs )
{ {
s_gs_instance = new Calamares::GlobalStorage; s_gs_instance = new Calamares::GlobalStorage;
m_gs = s_gs_instance; m_gs = s_gs_instance;
@ -194,11 +205,9 @@ GlobalStoragePythonWrapper::count() const
void void
GlobalStoragePythonWrapper::insert( const std::string& key, GlobalStoragePythonWrapper::insert( const std::string& key, const bp::object& value )
const bp::object& value )
{ {
m_gs->insert( QString::fromStdString( key ), m_gs->insert( QString::fromStdString( key ), CalamaresPython::variantFromPyObject( value ) );
CalamaresPython::variantFromPyObject( value ) );
} }
bp::list bp::list
@ -207,7 +216,9 @@ GlobalStoragePythonWrapper::keys() const
bp::list pyList; bp::list pyList;
const auto keys = m_gs->keys(); const auto keys = m_gs->keys();
for ( const QString& key : keys ) for ( const QString& key : keys )
{
pyList.append( key.toStdString() ); pyList.append( key.toStdString() );
}
return pyList; return pyList;
} }

View File

@ -34,8 +34,8 @@ namespace api
class object; class object;
} }
class list; class list;
} } // namespace python
} } // namespace boost
#endif #endif
namespace Calamares namespace Calamares

View File

@ -84,7 +84,8 @@ JobResult::JobResult( const QString& message, const QString& details, int number
: m_message( message ) : m_message( message )
, m_details( details ) , m_details( details )
, m_number( number ) , m_number( number )
{} {
}
Job::Job( QObject* parent ) Job::Job( QObject* parent )
@ -93,8 +94,7 @@ Job::Job( QObject* parent )
} }
Job::~Job() Job::~Job() {}
{}
qreal qreal

View File

@ -25,7 +25,8 @@
#include <QObject> #include <QObject>
#include <QSharedPointer> #include <QSharedPointer>
namespace Calamares { namespace Calamares
{
class DLLEXPORT JobResult class DLLEXPORT JobResult
{ {
@ -43,7 +44,7 @@ public:
GenericError = -1, GenericError = -1,
PythonUncaughtException = 1, PythonUncaughtException = 1,
InvalidConfiguration = 2 InvalidConfiguration = 2
} ; };
JobResult( const JobResult& rhs ) = delete; JobResult( const JobResult& rhs ) = delete;
JobResult( JobResult&& rhs ); JobResult( JobResult&& rhs );

View File

@ -36,7 +36,8 @@ GoodJob::exec()
JobResult JobResult
FailJob::exec() FailJob::exec()
{ {
return JobResult::error( tr( "Job failed (%1)" ).arg( m_name ), tr( "Programmed job failure was explicitly requested." ) ); return JobResult::error( tr( "Job failed (%1)" ).arg( m_name ),
tr( "Programmed job failure was explicitly requested." ) );
} }
} // namespace } // namespace Calamares

View File

@ -21,7 +21,8 @@
#include "Job.h" #include "Job.h"
namespace Calamares { namespace Calamares
{
/** @brief A Job with a name /** @brief A Job with a name
* *
@ -39,9 +40,10 @@ public:
} }
virtual QString prettyName() const override; virtual QString prettyName() const override;
protected: protected:
const QString m_name; const QString m_name;
} ; };
/// @brief Job does nothing, always succeeds /// @brief Job does nothing, always succeeds
class DLLEXPORT GoodJob : public NamedJob class DLLEXPORT GoodJob : public NamedJob
@ -53,7 +55,7 @@ public:
} }
virtual JobResult exec() override; virtual JobResult exec() override;
} ; };
/// @brief Job does nothing, always fails /// @brief Job does nothing, always fails
@ -66,7 +68,7 @@ public:
} }
virtual JobResult exec() override; virtual JobResult exec() override;
} ; };
} // namespace Calamares } // namespace Calamares

View File

@ -19,8 +19,8 @@
#include "JobQueue.h" #include "JobQueue.h"
#include "Job.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "Job.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "CalamaresConfig.h" #include "CalamaresConfig.h"
@ -50,14 +50,14 @@ public:
m_jobs = jobs; m_jobs = jobs;
qreal totalJobsWeight = 0.0; qreal totalJobsWeight = 0.0;
for( auto job : m_jobs ) for ( auto job : m_jobs )
{ {
totalJobsWeight += job->getJobWeight(); totalJobsWeight += job->getJobWeight();
} }
for( auto job : m_jobs ) for ( auto job : m_jobs )
{ {
qreal jobWeight = qreal( job->getJobWeight() / totalJobsWeight ); qreal jobWeight = qreal( job->getJobWeight() / totalJobsWeight );
m_jobWeights.append( jobWeight ) ; m_jobWeights.append( jobWeight );
} }
} }
@ -68,7 +68,7 @@ public:
QString details; QString details;
m_jobIndex = 0; m_jobIndex = 0;
for( auto job : m_jobs ) for ( auto job : m_jobs )
{ {
if ( anyFailed && !job->isEmergency() ) if ( anyFailed && !job->isEmergency() )
{ {
@ -87,12 +87,18 @@ public:
details = result.details(); details = result.details();
} }
if ( !anyFailed ) if ( !anyFailed )
{
++m_jobIndex; ++m_jobIndex;
} }
}
if ( anyFailed ) if ( anyFailed )
{
emitFailed( message, details ); emitFailed( message, details );
}
else else
{
emitProgress(); emitProgress();
}
emitFinished(); emitFinished();
} }
@ -109,49 +115,39 @@ private:
jobPercent = qBound( qreal( 0 ), jobPercent, qreal( 1 ) ); jobPercent = qBound( qreal( 0 ), jobPercent, qreal( 1 ) );
int jobCount = m_jobs.size(); int jobCount = m_jobs.size();
QString message = m_jobIndex < jobCount QString message = m_jobIndex < jobCount ? m_jobs.at( m_jobIndex )->prettyStatusMessage() : tr( "Done" );
? m_jobs.at( m_jobIndex )->prettyStatusMessage()
: tr( "Done" );
qreal cumulativeProgress = 0.0; qreal cumulativeProgress = 0.0;
for( auto jobWeight : m_jobWeights.mid( 0, m_jobIndex ) ) for ( auto jobWeight : m_jobWeights.mid( 0, m_jobIndex ) )
{ {
cumulativeProgress += jobWeight; cumulativeProgress += jobWeight;
} }
qreal percent = m_jobIndex < jobCount qreal percent
? cumulativeProgress + ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent ) = m_jobIndex < jobCount ? cumulativeProgress + ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent ) : 1.0;
: 1.0;
if (m_jobIndex < jobCount) if ( m_jobIndex < jobCount )
{ {
cDebug(Logger::LOGVERBOSE) << "[JOBQUEUE]: Progress for Job[" << m_jobIndex << "]: " << ( jobPercent * 100 ) << "% completed"; cDebug( Logger::LOGVERBOSE ) << "[JOBQUEUE]: Progress for Job[" << m_jobIndex
cDebug(Logger::LOGVERBOSE) << "[JOBQUEUE]: Progress Overall: " << ( cumulativeProgress * 100 ) << "% (accumulated) + " << "]: " << ( jobPercent * 100 ) << "% completed";
<< ( ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent ) * 100 ) << "% (this job) = " cDebug( Logger::LOGVERBOSE ) << "[JOBQUEUE]: Progress Overall: " << ( cumulativeProgress * 100 )
<< ( percent * 100 ) << "% (total)"; << "% (accumulated) + "
<< ( ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent ) * 100 )
<< "% (this job) = " << ( percent * 100 ) << "% (total)";
} }
QMetaObject::invokeMethod( m_queue, "progress", Qt::QueuedConnection, QMetaObject::invokeMethod(
Q_ARG( qreal, percent ), m_queue, "progress", Qt::QueuedConnection, Q_ARG( qreal, percent ), Q_ARG( QString, message ) );
Q_ARG( QString, message )
);
} }
void emitFailed( const QString& message, const QString& details ) void emitFailed( const QString& message, const QString& details )
{ {
QMetaObject::invokeMethod( m_queue, "failed", Qt::QueuedConnection, QMetaObject::invokeMethod(
Q_ARG( QString, message ), m_queue, "failed", Qt::QueuedConnection, Q_ARG( QString, message ), Q_ARG( QString, details ) );
Q_ARG( QString, details )
);
} }
void emitFinished() void emitFinished() { QMetaObject::invokeMethod( m_queue, "finished", Qt::QueuedConnection ); }
{
QMetaObject::invokeMethod( m_queue, "finished", Qt::QueuedConnection );
}
}; };
JobThread::~JobThread() JobThread::~JobThread() {}
{
}
JobQueue* JobQueue::s_instance = nullptr; JobQueue* JobQueue::s_instance = nullptr;
@ -186,8 +182,10 @@ JobQueue::~JobQueue()
if ( m_thread->isRunning() ) if ( m_thread->isRunning() )
{ {
m_thread->terminate(); m_thread->terminate();
if ( !m_thread->wait(300) ) if ( !m_thread->wait( 300 ) )
{
cError() << "Could not terminate job thread (expect a crash now)."; cError() << "Could not terminate job thread (expect a crash now).";
}
delete m_thread; delete m_thread;
} }

View File

@ -59,6 +59,6 @@ private:
GlobalStorage* m_storage; GlobalStorage* m_storage;
}; };
} } // namespace Calamares
#endif // CALAMARES_JOBQUEUE_H #endif // CALAMARES_JOBQUEUE_H

View File

@ -22,11 +22,11 @@
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#ifndef PLUGINDLLEXPORT #ifndef PLUGINDLLEXPORT
# if defined (PLUGINDLLEXPORT_PRO) #if defined( PLUGINDLLEXPORT_PRO )
# define PLUGINDLLEXPORT Q_DECL_EXPORT #define PLUGINDLLEXPORT Q_DECL_EXPORT
# else #else
# define PLUGINDLLEXPORT Q_DECL_IMPORT #define PLUGINDLLEXPORT Q_DECL_IMPORT
# endif #endif
#endif #endif
#endif #endif

View File

@ -25,7 +25,8 @@
#include <QDir> #include <QDir>
#include <QProcess> #include <QProcess>
namespace Calamares { namespace Calamares
{
ProcessJob::ProcessJob( const QString& command, ProcessJob::ProcessJob( const QString& command,
@ -38,27 +39,24 @@ ProcessJob::ProcessJob( const QString& command,
, m_workingPath( workingPath ) , m_workingPath( workingPath )
, m_runInChroot( runInChroot ) , m_runInChroot( runInChroot )
, m_timeoutSec( secondsTimeout ) , m_timeoutSec( secondsTimeout )
{} {
}
ProcessJob::~ProcessJob() ProcessJob::~ProcessJob() {}
{}
QString QString
ProcessJob::prettyName() const ProcessJob::prettyName() const
{ {
return ( m_runInChroot ? tr( "Run command '%1' in target system." ) : tr( " Run command '%1'." ) ) return ( m_runInChroot ? tr( "Run command '%1' in target system." ) : tr( " Run command '%1'." ) ).arg( m_command );
.arg( m_command );
} }
QString QString
ProcessJob::prettyStatusMessage() const ProcessJob::prettyStatusMessage() const
{ {
return tr( "Running command %1 %2" ) return tr( "Running command %1 %2" ).arg( m_command ).arg( m_runInChroot ? "in chroot." : " ." );
.arg( m_command )
.arg( m_runInChroot ? "in chroot." : " ." );
} }
@ -68,15 +66,11 @@ ProcessJob::exec()
using CalamaresUtils::System; using CalamaresUtils::System;
if ( m_runInChroot ) if ( m_runInChroot )
return CalamaresUtils::System::instance()-> return CalamaresUtils::System::instance()
targetEnvCommand( { m_command }, ->targetEnvCommand( { m_command }, m_workingPath, QString(), m_timeoutSec )
m_workingPath,
QString(),
m_timeoutSec )
.explainProcess( m_command, m_timeoutSec ); .explainProcess( m_command, m_timeoutSec );
else else
return return System::runCommand( System::RunLocation::RunInHost,
System::runCommand( System::RunLocation::RunInHost,
{ "/bin/sh", "-c", m_command }, { "/bin/sh", "-c", m_command },
m_workingPath, m_workingPath,
QString(), QString(),

View File

@ -24,7 +24,8 @@
#include <chrono> #include <chrono>
namespace Calamares { namespace Calamares
{
class ProcessJob : public Job class ProcessJob : public Job
{ {
@ -33,7 +34,7 @@ public:
explicit ProcessJob( const QString& command, explicit ProcessJob( const QString& command,
const QString& workingPath, const QString& workingPath,
bool runInChroot = false, bool runInChroot = false,
std::chrono::seconds secondsTimeout = std::chrono::seconds(30), std::chrono::seconds secondsTimeout = std::chrono::seconds( 30 ),
QObject* parent = nullptr ); QObject* parent = nullptr );
virtual ~ProcessJob() override; virtual ~ProcessJob() override;

View File

@ -72,25 +72,39 @@ variantFromPyObject( const boost::python::object& pyObject )
{ {
std::string pyType = bp::extract< std::string >( pyObject.attr( "__class__" ).attr( "__name__" ) ); std::string pyType = bp::extract< std::string >( pyObject.attr( "__class__" ).attr( "__name__" ) );
if ( pyType == "dict" ) if ( pyType == "dict" )
{
return variantMapFromPyDict( bp::extract< bp::dict >( pyObject ) ); return variantMapFromPyDict( bp::extract< bp::dict >( pyObject ) );
}
else if ( pyType == "list" ) else if ( pyType == "list" )
{
return variantListFromPyList( bp::extract< bp::list >( pyObject ) ); return variantListFromPyList( bp::extract< bp::list >( pyObject ) );
}
else if ( pyType == "int" ) else if ( pyType == "int" )
{
return QVariant( bp::extract< int >( pyObject ) ); return QVariant( bp::extract< int >( pyObject ) );
}
else if ( pyType == "float" ) else if ( pyType == "float" )
{
return QVariant( bp::extract< double >( pyObject ) ); return QVariant( bp::extract< double >( pyObject ) );
}
else if ( pyType == "str" ) else if ( pyType == "str" )
{
return QVariant( QString::fromStdString( bp::extract< std::string >( pyObject ) ) ); return QVariant( QString::fromStdString( bp::extract< std::string >( pyObject ) ) );
}
else if ( pyType == "bool" ) else if ( pyType == "bool" )
{
return QVariant( bp::extract< bool >( pyObject ) ); return QVariant( bp::extract< bool >( pyObject ) );
}
else else
{
return QVariant(); return QVariant();
}
} }
@ -99,7 +113,9 @@ variantListToPyList( const QVariantList& variantList )
{ {
bp::list pyList; bp::list pyList;
for ( const QVariant& variant : variantList ) for ( const QVariant& variant : variantList )
{
pyList.append( variantToPyObject( variant ) ); pyList.append( variantToPyObject( variant ) );
}
return pyList; return pyList;
} }
@ -109,7 +125,9 @@ variantListFromPyList( const boost::python::list& pyList )
{ {
QVariantList list; QVariantList list;
for ( int i = 0; i < bp::len( pyList ); ++i ) for ( int i = 0; i < bp::len( pyList ); ++i )
{
list.append( variantFromPyObject( pyList[ i ] ) ); list.append( variantFromPyObject( pyList[ i ] ) );
}
return list; return list;
} }
@ -119,7 +137,9 @@ variantMapToPyDict( const QVariantMap& variantMap )
{ {
bp::dict pyDict; bp::dict pyDict;
for ( auto it = variantMap.constBegin(); it != variantMap.constEnd(); ++it ) for ( auto it = variantMap.constBegin(); it != variantMap.constEnd(); ++it )
{
pyDict[ it.key().toStdString() ] = variantToPyObject( it.value() ); pyDict[ it.key().toStdString() ] = variantToPyObject( it.value() );
}
return pyDict; return pyDict;
} }
@ -152,7 +172,9 @@ variantHashToPyDict( const QVariantHash& variantHash )
{ {
bp::dict pyDict; bp::dict pyDict;
for ( auto it = variantHash.constBegin(); it != variantHash.constEnd(); ++it ) for ( auto it = variantHash.constBegin(); it != variantHash.constEnd(); ++it )
{
pyDict[ it.key().toStdString() ] = variantToPyObject( it.value() ); pyDict[ it.key().toStdString() ] = variantToPyObject( it.value() );
}
return pyDict; return pyDict;
} }
@ -181,17 +203,21 @@ variantHashFromPyDict( const boost::python::dict& pyDict )
} }
Helper* Helper::s_instance = nullptr; Helper* Helper::s_instance = nullptr;
static inline void add_if_lib_exists( const QDir& dir, const char* name, QStringList& list ) static inline void
add_if_lib_exists( const QDir& dir, const char* name, QStringList& list )
{ {
if ( ! ( dir.exists() && dir.isReadable() ) ) if ( !( dir.exists() && dir.isReadable() ) )
{
return; return;
}
QFileInfo fi( dir.absoluteFilePath( name ) ); QFileInfo fi( dir.absoluteFilePath( name ) );
if ( fi.exists() && fi.isReadable() ) if ( fi.exists() && fi.isReadable() )
{
list.append( fi.dir().absolutePath() ); list.append( fi.dir().absolutePath() );
}
} }
Helper::Helper( QObject* parent ) Helper::Helper( QObject* parent )
@ -201,7 +227,9 @@ Helper::Helper( QObject* parent )
if ( !s_instance ) if ( !s_instance )
{ {
if ( !Py_IsInitialized() ) if ( !Py_IsInitialized() )
{
Py_Initialize(); Py_Initialize();
}
m_mainModule = bp::import( "__main__" ); m_mainModule = bp::import( "__main__" );
m_mainNamespace = m_mainModule.attr( "__dict__" ); m_mainNamespace = m_mainModule.attr( "__dict__" );
@ -209,8 +237,7 @@ Helper::Helper( QObject* parent )
// If we're running from the build dir // If we're running from the build dir
add_if_lib_exists( QDir::current(), "libcalamares.so", m_pythonPaths ); add_if_lib_exists( QDir::current(), "libcalamares.so", m_pythonPaths );
QDir calaPythonPath( CalamaresUtils::systemLibDir().absolutePath() + QDir calaPythonPath( CalamaresUtils::systemLibDir().absolutePath() + QDir::separator() + "calamares" );
QDir::separator() + "calamares" );
add_if_lib_exists( calaPythonPath, "libcalamares.so", m_pythonPaths ); add_if_lib_exists( calaPythonPath, "libcalamares.so", m_pythonPaths );
bp::object sys = bp::import( "sys" ); bp::object sys = bp::import( "sys" );
@ -251,7 +278,7 @@ Helper::createCleanNamespace()
QString QString
Helper::handleLastError() Helper::handleLastError()
{ {
PyObject* type = nullptr, *val = nullptr, *traceback_p = nullptr; PyObject *type = nullptr, *val = nullptr, *traceback_p = nullptr;
PyErr_Fetch( &type, &val, &traceback_p ); PyErr_Fetch( &type, &val, &traceback_p );
Logger::CDebug debug; Logger::CDebug debug;
@ -264,10 +291,14 @@ Helper::handleLastError()
bp::str pystr( h_type ); bp::str pystr( h_type );
bp::extract< std::string > extracted( pystr ); bp::extract< std::string > extracted( pystr );
if ( extracted.check() ) if ( extracted.check() )
{
typeMsg = QString::fromStdString( extracted() ).trimmed(); typeMsg = QString::fromStdString( extracted() ).trimmed();
}
if ( typeMsg.isEmpty() ) if ( typeMsg.isEmpty() )
{
typeMsg = tr( "Unknown exception type" ); typeMsg = tr( "Unknown exception type" );
}
debug << typeMsg << '\n'; debug << typeMsg << '\n';
} }
@ -278,10 +309,14 @@ Helper::handleLastError()
bp::str pystr( h_val ); bp::str pystr( h_val );
bp::extract< std::string > extracted( pystr ); bp::extract< std::string > extracted( pystr );
if ( extracted.check() ) if ( extracted.check() )
{
valMsg = QString::fromStdString( extracted() ).trimmed(); valMsg = QString::fromStdString( extracted() ).trimmed();
}
if ( valMsg.isEmpty() ) if ( valMsg.isEmpty() )
{
valMsg = tr( "unparseable Python error" ); valMsg = tr( "unparseable Python error" );
}
// Special-case: CalledProcessError has an attribute "output" with the command output, // Special-case: CalledProcessError has an attribute "output" with the command output,
// add that to the printed message. // add that to the printed message.
@ -318,22 +353,32 @@ Helper::handleLastError()
bp::object pystr( bp::str( "\n" ).join( tb_list ) ); bp::object pystr( bp::str( "\n" ).join( tb_list ) );
bp::extract< std::string > extracted( pystr ); bp::extract< std::string > extracted( pystr );
if ( extracted.check() ) if ( extracted.check() )
{
tbMsg = QString::fromStdString( extracted() ).trimmed(); tbMsg = QString::fromStdString( extracted() ).trimmed();
}
if ( tbMsg.isEmpty() ) if ( tbMsg.isEmpty() )
{
tbMsg = tr( "unparseable Python traceback" ); tbMsg = tr( "unparseable Python traceback" );
}
debug << tbMsg << '\n'; debug << tbMsg << '\n';
} }
if ( typeMsg.isEmpty() && valMsg.isEmpty() && tbMsg.isEmpty() ) if ( typeMsg.isEmpty() && valMsg.isEmpty() && tbMsg.isEmpty() )
{
return tr( "Unfetchable Python error." ); return tr( "Unfetchable Python error." );
}
QStringList msgList; QStringList msgList;
if ( !typeMsg.isEmpty() ) if ( !typeMsg.isEmpty() )
{
msgList.append( QString( "<strong>%1</strong>" ).arg( typeMsg.toHtmlEscaped() ) ); msgList.append( QString( "<strong>%1</strong>" ).arg( typeMsg.toHtmlEscaped() ) );
}
if ( !valMsg.isEmpty() ) if ( !valMsg.isEmpty() )
{
msgList.append( valMsg.toHtmlEscaped() ); msgList.append( valMsg.toHtmlEscaped() );
}
if ( !tbMsg.isEmpty() ) if ( !tbMsg.isEmpty() )
{ {

View File

@ -66,6 +66,6 @@ private:
QStringList m_pythonPaths; QStringList m_pythonPaths;
}; };
} // namespace Calamares } // namespace CalamaresPython
#endif // CALAMARES_PYTHONJOBHELPER_H #endif // CALAMARES_PYTHONJOBHELPER_H

View File

@ -19,10 +19,10 @@
#include "PythonJob.h" #include "PythonJob.h"
#include "PythonHelper.h"
#include "utils/Logger.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "PythonHelper.h"
#include "utils/Logger.h"
#include <QDir> #include <QDir>
@ -35,27 +35,19 @@
namespace bp = boost::python; namespace bp = boost::python;
BOOST_PYTHON_FUNCTION_OVERLOADS( mount_overloads, BOOST_PYTHON_FUNCTION_OVERLOADS( mount_overloads, CalamaresPython::mount, 2, 4 );
CalamaresPython::mount, BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_str_overloads, CalamaresPython::target_env_call, 1, 3 );
2, 4 ); BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_list_overloads, CalamaresPython::target_env_call, 1, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_str_overloads, BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_call_str_overloads, CalamaresPython::check_target_env_call, 1, 3 );
CalamaresPython::target_env_call, BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_call_list_overloads, CalamaresPython::check_target_env_call, 1, 3 );
1, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_list_overloads,
CalamaresPython::target_env_call,
1, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_call_str_overloads,
CalamaresPython::check_target_env_call,
1, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_call_list_overloads,
CalamaresPython::check_target_env_call,
1, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_output_str_overloads, BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_output_str_overloads,
CalamaresPython::check_target_env_output, CalamaresPython::check_target_env_output,
1, 3 ); 1,
3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_output_list_overloads, BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_output_list_overloads,
CalamaresPython::check_target_env_output, CalamaresPython::check_target_env_output,
1, 3 ); 1,
3 );
BOOST_PYTHON_MODULE( libcalamares ) BOOST_PYTHON_MODULE( libcalamares )
{ {
bp::object package = bp::scope(); bp::object package = bp::scope();
@ -72,15 +64,14 @@ BOOST_PYTHON_MODULE( libcalamares )
.def_readonly( "pretty_name", &CalamaresPython::PythonJobInterface::prettyName ) .def_readonly( "pretty_name", &CalamaresPython::PythonJobInterface::prettyName )
.def_readonly( "working_path", &CalamaresPython::PythonJobInterface::workingPath ) .def_readonly( "working_path", &CalamaresPython::PythonJobInterface::workingPath )
.def_readonly( "configuration", &CalamaresPython::PythonJobInterface::configuration ) .def_readonly( "configuration", &CalamaresPython::PythonJobInterface::configuration )
.def( .def( "setprogress",
"setprogress",
&CalamaresPython::PythonJobInterface::setprogress, &CalamaresPython::PythonJobInterface::setprogress,
bp::args( "progress" ), bp::args( "progress" ),
"Reports the progress status of this job to Calamares, " "Reports the progress status of this job to Calamares, "
"as a real number between 0 and 1." "as a real number between 0 and 1." );
);
bp::class_< CalamaresPython::GlobalStoragePythonWrapper >( "GlobalStorage", bp::init< Calamares::GlobalStorage* >() ) bp::class_< CalamaresPython::GlobalStoragePythonWrapper >( "GlobalStorage",
bp::init< Calamares::GlobalStorage* >() )
.def( "contains", &CalamaresPython::GlobalStoragePythonWrapper::contains ) .def( "contains", &CalamaresPython::GlobalStoragePythonWrapper::contains )
.def( "count", &CalamaresPython::GlobalStoragePythonWrapper::count ) .def( "count", &CalamaresPython::GlobalStoragePythonWrapper::count )
.def( "insert", &CalamaresPython::GlobalStoragePythonWrapper::insert ) .def( "insert", &CalamaresPython::GlobalStoragePythonWrapper::insert )
@ -95,151 +86,88 @@ BOOST_PYTHON_MODULE( libcalamares )
Q_UNUSED( utilsScope ) Q_UNUSED( utilsScope )
bp::def( bp::def(
"debug", "debug", &CalamaresPython::debug, bp::args( "s" ), "Writes the given string to the Calamares debug stream." );
&CalamaresPython::debug, bp::def( "warning",
bp::args( "s" ),
"Writes the given string to the Calamares debug stream."
);
bp::def(
"warning",
&CalamaresPython::warning, &CalamaresPython::warning,
bp::args( "s" ), bp::args( "s" ),
"Writes the given string to the Calamares warning stream." "Writes the given string to the Calamares warning stream." );
);
bp::def( bp::def( "mount",
"mount",
&CalamaresPython::mount, &CalamaresPython::mount,
mount_overloads( mount_overloads( bp::args( "device_path", "mount_point", "filesystem_name", "options" ),
bp::args( "device_path",
"mount_point",
"filesystem_name",
"options" ),
"Runs the mount utility with the specified parameters.\n" "Runs the mount utility with the specified parameters.\n"
"Returns the program's exit code, or:\n" "Returns the program's exit code, or:\n"
"-1 = QProcess crash\n" "-1 = QProcess crash\n"
"-2 = QProcess cannot start\n" "-2 = QProcess cannot start\n"
"-3 = bad arguments" "-3 = bad arguments" ) );
)
);
bp::def( bp::def(
"target_env_call", "target_env_call",
static_cast< int (*)( const std::string&, static_cast< int ( * )( const std::string&, const std::string&, int ) >( &CalamaresPython::target_env_call ),
const std::string&, target_env_call_str_overloads( bp::args( "command", "stdin", "timeout" ),
int ) >( &CalamaresPython::target_env_call ),
target_env_call_str_overloads(
bp::args( "command",
"stdin",
"timeout" ),
"Runs the specified command in the chroot of the target system.\n" "Runs the specified command in the chroot of the target system.\n"
"Returns the program's exit code, or:\n" "Returns the program's exit code, or:\n"
"-1 = QProcess crash\n" "-1 = QProcess crash\n"
"-2 = QProcess cannot start\n" "-2 = QProcess cannot start\n"
"-3 = bad arguments\n" "-3 = bad arguments\n"
"-4 = QProcess timeout" "-4 = QProcess timeout" ) );
) bp::def( "target_env_call",
); static_cast< int ( * )( const bp::list&, const std::string&, int ) >( &CalamaresPython::target_env_call ),
bp::def( target_env_call_list_overloads( bp::args( "args", "stdin", "timeout" ),
"target_env_call",
static_cast< int (*)( const bp::list&,
const std::string&,
int ) >( &CalamaresPython::target_env_call ),
target_env_call_list_overloads(
bp::args( "args",
"stdin",
"timeout" ),
"Runs the specified command in the chroot of the target system.\n" "Runs the specified command in the chroot of the target system.\n"
"Returns the program's exit code, or:\n" "Returns the program's exit code, or:\n"
"-1 = QProcess crash\n" "-1 = QProcess crash\n"
"-2 = QProcess cannot start\n" "-2 = QProcess cannot start\n"
"-3 = bad arguments\n" "-3 = bad arguments\n"
"-4 = QProcess timeout" "-4 = QProcess timeout" ) );
)
);
bp::def( bp::def( "check_target_env_call",
"check_target_env_call", static_cast< int ( * )( const std::string&, const std::string&, int ) >(
static_cast< int (*)( const std::string&, &CalamaresPython::check_target_env_call ),
const std::string&, check_target_env_call_str_overloads( bp::args( "command", "stdin", "timeout" ),
int ) >( &CalamaresPython::check_target_env_call ),
check_target_env_call_str_overloads(
bp::args( "command",
"stdin",
"timeout" ),
"Runs the specified command in the chroot of the target system.\n" "Runs the specified command in the chroot of the target system.\n"
"Returns 0, which is program's exit code if the program exited " "Returns 0, which is program's exit code if the program exited "
"successfully, or raises a subprocess.CalledProcessError." "successfully, or raises a subprocess.CalledProcessError." ) );
)
);
bp::def( bp::def(
"check_target_env_call", "check_target_env_call",
static_cast< int (*)( const bp::list&, static_cast< int ( * )( const bp::list&, const std::string&, int ) >( &CalamaresPython::check_target_env_call ),
const std::string&, check_target_env_call_list_overloads( bp::args( "args", "stdin", "timeout" ),
int ) >( &CalamaresPython::check_target_env_call ),
check_target_env_call_list_overloads(
bp::args( "args",
"stdin",
"timeout" ),
"Runs the specified command in the chroot of the target system.\n" "Runs the specified command in the chroot of the target system.\n"
"Returns 0, which is program's exit code if the program exited " "Returns 0, which is program's exit code if the program exited "
"successfully, or raises a subprocess.CalledProcessError." "successfully, or raises a subprocess.CalledProcessError." ) );
)
);
bp::def( bp::def( "check_target_env_output",
"check_target_env_output", static_cast< std::string ( * )( const std::string&, const std::string&, int ) >(
static_cast< std::string (*)( const std::string&, &CalamaresPython::check_target_env_output ),
const std::string&, check_target_env_output_str_overloads( bp::args( "command", "stdin", "timeout" ),
int ) >( &CalamaresPython::check_target_env_output ),
check_target_env_output_str_overloads(
bp::args( "command",
"stdin",
"timeout" ),
"Runs the specified command in the chroot of the target system.\n" "Runs the specified command in the chroot of the target system.\n"
"Returns the program's standard output, and raises a " "Returns the program's standard output, and raises a "
"subprocess.CalledProcessError if something went wrong." "subprocess.CalledProcessError if something went wrong." ) );
) bp::def( "check_target_env_output",
); static_cast< std::string ( * )( const bp::list&, const std::string&, int ) >(
bp::def( &CalamaresPython::check_target_env_output ),
"check_target_env_output", check_target_env_output_list_overloads( bp::args( "args", "stdin", "timeout" ),
static_cast< std::string (*)( const bp::list&,
const std::string&,
int ) >( &CalamaresPython::check_target_env_output ),
check_target_env_output_list_overloads(
bp::args( "args",
"stdin",
"timeout" ),
"Runs the specified command in the chroot of the target system.\n" "Runs the specified command in the chroot of the target system.\n"
"Returns the program's standard output, and raises a " "Returns the program's standard output, and raises a "
"subprocess.CalledProcessError if something went wrong." "subprocess.CalledProcessError if something went wrong." ) );
) bp::def( "obscure",
);
bp::def(
"obscure",
&CalamaresPython::obscure, &CalamaresPython::obscure,
bp::args( "s" ), bp::args( "s" ),
"Simple string obfuscation function based on KStringHandler::obscure.\n" "Simple string obfuscation function based on KStringHandler::obscure.\n"
"Returns a string, generated using a simple symmetric encryption.\n" "Returns a string, generated using a simple symmetric encryption.\n"
"Applying the function to a string obscured by this function will result " "Applying the function to a string obscured by this function will result "
"in the original string." "in the original string." );
);
bp::def( bp::def( "gettext_languages",
"gettext_languages",
&CalamaresPython::gettext_languages, &CalamaresPython::gettext_languages,
"Returns list of languages (most to least-specific) for gettext." "Returns list of languages (most to least-specific) for gettext." );
);
bp::def( bp::def( "gettext_path", &CalamaresPython::gettext_path, "Returns path for gettext search." );
"gettext_path",
&CalamaresPython::gettext_path,
"Returns path for gettext search."
);
} }
namespace Calamares { namespace Calamares
{
PythonJob::PythonJob( const QString& scriptFile, PythonJob::PythonJob( const QString& scriptFile,
@ -255,8 +183,7 @@ PythonJob::PythonJob( const QString& scriptFile,
} }
PythonJob::~PythonJob() PythonJob::~PythonJob() {}
{}
QString QString
@ -270,10 +197,13 @@ QString
PythonJob::prettyStatusMessage() const PythonJob::prettyStatusMessage() const
{ {
if ( m_description.isEmpty() ) if ( m_description.isEmpty() )
return tr( "Running %1 operation." ) {
.arg( QDir( m_workingPath ).dirName() ); return tr( "Running %1 operation." ).arg( QDir( m_workingPath ).dirName() );
}
else else
{
return m_description; return m_description;
}
} }
@ -282,19 +212,15 @@ PythonJob::exec()
{ {
// We assume m_scriptFile to be relative to m_workingPath. // We assume m_scriptFile to be relative to m_workingPath.
QDir workingDir( m_workingPath ); QDir workingDir( m_workingPath );
if ( !workingDir.exists() || if ( !workingDir.exists() || !workingDir.isReadable() )
!workingDir.isReadable() )
{ {
return JobResult::error( tr( "Bad working directory path" ), return JobResult::error(
tr( "Working directory %1 for python job %2 is not readable." ) tr( "Bad working directory path" ),
.arg( m_workingPath ) tr( "Working directory %1 for python job %2 is not readable." ).arg( m_workingPath ).arg( prettyName() ) );
.arg( prettyName() ) );
} }
QFileInfo scriptFI( workingDir.absoluteFilePath( m_scriptFile ) ); QFileInfo scriptFI( workingDir.absoluteFilePath( m_scriptFile ) );
if ( !scriptFI.exists() || if ( !scriptFI.exists() || !scriptFI.isFile() || !scriptFI.isReadable() )
!scriptFI.isFile() ||
!scriptFI.isReadable() )
{ {
return JobResult::error( tr( "Bad main script file" ), return JobResult::error( tr( "Bad main script file" ),
tr( "Main script file %1 for python job %2 is not readable." ) tr( "Main script file %1 for python job %2 is not readable." )
@ -310,15 +236,14 @@ PythonJob::exec()
bp::dict calamaresNamespace = bp::extract< bp::dict >( calamaresModule.attr( "__dict__" ) ); bp::dict calamaresNamespace = bp::extract< bp::dict >( calamaresModule.attr( "__dict__" ) );
calamaresNamespace[ "job" ] = CalamaresPython::PythonJobInterface( this ); calamaresNamespace[ "job" ] = CalamaresPython::PythonJobInterface( this );
calamaresNamespace[ "globalstorage" ] = CalamaresPython::GlobalStoragePythonWrapper( calamaresNamespace[ "globalstorage" ]
JobQueue::instance()->globalStorage() ); = CalamaresPython::GlobalStoragePythonWrapper( JobQueue::instance()->globalStorage() );
bp::object execResult = bp::exec_file( scriptFI.absoluteFilePath().toLocal8Bit().data(), bp::object execResult
scriptNamespace, = bp::exec_file( scriptFI.absoluteFilePath().toLocal8Bit().data(), scriptNamespace, scriptNamespace );
scriptNamespace );
bp::object entryPoint = scriptNamespace[ "run" ]; bp::object entryPoint = scriptNamespace[ "run" ];
bp::object prettyNameFunc = scriptNamespace.get("pretty_name", bp::object()); bp::object prettyNameFunc = scriptNamespace.get( "pretty_name", bp::object() );
cDebug() << "Job file" << scriptFI.absoluteFilePath(); cDebug() << "Job file" << scriptFI.absoluteFilePath();
if ( !prettyNameFunc.is_none() ) if ( !prettyNameFunc.is_none() )
@ -337,14 +262,16 @@ PythonJob::exec()
if ( m_description.isEmpty() ) if ( m_description.isEmpty() )
{ {
bp::extract< std::string > entryPoint_doc_attr(entryPoint.attr( "__doc__" ) ); bp::extract< std::string > entryPoint_doc_attr( entryPoint.attr( "__doc__" ) );
if ( entryPoint_doc_attr.check() ) if ( entryPoint_doc_attr.check() )
{ {
m_description = QString::fromStdString( entryPoint_doc_attr() ).trimmed(); m_description = QString::fromStdString( entryPoint_doc_attr() ).trimmed();
auto i_newline = m_description.indexOf('\n'); auto i_newline = m_description.indexOf( '\n' );
if ( i_newline > 0 ) if ( i_newline > 0 )
{
m_description.truncate( i_newline ); m_description.truncate( i_newline );
}
cDebug() << "Job description from __doc__" << prettyName() << "=" << m_description; cDebug() << "Job description from __doc__" << prettyName() << "=" << m_description;
emit progress( 0 ); emit progress( 0 );
} }
@ -374,9 +301,7 @@ PythonJob::exec()
bp::handle_exception(); bp::handle_exception();
PyErr_Clear(); PyErr_Clear();
return JobResult::internalError( return JobResult::internalError(
tr( "Boost.Python error in job \"%1\"." ).arg( prettyName() ), tr( "Boost.Python error in job \"%1\"." ).arg( prettyName() ), msg, JobResult::PythonUncaughtException );
msg,
JobResult::PythonUncaughtException );
} }
} }
@ -392,8 +317,10 @@ CalamaresPython::Helper*
PythonJob::helper() PythonJob::helper()
{ {
auto ptr = CalamaresPython::Helper::s_instance; auto ptr = CalamaresPython::Helper::s_instance;
if (!ptr) if ( !ptr )
{
ptr = new CalamaresPython::Helper; ptr = new CalamaresPython::Helper;
}
return ptr; return ptr;
} }

View File

@ -27,9 +27,10 @@ namespace CalamaresPython
{ {
class PythonJobInterface; class PythonJobInterface;
class Helper; class Helper;
} } // namespace CalamaresPython
namespace Calamares { namespace Calamares
{
class PythonJob : public Job class PythonJob : public Job
{ {

View File

@ -20,8 +20,8 @@
#include "PythonJobApi.h" #include "PythonJobApi.h"
#include "PythonHelper.h" #include "PythonHelper.h"
#include "utils/Logger.h"
#include "utils/CalamaresUtilsSystem.h" #include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include "utils/String.h" #include "utils/String.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
@ -40,15 +40,19 @@ static int
_handle_check_target_env_call_error( const CalamaresUtils::ProcessResult& ec, const QString& cmd ) _handle_check_target_env_call_error( const CalamaresUtils::ProcessResult& ec, const QString& cmd )
{ {
if ( !ec.first ) if ( !ec.first )
{
return ec.first; return ec.first;
}
QString raise = QString( "import subprocess\n" QString raise = QString( "import subprocess\n"
"e = subprocess.CalledProcessError(%1,\"%2\")\n" ) "e = subprocess.CalledProcessError(%1,\"%2\")\n" )
.arg( ec.first ) .arg( ec.first )
.arg( cmd ); .arg( cmd );
if ( !ec.second.isEmpty() ) if ( !ec.second.isEmpty() )
raise.append( QStringLiteral("e.output = \"\"\"%1\"\"\"\n").arg( ec.second ) ); {
raise.append("raise e"); raise.append( QStringLiteral( "e.output = \"\"\"%1\"\"\"\n" ).arg( ec.second ) );
}
raise.append( "raise e" );
bp::exec( raise.toStdString().c_str() ); bp::exec( raise.toStdString().c_str() );
bp::throw_error_already_set(); bp::throw_error_already_set();
return ec.first; return ec.first;
@ -63,8 +67,7 @@ mount( const std::string& device_path,
const std::string& filesystem_name, const std::string& filesystem_name,
const std::string& options ) const std::string& options )
{ {
return CalamaresUtils::System::instance()-> return CalamaresUtils::System::instance()->mount( QString::fromStdString( device_path ),
mount( QString::fromStdString( device_path ),
QString::fromStdString( mount_point ), QString::fromStdString( mount_point ),
QString::fromStdString( filesystem_name ), QString::fromStdString( filesystem_name ),
QString::fromStdString( options ) ); QString::fromStdString( options ) );
@ -77,66 +80,50 @@ _bp_list_to_qstringlist( const bp::list& args )
QStringList list; QStringList list;
for ( int i = 0; i < bp::len( args ); ++i ) for ( int i = 0; i < bp::len( args ); ++i )
{ {
list.append( QString::fromStdString( list.append( QString::fromStdString( bp::extract< std::string >( args[ i ] ) ) );
bp::extract< std::string >( args[ i ] ) ) );
} }
return list; return list;
} }
static inline CalamaresUtils::ProcessResult static inline CalamaresUtils::ProcessResult
_target_env_command( _target_env_command( const QStringList& args, const std::string& stdin, int timeout )
const QStringList& args,
const std::string& stdin,
int timeout )
{ {
// Since Python doesn't give us the type system for distinguishing // Since Python doesn't give us the type system for distinguishing
// seconds from other integral types, massage to seconds here. // seconds from other integral types, massage to seconds here.
return CalamaresUtils::System::instance()-> return CalamaresUtils::System::instance()->targetEnvCommand(
targetEnvCommand( args, args, QString(), QString::fromStdString( stdin ), std::chrono::seconds( timeout ) );
QString(),
QString::fromStdString( stdin ),
std::chrono::seconds( timeout ) );
} }
int int
target_env_call( const std::string& command, target_env_call( const std::string& command, const std::string& stdin, int timeout )
const std::string& stdin,
int timeout )
{ {
return _target_env_command( return _target_env_command( QStringList { QString::fromStdString( command ) }, stdin, timeout ).first;
QStringList{ QString::fromStdString( command ) }, stdin, timeout ).first;
} }
int int
target_env_call( const bp::list& args, target_env_call( const bp::list& args, const std::string& stdin, int timeout )
const std::string& stdin,
int timeout )
{ {
return _target_env_command( return _target_env_command( _bp_list_to_qstringlist( args ), stdin, timeout ).first;
_bp_list_to_qstringlist( args ), stdin, timeout ).first;
} }
int int
check_target_env_call( const std::string& command, check_target_env_call( const std::string& command, const std::string& stdin, int timeout )
const std::string& stdin,
int timeout )
{ {
auto ec = _target_env_command( auto ec = _target_env_command( QStringList { QString::fromStdString( command ) }, stdin, timeout );
QStringList{ QString::fromStdString( command ) }, stdin, timeout );
return _handle_check_target_env_call_error( ec, QString::fromStdString( command ) ); return _handle_check_target_env_call_error( ec, QString::fromStdString( command ) );
} }
int int
check_target_env_call( const bp::list& args, check_target_env_call( const bp::list& args, const std::string& stdin, int timeout )
const std::string& stdin,
int timeout )
{ {
auto ec = _target_env_command( _bp_list_to_qstringlist( args ), stdin, timeout ); auto ec = _target_env_command( _bp_list_to_qstringlist( args ), stdin, timeout );
if ( !ec.first ) if ( !ec.first )
{
return ec.first; return ec.first;
}
QStringList failedCmdList = _bp_list_to_qstringlist( args ); QStringList failedCmdList = _bp_list_to_qstringlist( args );
return _handle_check_target_env_call_error( ec, failedCmdList.join( ' ' ) ); return _handle_check_target_env_call_error( ec, failedCmdList.join( ' ' ) );
@ -144,25 +131,19 @@ check_target_env_call( const bp::list& args,
std::string std::string
check_target_env_output( const std::string& command, check_target_env_output( const std::string& command, const std::string& stdin, int timeout )
const std::string& stdin,
int timeout )
{ {
auto ec = _target_env_command( auto ec = _target_env_command( QStringList { QString::fromStdString( command ) }, stdin, timeout );
QStringList{ QString::fromStdString( command ) }, stdin, timeout );
_handle_check_target_env_call_error( ec, QString::fromStdString( command ) ); _handle_check_target_env_call_error( ec, QString::fromStdString( command ) );
return ec.second.toStdString(); return ec.second.toStdString();
} }
std::string std::string
check_target_env_output( const bp::list& args, check_target_env_output( const bp::list& args, const std::string& stdin, int timeout )
const std::string& stdin,
int timeout )
{ {
QStringList list = _bp_list_to_qstringlist( args ); QStringList list = _bp_list_to_qstringlist( args );
auto ec = _target_env_command( auto ec = _target_env_command( list, stdin, timeout );
list, stdin, timeout );
_handle_check_target_env_call_error( ec, list.join( ' ' ) ); _handle_check_target_env_call_error( ec, list.join( ' ' ) );
return ec.second.toStdString(); return ec.second.toStdString();
} }
@ -194,7 +175,9 @@ void
PythonJobInterface::setprogress( qreal progress ) PythonJobInterface::setprogress( qreal progress )
{ {
if ( progress >= 0 && progress <= 1 ) if ( progress >= 0 && progress <= 1 )
{
m_parent->emitProgress( progress ); m_parent->emitProgress( progress );
}
} }
@ -216,7 +199,8 @@ _gettext_languages()
// own GlobalStoragePythonWrapper, which then holds a // own GlobalStoragePythonWrapper, which then holds a
// GlobalStorage object for all of Python. // GlobalStorage object for all of Python.
Calamares::JobQueue* jq = Calamares::JobQueue::instance(); Calamares::JobQueue* jq = Calamares::JobQueue::instance();
Calamares::GlobalStorage* gs = jq ? jq->globalStorage() : CalamaresPython::GlobalStoragePythonWrapper::globalStorageInstance(); Calamares::GlobalStorage* gs
= jq ? jq->globalStorage() : CalamaresPython::GlobalStoragePythonWrapper::globalStorageInstance();
QVariant localeConf_ = gs->value( "localeConf" ); QVariant localeConf_ = gs->value( "localeConf" );
if ( localeConf_.canConvert< QVariantMap >() ) if ( localeConf_.canConvert< QVariantMap >() )
@ -246,7 +230,9 @@ gettext_languages()
{ {
bp::list pyList; bp::list pyList;
for ( auto lang : _gettext_languages() ) for ( auto lang : _gettext_languages() )
{
pyList.append( lang.toStdString() ); pyList.append( lang.toStdString() );
}
return pyList; return pyList;
} }
@ -257,8 +243,10 @@ _add_localedirs( QStringList& pathList, const QString& candidate )
{ {
pathList.prepend( candidate ); pathList.prepend( candidate );
if ( QDir( candidate ).cd( "lang" ) ) if ( QDir( candidate ).cd( "lang" ) )
{
pathList.prepend( candidate + "/lang" ); pathList.prepend( candidate + "/lang" );
} }
}
} }
bp::object bp::object
@ -266,15 +254,18 @@ gettext_path()
{ {
// TODO: distinguish between -d runs and normal runs // TODO: distinguish between -d runs and normal runs
// TODO: can we detect DESTDIR-installs? // TODO: can we detect DESTDIR-installs?
QStringList candidatePaths = QStandardPaths::locateAll( QStandardPaths::GenericDataLocation, "locale", QStandardPaths::LocateDirectory ); QStringList candidatePaths
= QStandardPaths::locateAll( QStandardPaths::GenericDataLocation, "locale", QStandardPaths::LocateDirectory );
QString extra = QCoreApplication::applicationDirPath(); QString extra = QCoreApplication::applicationDirPath();
_add_localedirs( candidatePaths, extra ); // Often /usr/local/bin _add_localedirs( candidatePaths, extra ); // Often /usr/local/bin
if ( !extra.isEmpty() ) if ( !extra.isEmpty() )
{ {
QDir d( extra ); QDir d( extra );
if ( d.cd( "../share/locale" ) ) // Often /usr/local/bin/../share/locale -> /usr/local/share/locale if ( d.cd( "../share/locale" ) ) // Often /usr/local/bin/../share/locale -> /usr/local/share/locale
{
_add_localedirs( candidatePaths, d.canonicalPath() ); _add_localedirs( candidatePaths, d.canonicalPath() );
} }
}
_add_localedirs( candidatePaths, QDir().canonicalPath() ); // . _add_localedirs( candidatePaths, QDir().canonicalPath() ); // .
cDebug() << "Determining gettext path from" << candidatePaths; cDebug() << "Determining gettext path from" << candidatePaths;
@ -296,4 +287,4 @@ gettext_path()
} }
} } // namespace CalamaresPython

View File

@ -35,29 +35,19 @@ int mount( const std::string& device_path,
const std::string& filesystem_name = std::string(), const std::string& filesystem_name = std::string(),
const std::string& options = std::string() ); const std::string& options = std::string() );
int target_env_call( const std::string& command, int target_env_call( const std::string& command, const std::string& stdin = std::string(), int timeout = 0 );
const std::string& stdin = std::string(),
int timeout = 0 );
int target_env_call( const boost::python::list& args, int target_env_call( const boost::python::list& args, const std::string& stdin = std::string(), int timeout = 0 );
const std::string& stdin = std::string(),
int timeout = 0 );
int check_target_env_call( const std::string& command, int check_target_env_call( const std::string& command, const std::string& stdin = std::string(), int timeout = 0 );
const std::string& stdin = std::string(),
int timeout = 0 );
int check_target_env_call( const boost::python::list& args, int check_target_env_call( const boost::python::list& args, const std::string& stdin = std::string(), int timeout = 0 );
const std::string& stdin = std::string(),
int timeout = 0 );
std::string check_target_env_output( const std::string& command, std::string
const std::string& stdin = std::string(), check_target_env_output( const std::string& command, const std::string& stdin = std::string(), int timeout = 0 );
int timeout = 0 );
std::string check_target_env_output( const boost::python::list& args, std::string
const std::string& stdin = std::string(), check_target_env_output( const boost::python::list& args, const std::string& stdin = std::string(), int timeout = 0 );
int timeout = 0 );
std::string obscure( const std::string& string ); std::string obscure( const std::string& string );
@ -85,6 +75,6 @@ private:
Calamares::PythonJob* m_parent; Calamares::PythonJob* m_parent;
}; };
} } // namespace CalamaresPython
#endif // PYTHONJOBAPI_H #endif // PYTHONJOBAPI_H

View File

@ -40,8 +40,10 @@ static QString
requireString( const YAML::Node& config, const char* key ) requireString( const YAML::Node& config, const char* key )
{ {
auto v = config[ key ]; auto v = config[ key ];
if ( hasValue(v) ) if ( hasValue( v ) )
{
return QString::fromStdString( v.as< std::string >() ); return QString::fromStdString( v.as< std::string >() );
}
else else
{ {
cWarning() << Logger::SubEntry << "Required settings.conf key" << key << "is missing."; cWarning() << Logger::SubEntry << "Required settings.conf key" << key << "is missing.";
@ -54,8 +56,10 @@ static bool
requireBool( const YAML::Node& config, const char* key, bool d ) requireBool( const YAML::Node& config, const char* key, bool d )
{ {
auto v = config[ key ]; auto v = config[ key ];
if ( hasValue(v) ) if ( hasValue( v ) )
{
return v.as< bool >(); return v.as< bool >();
}
else else
{ {
cWarning() << Logger::SubEntry << "Required settings.conf key" << key << "is missing."; cWarning() << Logger::SubEntry << "Required settings.conf key" << key << "is missing.";
@ -86,17 +90,17 @@ interpretModulesSearch( const bool debugMode, const QStringList& rawPaths, QStri
// module search path in the build dir. // module search path in the build dir.
if ( debugMode ) if ( debugMode )
{ {
QString buildDirModules = QDir::current().absolutePath() + QString buildDirModules
QDir::separator() + "src" + = QDir::current().absolutePath() + QDir::separator() + "src" + QDir::separator() + "modules";
QDir::separator() + "modules";
if ( QDir( buildDirModules ).exists() ) if ( QDir( buildDirModules ).exists() )
{
output.append( buildDirModules ); output.append( buildDirModules );
} }
}
// Install path is set in CalamaresAddPlugin.cmake // Install path is set in CalamaresAddPlugin.cmake
output.append( CalamaresUtils::systemLibDir().absolutePath() + output.append( CalamaresUtils::systemLibDir().absolutePath() + QDir::separator() + "calamares"
QDir::separator() + "calamares" + + QDir::separator() + "modules" );
QDir::separator() + "modules" );
} }
else else
{ {
@ -106,9 +110,11 @@ interpretModulesSearch( const bool debugMode, const QStringList& rawPaths, QStri
output.append( d.absolutePath() ); output.append( d.absolutePath() );
} }
else else
{
cDebug() << Logger::SubEntry << "module-search entry non-existent" << path; cDebug() << Logger::SubEntry << "module-search entry non-existent" << path;
} }
} }
}
} }
static void static void
@ -124,15 +130,17 @@ interpretInstances( const YAML::Node& node, Settings::InstanceDescriptionList& c
for ( const QVariant& instancesVListItem : instances ) for ( const QVariant& instancesVListItem : instances )
{ {
if ( instancesVListItem.type() != QVariant::Map ) if ( instancesVListItem.type() != QVariant::Map )
{
continue; continue;
QVariantMap instancesVListItemMap = }
instancesVListItem.toMap(); QVariantMap instancesVListItemMap = instancesVListItem.toMap();
Settings::InstanceDescription instanceMap; Settings::InstanceDescription instanceMap;
for ( auto it = instancesVListItemMap.constBegin(); for ( auto it = instancesVListItemMap.constBegin(); it != instancesVListItemMap.constEnd(); ++it )
it != instancesVListItemMap.constEnd(); ++it )
{ {
if ( it.value().type() != QVariant::String ) if ( it.value().type() != QVariant::String )
{
continue; continue;
}
instanceMap.insert( it.key(), it.value().toString() ); instanceMap.insert( it.key(), it.value().toString() );
} }
customInstances.append( instanceMap ); customInstances.append( instanceMap );
@ -149,37 +157,43 @@ interpretSequence( const YAML::Node& node, Settings::ModuleSequence& moduleSeque
{ {
QVariant sequenceV = CalamaresUtils::yamlToVariant( node ); QVariant sequenceV = CalamaresUtils::yamlToVariant( node );
if ( !( sequenceV.type() == QVariant::List ) ) if ( !( sequenceV.type() == QVariant::List ) )
{
throw YAML::Exception( YAML::Mark(), "sequence key does not have a list-value" ); throw YAML::Exception( YAML::Mark(), "sequence key does not have a list-value" );
}
const auto sequence = sequenceV.toList(); const auto sequence = sequenceV.toList();
for ( const QVariant& sequenceVListItem : sequence ) for ( const QVariant& sequenceVListItem : sequence )
{ {
if ( sequenceVListItem.type() != QVariant::Map ) if ( sequenceVListItem.type() != QVariant::Map )
{
continue; continue;
}
QString thisActionS = sequenceVListItem.toMap().firstKey(); QString thisActionS = sequenceVListItem.toMap().firstKey();
ModuleAction thisAction; ModuleAction thisAction;
if ( thisActionS == "show" ) if ( thisActionS == "show" )
{
thisAction = ModuleAction::Show; thisAction = ModuleAction::Show;
}
else if ( thisActionS == "exec" ) else if ( thisActionS == "exec" )
{
thisAction = ModuleAction::Exec; thisAction = ModuleAction::Exec;
}
else else
{
continue; continue;
}
QStringList thisActionRoster = sequenceVListItem QStringList thisActionRoster = sequenceVListItem.toMap().value( thisActionS ).toStringList();
.toMap() moduleSequence.append( qMakePair( thisAction, thisActionRoster ) );
.value( thisActionS )
.toStringList();
moduleSequence.append( qMakePair( thisAction,
thisActionRoster ) );
} }
} }
else else
{
throw YAML::Exception( YAML::Mark(), "sequence key is missing" ); throw YAML::Exception( YAML::Mark(), "sequence key is missing" );
}
} }
Settings::Settings( const QString& settingsFilePath, Settings::Settings( const QString& settingsFilePath, bool debugMode, QObject* parent )
bool debugMode,
QObject* parent )
: QObject( parent ) : QObject( parent )
, m_debug( debugMode ) , m_debug( debugMode )
, m_doChroot( true ) , m_doChroot( true )
@ -198,7 +212,8 @@ Settings::Settings( const QString& settingsFilePath,
YAML::Node config = YAML::Load( ba.constData() ); YAML::Node config = YAML::Load( ba.constData() );
Q_ASSERT( config.IsMap() ); Q_ASSERT( config.IsMap() );
interpretModulesSearch( debugMode, CalamaresUtils::yamlToStringList( config[ "modules-search" ] ), m_modulesSearchPaths ); interpretModulesSearch(
debugMode, CalamaresUtils::yamlToStringList( config[ "modules-search" ] ), m_modulesSearchPaths );
interpretInstances( config[ "instances" ], m_customModuleInstances ); interpretInstances( config[ "instances" ], m_customModuleInstances );
interpretSequence( config[ "sequence" ], m_modulesSequence ); interpretSequence( config[ "sequence" ], m_modulesSequence );
@ -283,4 +298,4 @@ Settings::disableCancelDuringExec() const
} }
} } // namespace Calamares

View File

@ -36,9 +36,7 @@ class DLLEXPORT Settings : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Settings( const QString& settingsFilePath, explicit Settings( const QString& settingsFilePath, bool debugMode, QObject* parent = nullptr );
bool debugMode,
QObject* parent = nullptr );
static Settings* instance(); static Settings* instance();
@ -88,6 +86,6 @@ private:
bool m_disableCancelDuringExec; bool m_disableCancelDuringExec;
}; };
} } // namespace Calamares
#endif // SETTINGS_H #endif // SETTINGS_H

View File

@ -16,6 +16,8 @@
*/ */
// BEGIN Generated from CLDR data // BEGIN Generated from CLDR data
// *INDENT-OFF*
// clang-format off
struct CountryData struct CountryData

View File

@ -50,18 +50,24 @@ Label::setLabels( const QString& locale, LabelFormat format )
QString countryName; QString countryName;
if ( languageName.isEmpty() ) if ( languageName.isEmpty() )
{
languageName = QString( "* %1 (%2)" ).arg( locale, englishName ); languageName = QString( "* %1 (%2)" ).arg( locale, englishName );
}
bool needsCountryName = ( format == LabelFormat::AlwaysWithCountry ) || bool needsCountryName = ( format == LabelFormat::AlwaysWithCountry )
(locale.contains( '_' ) && QLocale::countriesForLanguage( m_locale.language() ).count() > 1 ); || ( locale.contains( '_' ) && QLocale::countriesForLanguage( m_locale.language() ).count() > 1 );
if ( needsCountryName ) if ( needsCountryName )
{
countryName = m_locale.nativeCountryName(); countryName = m_locale.nativeCountryName();
}
m_label = needsCountryName ? longFormat.arg( languageName, countryName ) : languageName; m_label = needsCountryName ? longFormat.arg( languageName, countryName ) : languageName;
m_englishLabel = needsCountryName ? longFormat.arg( englishName, QLocale::countryToString( m_locale.country() ) ) : englishName; m_englishLabel = needsCountryName ? longFormat.arg( englishName, QLocale::countryToString( m_locale.country() ) )
: englishName;
} }
QLocale Label::getLocale( const QString& localeName ) QLocale
Label::getLocale( const QString& localeName )
{ {
if ( localeName.contains( "@latin" ) ) if ( localeName.contains( "@latin" ) )
{ {
@ -69,8 +75,10 @@ QLocale Label::getLocale( const QString& localeName )
return QLocale( loc.language(), QLocale::Script::LatinScript, loc.country() ); return QLocale( loc.language(), QLocale::Script::LatinScript, loc.country() );
} }
else else
{
return QLocale( localeName ); return QLocale( localeName );
}
} }
} } // namespace Locale
} // namespace } // namespace CalamaresUtils

View File

@ -39,7 +39,11 @@ class Label
{ {
public: public:
/** @brief Formatting option for label -- add (country) to label. */ /** @brief Formatting option for label -- add (country) to label. */
enum class LabelFormat { AlwaysWithCountry, IfNeededWithCountry } ; enum class LabelFormat
{
AlwaysWithCountry,
IfNeededWithCountry
};
/** @brief Empty locale. This uses the system-default locale. */ /** @brief Empty locale. This uses the system-default locale. */
Label(); Label();
@ -56,54 +60,30 @@ public:
* *
* English (@see isEnglish() -- it means en_US) is sorted at the top. * English (@see isEnglish() -- it means en_US) is sorted at the top.
*/ */
bool operator <( const Label& other ) const bool operator<( const Label& other ) const { return m_localeId < other.m_localeId; }
{
return m_localeId < other.m_localeId;
}
/** @brief Is this locale English? /** @brief Is this locale English?
* *
* en_US and en (American English) is defined as English. The Queen's * en_US and en (American English) is defined as English. The Queen's
* English -- proper English -- is relegated to non-English status. * English -- proper English -- is relegated to non-English status.
*/ */
bool isEnglish() const bool isEnglish() const { return m_localeId == QLatin1Literal( "en_US" ) || m_localeId == QLatin1Literal( "en" ); }
{
return m_localeId == QLatin1Literal( "en_US" ) || m_localeId == QLatin1Literal( "en" );
}
/** @brief Get the human-readable name for this locale. */ /** @brief Get the human-readable name for this locale. */
QString label() const QString label() const { return m_label; }
{
return m_label;
}
/** @brief Get the *English* human-readable name for this locale. */ /** @brief Get the *English* human-readable name for this locale. */
QString englishLabel() const QString englishLabel() const { return m_englishLabel; }
{
return m_englishLabel;
}
/** @brief Get the Qt locale. */ /** @brief Get the Qt locale. */
QLocale locale() const QLocale locale() const { return m_locale; }
{
return m_locale;
}
QString name() const QString name() const { return m_locale.name(); }
{
return m_locale.name();
}
/// @brief Convenience accessor to the language part of the locale /// @brief Convenience accessor to the language part of the locale
QLocale::Language language() const QLocale::Language language() const { return m_locale.language(); }
{
return m_locale.language();
}
/// @brief Convenience accessor to the country part (if any) of the locale /// @brief Convenience accessor to the country part (if any) of the locale
QLocale::Country country() const QLocale::Country country() const { return m_locale.country(); }
{
return m_locale.country();
}
/** @brief Get a Qt locale for the given @p localeName /** @brief Get a Qt locale for the given @p localeName
* *
@ -119,9 +99,9 @@ protected:
QString m_localeId; // the locale identifier, e.g. "en_GB" QString m_localeId; // the locale identifier, e.g. "en_GB"
QString m_label; // the native name of the locale QString m_label; // the native name of the locale
QString m_englishLabel; QString m_englishLabel;
} ; };
} } // namespace Locale
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -34,12 +34,12 @@ LabelModel::LabelModel( const QStringList& locales, QObject* parent )
m_locales.reserve( locales.count() ); m_locales.reserve( locales.count() );
for ( const auto& l : locales ) for ( const auto& l : locales )
{
m_locales.push_back( Label( l ) ); m_locales.push_back( Label( l ) );
}
} }
LabelModel::~LabelModel() LabelModel::~LabelModel() {}
{
}
int int
LabelModel::rowCount( const QModelIndex& ) const LabelModel::rowCount( const QModelIndex& ) const
@ -51,10 +51,14 @@ QVariant
LabelModel::data( const QModelIndex& index, int role ) const LabelModel::data( const QModelIndex& index, int role ) const
{ {
if ( ( role != LabelRole ) && ( role != EnglishLabelRole ) ) if ( ( role != LabelRole ) && ( role != EnglishLabelRole ) )
{
return QVariant(); return QVariant();
}
if ( !index.isValid() ) if ( !index.isValid() )
{
return QVariant(); return QVariant();
}
const auto& locale = m_locales.at( index.row() ); const auto& locale = m_locales.at( index.row() );
switch ( role ) switch ( role )
@ -75,59 +79,62 @@ LabelModel::locale( int row ) const
{ {
for ( const auto& l : m_locales ) for ( const auto& l : m_locales )
if ( l.isEnglish() ) if ( l.isEnglish() )
{
return l; return l;
return m_locales[0];
} }
return m_locales[row]; return m_locales[ 0 ];
}
return m_locales[ row ];
} }
int int
LabelModel::find( std::function<bool ( const Label& )> predicate ) const LabelModel::find( std::function< bool( const Label& ) > predicate ) const
{ {
for ( int row = 0; row < m_locales.count() ; ++row ) for ( int row = 0; row < m_locales.count(); ++row )
{
if ( predicate( m_locales[ row ] ) )
{ {
if ( predicate( m_locales[row] ) )
return row; return row;
} }
}
return -1; return -1;
} }
int int
LabelModel::find( std::function<bool ( const QLocale& )> predicate ) const LabelModel::find( std::function< bool( const QLocale& ) > predicate ) const
{ {
return find( [&]( const Label& l ) return find( [&]( const Label& l ) { return predicate( l.locale() ); } );
{
return predicate( l.locale() );
} );
} }
int int
LabelModel::find( const QLocale& locale ) const LabelModel::find( const QLocale& locale ) const
{ {
return find( [&]( const Label& l ) return find( [&]( const Label& l ) { return locale == l.locale(); } );
{
return locale == l.locale();
} );
} }
int int
LabelModel::find( const QString& countryCode ) const LabelModel::find( const QString& countryCode ) const
{ {
if ( countryCode.length() != 2 ) if ( countryCode.length() != 2 )
{
return -1; return -1;
}
auto c_l = countryData( countryCode ); auto c_l = countryData( countryCode );
int r = find( [&]( const Label& l ){ return ( l.language() == c_l.second ) && ( l.country() == c_l.first ); } ); int r = find( [&]( const Label& l ) { return ( l.language() == c_l.second ) && ( l.country() == c_l.first ); } );
if ( r >= 0 ) if ( r >= 0 )
{
return r; return r;
return find( [&]( const Label& l ){ return l.language() == c_l.second; } ); }
return find( [&]( const Label& l ) { return l.language() == c_l.second; } );
} }
LabelModel* availableTranslations() LabelModel*
availableTranslations()
{ {
static LabelModel* model = new LabelModel( QString( CALAMARES_TRANSLATION_LANGUAGES ).split( ';') ); static LabelModel* model = new LabelModel( QString( CALAMARES_TRANSLATION_LANGUAGES ).split( ';' ) );
return model; return model;
} }
} } // namespace Locale
} // namespace } // namespace CalamaresUtils

View File

@ -58,8 +58,8 @@ public:
* *
* Returns the row number of the first match, or -1 if there isn't one. * Returns the row number of the first match, or -1 if there isn't one.
*/ */
int find( std::function<bool( const QLocale& )> predicate ) const; int find( std::function< bool( const QLocale& ) > predicate ) const;
int find( std::function<bool( const Label& )> predicate ) const; int find( std::function< bool( const Label& ) > predicate ) const;
/// @brief Looks for an item using the same locale, -1 if there isn't one /// @brief Looks for an item using the same locale, -1 if there isn't one
int find( const QLocale& ) const; int find( const QLocale& ) const;
/// @brief Looks for an item that best matches the 2-letter country code /// @brief Looks for an item that best matches the 2-letter country code
@ -67,7 +67,7 @@ public:
private: private:
QVector< Label > m_locales; QVector< Label > m_locales;
} ; };
/** @brief Returns a model with all available translations. /** @brief Returns a model with all available translations.
* *
@ -80,6 +80,6 @@ private:
* NOTE: While the model is not typed const, it should be. Do not modify. * NOTE: While the model is not typed const, it should be. Do not modify.
*/ */
DLLEXPORT LabelModel* availableTranslations(); DLLEXPORT LabelModel* availableTranslations();
} } // namespace Locale
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -28,13 +28,13 @@ namespace Locale
struct TwoChar struct TwoChar
{ {
TwoChar( const QString& code ) TwoChar( const QString& code )
: cc1(0) : cc1( 0 )
, cc2(0) , cc2( 0 )
{ {
if ( code.length() == 2 ) if ( code.length() == 2 )
{ {
cc1 = code[0].toLatin1(); cc1 = code[ 0 ].toLatin1();
cc2 = code[1].toLatin1(); cc2 = code[ 1 ].toLatin1();
} }
} }
@ -42,52 +42,65 @@ struct TwoChar
char cc2; char cc2;
}; };
static const CountryData* lookup( TwoChar c ) static const CountryData*
lookup( TwoChar c )
{ {
if ( !c.cc1 ) if ( !c.cc1 )
{
return nullptr; return nullptr;
}
const CountryData* p = std::find_if(country_data_table, country_data_table + country_data_size, const CountryData* p
[c=c]( const CountryData& d ){ return (d.cc1 == c.cc1) && (d.cc2 == c.cc2); } = std::find_if( country_data_table, country_data_table + country_data_size, [c = c]( const CountryData& d ) {
); return ( d.cc1 == c.cc1 ) && ( d.cc2 == c.cc2 );
} );
if ( p == country_data_table + country_data_size ) if ( p == country_data_table + country_data_size )
{
return nullptr; return nullptr;
}
return p; return p;
} }
QLocale::Country countryForCode(const QString& code) QLocale::Country
countryForCode( const QString& code )
{ {
const CountryData* p = lookup( TwoChar( code ) ); const CountryData* p = lookup( TwoChar( code ) );
return p ? p->c : QLocale::Country::AnyCountry; return p ? p->c : QLocale::Country::AnyCountry;
} }
QLocale::Language languageForCountry(const QString& code) QLocale::Language
languageForCountry( const QString& code )
{ {
const CountryData* p = lookup( TwoChar( code ) ); const CountryData* p = lookup( TwoChar( code ) );
return p ? p->l : QLocale::Language::AnyLanguage; return p ? p->l : QLocale::Language::AnyLanguage;
} }
QPair<QLocale::Country, QLocale::Language> countryData(const QString& code) QPair< QLocale::Country, QLocale::Language >
countryData( const QString& code )
{ {
const CountryData* p = lookup( TwoChar( code ) ); const CountryData* p = lookup( TwoChar( code ) );
return p ? qMakePair( p->c, p->l ) : qMakePair( QLocale::Country::AnyCountry, QLocale::Language::AnyLanguage ); return p ? qMakePair( p->c, p->l ) : qMakePair( QLocale::Country::AnyCountry, QLocale::Language::AnyLanguage );
} }
QLocale countryLocale(const QString& code) QLocale
countryLocale( const QString& code )
{ {
auto p = countryData( code ); auto p = countryData( code );
return QLocale( p.second, p.first ); return QLocale( p.second, p.first );
} }
QLocale::Language languageForCountry(QLocale::Country country) QLocale::Language
languageForCountry( QLocale::Country country )
{ {
const CountryData* p = std::find_if(country_data_table, country_data_table + country_data_size, const CountryData* p = std::find_if( country_data_table,
[c=country]( const CountryData& d ){ return d.c == c; } country_data_table + country_data_size,
); [c = country]( const CountryData& d ) { return d.c == c; } );
if ( p == country_data_table + country_data_size ) if ( p == country_data_table + country_data_size )
{
return QLocale::Language::AnyLanguage; return QLocale::Language::AnyLanguage;
}
return p->l; return p->l;
} }
} } // namespace Locale
} // namespace } // namespace CalamaresUtils

View File

@ -28,28 +28,28 @@ namespace CalamaresUtils
{ {
namespace Locale namespace Locale
{ {
/* All the functions in this file do lookups of locale data /* All the functions in this file do lookups of locale data
* based on CLDR tables; these are lookups that you can't (easily) * based on CLDR tables; these are lookups that you can't (easily)
* do with just QLocale (e.g. from 2-letter country code to a likely * do with just QLocale (e.g. from 2-letter country code to a likely
* locale). * locale).
*/ */
/// @brief Map a 2-letter code to a Country, or AnyCountry if not found /// @brief Map a 2-letter code to a Country, or AnyCountry if not found
DLLEXPORT QLocale::Country countryForCode( const QString& code ); DLLEXPORT QLocale::Country countryForCode( const QString& code );
/** @brief Map a Country to a Language, or AnyLanguage if not found /** @brief Map a Country to a Language, or AnyLanguage if not found
* *
* This is a *likely* language for the given country, based on the * This is a *likely* language for the given country, based on the
* CLDR tables. For instance, this maps Belgium to Dutch. * CLDR tables. For instance, this maps Belgium to Dutch.
*/ */
DLLEXPORT QLocale::Language languageForCountry( QLocale::Country country ); DLLEXPORT QLocale::Language languageForCountry( QLocale::Country country );
/// @brief Map a 2-letter code to a Language, or AnyLanguage if not found /// @brief Map a 2-letter code to a Language, or AnyLanguage if not found
DLLEXPORT QLocale::Language languageForCountry( const QString& code ); DLLEXPORT QLocale::Language languageForCountry( const QString& code );
/// @brief Get both Country and Language for a 2-letter code /// @brief Get both Country and Language for a 2-letter code
DLLEXPORT QPair< QLocale::Country, QLocale::Language > countryData( const QString& code ); DLLEXPORT QPair< QLocale::Country, QLocale::Language > countryData( const QString& code );
/// @brief Get a likely locale for a 2-letter country code /// @brief Get a likely locale for a 2-letter country code
DLLEXPORT QLocale countryLocale( const QString& code ); DLLEXPORT QLocale countryLocale( const QString& code );
} } // namespace Locale
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -25,13 +25,9 @@
QTEST_GUILESS_MAIN( LocaleTests ) QTEST_GUILESS_MAIN( LocaleTests )
LocaleTests::LocaleTests() LocaleTests::LocaleTests() {}
{
}
LocaleTests::~LocaleTests() LocaleTests::~LocaleTests() {}
{
}
void void
LocaleTests::initTestCase() LocaleTests::initTestCase()
@ -82,6 +78,9 @@ LocaleTests::testEsperanto()
QVERIFY( locale.language() == QLocale::Lithuanian ? locale.country() == QLocale::Lithuania : true ); QVERIFY( locale.language() == QLocale::Lithuanian ? locale.country() == QLocale::Lithuania : true );
QVERIFY( locale.language() != QLocale::C ); QVERIFY( locale.language() != QLocale::C );
} }
#if QT_VERSION < QT_VERSION_CHECK( 5, 12, 2 )
QCOMPARE( QLocale( "eo" ).language(), QLocale::C ); QCOMPARE( QLocale( "eo" ).language(), QLocale::C );
#else
QCOMPARE( QLocale( "eo" ).language(), QLocale::Esperanto );
#endif
} }

View File

@ -231,6 +231,8 @@ cpp_header_comment = """/* GENERATED FILE DO NOT EDIT
*/ */
// BEGIN Generated from CLDR data // BEGIN Generated from CLDR data
// *INDENT-OFF*
// clang-format off
""" """

View File

@ -26,16 +26,13 @@ namespace CalamaresUtils
namespace Partition namespace Partition
{ {
static const NamedEnumTable<SizeUnit>& static const NamedEnumTable< SizeUnit >&
unitSuffixes() unitSuffixes()
{ {
static const NamedEnumTable<SizeUnit> names{ static const NamedEnumTable< SizeUnit > names {
{ QStringLiteral( "%" ), SizeUnit::Percent }, { QStringLiteral( "%" ), SizeUnit::Percent }, { QStringLiteral( "K" ), SizeUnit::KiB },
{ QStringLiteral( "K" ), SizeUnit::KiB }, { QStringLiteral( "KiB" ), SizeUnit::KiB }, { QStringLiteral( "M" ), SizeUnit::MiB },
{ QStringLiteral( "KiB" ), SizeUnit::KiB }, { QStringLiteral( "MiB" ), SizeUnit::MiB }, { QStringLiteral( "G" ), SizeUnit::GiB },
{ QStringLiteral( "M" ), SizeUnit::MiB },
{ QStringLiteral( "MiB" ), SizeUnit::MiB },
{ QStringLiteral( "G" ), SizeUnit::GiB },
{ QStringLiteral( "GiB" ), SizeUnit::GiB } { QStringLiteral( "GiB" ), SizeUnit::GiB }
}; };
@ -55,8 +52,10 @@ PartitionSize::PartitionSize( const QString& s )
{ {
m_value = s.toInt(); m_value = s.toInt();
if ( m_value > 0 ) if ( m_value > 0 )
{
m_unit = SizeUnit::Byte; m_unit = SizeUnit::Byte;
} }
}
if ( m_value <= 0 ) if ( m_value <= 0 )
{ {
@ -69,9 +68,13 @@ qint64
PartitionSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const PartitionSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const
{ {
if ( !isValid() ) if ( !isValid() )
{
return -1; return -1;
}
if ( totalSectors < 1 || sectorSize < 1 ) if ( totalSectors < 1 || sectorSize < 1 )
{
return -1; return -1;
}
switch ( m_unit ) switch ( m_unit )
{ {
@ -79,14 +82,18 @@ PartitionSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const
return -1; return -1;
case SizeUnit::Percent: case SizeUnit::Percent:
if ( value() == 100 ) if ( value() == 100 )
{
return totalSectors; // Common-case, avoid futzing around return totalSectors; // Common-case, avoid futzing around
}
else else
{
return totalSectors * value() / 100; return totalSectors * value() / 100;
}
case SizeUnit::Byte: case SizeUnit::Byte:
case SizeUnit::KiB: case SizeUnit::KiB:
case SizeUnit::MiB: case SizeUnit::MiB:
case SizeUnit::GiB: case SizeUnit::GiB:
return CalamaresUtils::bytesToSectors ( toBytes(), sectorSize ); return CalamaresUtils::bytesToSectors( toBytes(), sectorSize );
} }
return -1; return -1;
@ -96,7 +103,9 @@ qint64
PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const
{ {
if ( !isValid() ) if ( !isValid() )
{
return -1; return -1;
}
switch ( m_unit ) switch ( m_unit )
{ {
@ -104,11 +113,17 @@ PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const
return -1; return -1;
case SizeUnit::Percent: case SizeUnit::Percent:
if ( totalSectors < 1 || sectorSize < 1 ) if ( totalSectors < 1 || sectorSize < 1 )
{
return -1; return -1;
}
if ( value() == 100 ) if ( value() == 100 )
{
return totalSectors * sectorSize; // Common-case, avoid futzing around return totalSectors * sectorSize; // Common-case, avoid futzing around
}
else else
{
return totalSectors * value() / 100; return totalSectors * value() / 100;
}
case SizeUnit::Byte: case SizeUnit::Byte:
case SizeUnit::KiB: case SizeUnit::KiB:
case SizeUnit::MiB: case SizeUnit::MiB:
@ -124,7 +139,9 @@ qint64
PartitionSize::toBytes( qint64 totalBytes ) const PartitionSize::toBytes( qint64 totalBytes ) const
{ {
if ( !isValid() ) if ( !isValid() )
{
return -1; return -1;
}
switch ( m_unit ) switch ( m_unit )
{ {
@ -132,11 +149,17 @@ PartitionSize::toBytes( qint64 totalBytes ) const
return -1; return -1;
case SizeUnit::Percent: case SizeUnit::Percent:
if ( totalBytes < 1 ) if ( totalBytes < 1 )
{
return -1; return -1;
}
if ( value() == 100 ) if ( value() == 100 )
{
return totalBytes; // Common-case, avoid futzing around return totalBytes; // Common-case, avoid futzing around
}
else else
{
return totalBytes * value() / 100; return totalBytes * value() / 100;
}
case SizeUnit::Byte: case SizeUnit::Byte:
case SizeUnit::KiB: case SizeUnit::KiB:
case SizeUnit::MiB: case SizeUnit::MiB:
@ -152,7 +175,9 @@ qint64
PartitionSize::toBytes() const PartitionSize::toBytes() const
{ {
if ( !isValid() ) if ( !isValid() )
{
return -1; return -1;
}
switch ( m_unit ) switch ( m_unit )
{ {
@ -162,20 +187,22 @@ PartitionSize::toBytes() const
case SizeUnit::Byte: case SizeUnit::Byte:
return value(); return value();
case SizeUnit::KiB: case SizeUnit::KiB:
return CalamaresUtils::KiBtoBytes( static_cast<unsigned long long>( value() ) ); return CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( value() ) );
case SizeUnit::MiB: case SizeUnit::MiB:
return CalamaresUtils::MiBtoBytes( static_cast<unsigned long long>( value() ) ); return CalamaresUtils::MiBtoBytes( static_cast< unsigned long long >( value() ) );
case SizeUnit::GiB: case SizeUnit::GiB:
return CalamaresUtils::GiBtoBytes( static_cast<unsigned long long>( value() ) ); return CalamaresUtils::GiBtoBytes( static_cast< unsigned long long >( value() ) );
} }
NOTREACHED return -1; NOTREACHED return -1;
} }
bool bool
PartitionSize::operator< ( const PartitionSize& other ) const PartitionSize::operator<( const PartitionSize& other ) const
{ {
if ( !unitsComparable( m_unit, other.m_unit ) ) if ( !unitsComparable( m_unit, other.m_unit ) )
{
return false; return false;
}
switch ( m_unit ) switch ( m_unit )
{ {
@ -187,16 +214,18 @@ PartitionSize::operator< ( const PartitionSize& other ) const
case SizeUnit::KiB: case SizeUnit::KiB:
case SizeUnit::MiB: case SizeUnit::MiB:
case SizeUnit::GiB: case SizeUnit::GiB:
return ( toBytes() < other.toBytes () ); return ( toBytes() < other.toBytes() );
} }
NOTREACHED return false; NOTREACHED return false;
} }
bool bool
PartitionSize::operator> ( const PartitionSize& other ) const PartitionSize::operator>( const PartitionSize& other ) const
{ {
if ( !unitsComparable( m_unit, other.m_unit ) ) if ( !unitsComparable( m_unit, other.m_unit ) )
{
return false; return false;
}
switch ( m_unit ) switch ( m_unit )
{ {
@ -208,16 +237,18 @@ PartitionSize::operator> ( const PartitionSize& other ) const
case SizeUnit::KiB: case SizeUnit::KiB:
case SizeUnit::MiB: case SizeUnit::MiB:
case SizeUnit::GiB: case SizeUnit::GiB:
return ( toBytes() > other.toBytes () ); return ( toBytes() > other.toBytes() );
} }
NOTREACHED return false; NOTREACHED return false;
} }
bool bool
PartitionSize::operator== ( const PartitionSize& other ) const PartitionSize::operator==( const PartitionSize& other ) const
{ {
if ( !unitsComparable( m_unit, other.m_unit ) ) if ( !unitsComparable( m_unit, other.m_unit ) )
{
return false; return false;
}
switch ( m_unit ) switch ( m_unit )
{ {
@ -229,10 +260,10 @@ PartitionSize::operator== ( const PartitionSize& other ) const
case SizeUnit::KiB: case SizeUnit::KiB:
case SizeUnit::MiB: case SizeUnit::MiB:
case SizeUnit::GiB: case SizeUnit::GiB:
return ( toBytes() == other.toBytes () ); return ( toBytes() == other.toBytes() );
} }
NOTREACHED return false; NOTREACHED return false;
} }
} } // namespace Partition
} // namespace } // namespace CalamaresUtils

View File

@ -20,8 +20,8 @@
#ifndef PARTITION_PARTITIONSIZE_H #ifndef PARTITION_PARTITIONSIZE_H
#define PARTITION_PARTITIONSIZE_H #define PARTITION_PARTITIONSIZE_H
#include "utils/Units.h"
#include "utils/NamedSuffix.h" #include "utils/NamedSuffix.h"
#include "utils/Units.h"
// Qt // Qt
#include <QString> #include <QString>
@ -47,21 +47,24 @@ enum class SizeUnit
* the available drive space are on). This class handles parsing * the available drive space are on). This class handles parsing
* of such strings from the config file. * of such strings from the config file.
*/ */
class PartitionSize : public NamedSuffix<SizeUnit, SizeUnit::None> class PartitionSize : public NamedSuffix< SizeUnit, SizeUnit::None >
{ {
public: public:
PartitionSize() : NamedSuffix() { } PartitionSize()
PartitionSize( int v, SizeUnit u ) : NamedSuffix( v, u ) { } : NamedSuffix()
{
}
PartitionSize( int v, SizeUnit u )
: NamedSuffix( v, u )
{
}
PartitionSize( const QString& ); PartitionSize( const QString& );
bool isValid() const bool isValid() const { return ( unit() != SizeUnit::None ) && ( value() > 0 ); }
{
return ( unit() != SizeUnit::None ) && ( value() > 0 );
}
bool operator< ( const PartitionSize& other ) const; bool operator<( const PartitionSize& other ) const;
bool operator> ( const PartitionSize& other ) const; bool operator>( const PartitionSize& other ) const;
bool operator== ( const PartitionSize& other ) const; bool operator==( const PartitionSize& other ) const;
/** @brief Convert the size to the number of sectors @p totalSectors . /** @brief Convert the size to the number of sectors @p totalSectors .
* *
@ -109,14 +112,13 @@ public:
*/ */
static constexpr bool unitsComparable( const SizeUnit u1, const SizeUnit u2 ) static constexpr bool unitsComparable( const SizeUnit u1, const SizeUnit u2 )
{ {
return !( ( u1 == SizeUnit::None || u2 == SizeUnit::None ) || return !( ( u1 == SizeUnit::None || u2 == SizeUnit::None )
( u1 == SizeUnit::Percent && u2 != SizeUnit::Percent ) || || ( u1 == SizeUnit::Percent && u2 != SizeUnit::Percent )
( u1 != SizeUnit::Percent && u2 == SizeUnit::Percent ) ); || ( u1 != SizeUnit::Percent && u2 == SizeUnit::Percent ) );
} }
}; };
} } // namespace Partition
} // namespace } // namespace CalamaresUtils
#endif // PARTITION_PARTITIONSIZE_H #endif // PARTITION_PARTITIONSIZE_H

View File

@ -31,13 +31,9 @@ Q_DECLARE_METATYPE( SizeUnit )
QTEST_GUILESS_MAIN( PartitionSizeTests ) QTEST_GUILESS_MAIN( PartitionSizeTests )
PartitionSizeTests::PartitionSizeTests() PartitionSizeTests::PartitionSizeTests() {}
{
}
PartitionSizeTests::~PartitionSizeTests() PartitionSizeTests::~PartitionSizeTests() {}
{
}
void void
PartitionSizeTests::initTestCase() PartitionSizeTests::initTestCase()
@ -47,36 +43,38 @@ PartitionSizeTests::initTestCase()
void void
PartitionSizeTests::testUnitComparison_data() PartitionSizeTests::testUnitComparison_data()
{ {
QTest::addColumn<SizeUnit>("u1"); QTest::addColumn< SizeUnit >( "u1" );
QTest::addColumn<SizeUnit>("u2"); QTest::addColumn< SizeUnit >( "u2" );
QTest::addColumn<bool>("comparable"); QTest::addColumn< bool >( "comparable" );
QTest::newRow("nones") << SizeUnit::None << SizeUnit::None << false; QTest::newRow( "nones" ) << SizeUnit::None << SizeUnit::None << false;
QTest::newRow("none+%") << SizeUnit::None << SizeUnit::Percent<< false; QTest::newRow( "none+%" ) << SizeUnit::None << SizeUnit::Percent << false;
QTest::newRow("%+none") << SizeUnit::Percent << SizeUnit::None << false; QTest::newRow( "%+none" ) << SizeUnit::Percent << SizeUnit::None << false;
QTest::newRow("KiB+none") << SizeUnit::KiB << SizeUnit::None << false; QTest::newRow( "KiB+none" ) << SizeUnit::KiB << SizeUnit::None << false;
QTest::newRow("none+MiB") << SizeUnit::None << SizeUnit::MiB << false; QTest::newRow( "none+MiB" ) << SizeUnit::None << SizeUnit::MiB << false;
QTest::newRow("KiB+KiB") << SizeUnit::KiB << SizeUnit::KiB << true; QTest::newRow( "KiB+KiB" ) << SizeUnit::KiB << SizeUnit::KiB << true;
QTest::newRow("KiB+MiB") << SizeUnit::KiB << SizeUnit::MiB << true; QTest::newRow( "KiB+MiB" ) << SizeUnit::KiB << SizeUnit::MiB << true;
QTest::newRow("KiB+GiB") << SizeUnit::KiB << SizeUnit::GiB << true; QTest::newRow( "KiB+GiB" ) << SizeUnit::KiB << SizeUnit::GiB << true;
QTest::newRow("MiB+MiB") << SizeUnit::MiB << SizeUnit::MiB << true; QTest::newRow( "MiB+MiB" ) << SizeUnit::MiB << SizeUnit::MiB << true;
QTest::newRow("MiB+GiB") << SizeUnit::MiB << SizeUnit::GiB << true; QTest::newRow( "MiB+GiB" ) << SizeUnit::MiB << SizeUnit::GiB << true;
QTest::newRow("GiB+GiB") << SizeUnit::GiB << SizeUnit::GiB << true; QTest::newRow( "GiB+GiB" ) << SizeUnit::GiB << SizeUnit::GiB << true;
QTest::newRow("%+None") << SizeUnit::Percent << SizeUnit::None << false; QTest::newRow( "%+None" ) << SizeUnit::Percent << SizeUnit::None << false;
QTest::newRow("%+%") << SizeUnit::Percent << SizeUnit::Percent << true; QTest::newRow( "%+%" ) << SizeUnit::Percent << SizeUnit::Percent << true;
QTest::newRow("%+KiB") << SizeUnit::Percent << SizeUnit::KiB << false; QTest::newRow( "%+KiB" ) << SizeUnit::Percent << SizeUnit::KiB << false;
} }
static bool static bool
original_compare( SizeUnit m_unit, SizeUnit other_m_unit ) original_compare( SizeUnit m_unit, SizeUnit other_m_unit )
{ {
if ( ( m_unit == SizeUnit::None || other_m_unit == SizeUnit::None ) || if ( ( m_unit == SizeUnit::None || other_m_unit == SizeUnit::None )
( m_unit == SizeUnit::Percent && other_m_unit != SizeUnit::Percent ) || || ( m_unit == SizeUnit::Percent && other_m_unit != SizeUnit::Percent )
( m_unit != SizeUnit::Percent && other_m_unit == SizeUnit::Percent ) ) || ( m_unit != SizeUnit::Percent && other_m_unit == SizeUnit::Percent ) )
{
return false; return false;
}
return true; return true;
} }
@ -104,33 +102,33 @@ PartitionSizeTests::testUnitComparison()
void void
PartitionSizeTests::testUnitNormalisation_data() PartitionSizeTests::testUnitNormalisation_data()
{ {
QTest::addColumn<SizeUnit>("u1"); QTest::addColumn< SizeUnit >( "u1" );
QTest::addColumn<int>("v"); QTest::addColumn< int >( "v" );
QTest::addColumn<long>("bytes"); QTest::addColumn< long >( "bytes" );
QTest::newRow("none") << SizeUnit::None << 16 << -1L; QTest::newRow( "none" ) << SizeUnit::None << 16 << -1L;
QTest::newRow("none") << SizeUnit::None << 0 << -1L; QTest::newRow( "none" ) << SizeUnit::None << 0 << -1L;
QTest::newRow("none") << SizeUnit::None << -2 << -1L; QTest::newRow( "none" ) << SizeUnit::None << -2 << -1L;
QTest::newRow("percent") << SizeUnit::Percent << 0 << -1L; QTest::newRow( "percent" ) << SizeUnit::Percent << 0 << -1L;
QTest::newRow("percent") << SizeUnit::Percent << 16 << -1L; QTest::newRow( "percent" ) << SizeUnit::Percent << 16 << -1L;
QTest::newRow("percent") << SizeUnit::Percent << -2 << -1L; QTest::newRow( "percent" ) << SizeUnit::Percent << -2 << -1L;
QTest::newRow("KiB") << SizeUnit::KiB << 0 << -1L; QTest::newRow( "KiB" ) << SizeUnit::KiB << 0 << -1L;
QTest::newRow("KiB") << SizeUnit::KiB << 1 << 1024L; QTest::newRow( "KiB" ) << SizeUnit::KiB << 1 << 1024L;
QTest::newRow("KiB") << SizeUnit::KiB << 1000 << 1024000L; QTest::newRow( "KiB" ) << SizeUnit::KiB << 1000 << 1024000L;
QTest::newRow("KiB") << SizeUnit::KiB << 1024 << 1024 * 1024L; QTest::newRow( "KiB" ) << SizeUnit::KiB << 1024 << 1024 * 1024L;
QTest::newRow("KiB") << SizeUnit::KiB << -2 << -1L; QTest::newRow( "KiB" ) << SizeUnit::KiB << -2 << -1L;
QTest::newRow("MiB") << SizeUnit::MiB << 0 << -1L; QTest::newRow( "MiB" ) << SizeUnit::MiB << 0 << -1L;
QTest::newRow("MiB") << SizeUnit::MiB << 1 << 1024 * 1024L; QTest::newRow( "MiB" ) << SizeUnit::MiB << 1 << 1024 * 1024L;
QTest::newRow("MiB") << SizeUnit::MiB << 1000 << 1024 * 1024000L; QTest::newRow( "MiB" ) << SizeUnit::MiB << 1000 << 1024 * 1024000L;
QTest::newRow("MiB") << SizeUnit::MiB << 1024 << 1024 * 1024 * 1024L; QTest::newRow( "MiB" ) << SizeUnit::MiB << 1024 << 1024 * 1024 * 1024L;
QTest::newRow("MiB") << SizeUnit::MiB << -2 << -1L; QTest::newRow( "MiB" ) << SizeUnit::MiB << -2 << -1L;
QTest::newRow("GiB") << SizeUnit::GiB << 0 << -1L; QTest::newRow( "GiB" ) << SizeUnit::GiB << 0 << -1L;
QTest::newRow("GiB") << SizeUnit::GiB << 1 << 1024 * 1024 * 1024L; QTest::newRow( "GiB" ) << SizeUnit::GiB << 1 << 1024 * 1024 * 1024L;
QTest::newRow("GiB") << SizeUnit::GiB << 2 << 2048 * 1024 * 1024L; QTest::newRow( "GiB" ) << SizeUnit::GiB << 2 << 2048 * 1024 * 1024L;
} }
void void
@ -140,5 +138,5 @@ PartitionSizeTests::testUnitNormalisation()
QFETCH( int, v ); QFETCH( int, v );
QFETCH( long, bytes ); QFETCH( long, bytes );
QCOMPARE( PartitionSize( v, u1 ).toBytes(), static_cast<qint64>( bytes ) ); QCOMPARE( PartitionSize( v, u1 ).toBytes(), static_cast< qint64 >( bytes ) );
} }

View File

@ -19,10 +19,10 @@
#include "CalamaresUtilsSystem.h" #include "CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "Settings.h" #include "Settings.h"
#include "utils/Logger.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
@ -34,8 +34,11 @@
#endif #endif
#ifdef Q_OS_FREEBSD #ifdef Q_OS_FREEBSD
// clang-format off
// these includes need to stay in-order (that's a FreeBSD thing)
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
// clang-format on
#endif #endif
/** @brief When logging commands, don't log everything. /** @brief When logging commands, don't log everything.
@ -48,12 +51,12 @@
struct RedactedList struct RedactedList
{ {
RedactedList( const QStringList& l ) RedactedList( const QStringList& l )
: list(l) : list( l )
{ {
} }
const QStringList& list; const QStringList& list;
} ; };
QDebug& QDebug&
operator<<( QDebug& s, const RedactedList& l ) operator<<( QDebug& s, const RedactedList& l )
@ -63,12 +66,18 @@ operator<<( QDebug& s, const RedactedList& l )
{ {
for ( const auto& item : l.list ) for ( const auto& item : l.list )
if ( item.startsWith( "$6$" ) ) if ( item.startsWith( "$6$" ) )
{
s << "<password>"; s << "<password>";
else
s << item;
} }
else else
{
s << item;
}
}
else
{
s << l.list; s << l.list;
}
return s; return s;
} }
@ -92,8 +101,7 @@ System::System( bool doChroot, QObject* parent )
} }
System::~System() System::~System() {}
{}
System* System*
@ -118,11 +126,15 @@ System::mount( const QString& devicePath,
if ( devicePath.isEmpty() || mountPoint.isEmpty() ) if ( devicePath.isEmpty() || mountPoint.isEmpty() )
{ {
if ( devicePath.isEmpty() ) if ( devicePath.isEmpty() )
{
cWarning() << "Can't mount an empty device."; cWarning() << "Can't mount an empty device.";
}
if ( mountPoint.isEmpty() ) if ( mountPoint.isEmpty() )
{
cWarning() << "Can't mount on an empty mountpoint."; cWarning() << "Can't mount on an empty mountpoint.";
}
return static_cast<int>(ProcessResult::Code::NoWorkingDirectory); return static_cast< int >( ProcessResult::Code::NoWorkingDirectory );
} }
QDir mountPointDir( mountPoint ); QDir mountPointDir( mountPoint );
@ -132,7 +144,7 @@ System::mount( const QString& devicePath,
if ( !ok ) if ( !ok )
{ {
cWarning() << "Could not create mountpoint" << mountPoint; cWarning() << "Could not create mountpoint" << mountPoint;
return static_cast<int>(ProcessResult::Code::NoWorkingDirectory); return static_cast< int >( ProcessResult::Code::NoWorkingDirectory );
} }
} }
@ -140,17 +152,20 @@ System::mount( const QString& devicePath,
QStringList args = { devicePath, mountPoint }; QStringList args = { devicePath, mountPoint };
if ( !filesystemName.isEmpty() ) if ( !filesystemName.isEmpty() )
{
args << "-t" << filesystemName; args << "-t" << filesystemName;
}
if ( !options.isEmpty() ) if ( !options.isEmpty() )
{
args << "-o" << options; args << "-o" << options;
}
return QProcess::execute( program, args ); return QProcess::execute( program, args );
} }
ProcessResult ProcessResult
System::runCommand( System::runCommand( System::RunLocation location,
System::RunLocation location,
const QStringList& args, const QStringList& args,
const QString& workingPath, const QString& workingPath,
const QString& stdInput, const QString& stdInput,
@ -158,10 +173,10 @@ System::runCommand(
{ {
QString output; QString output;
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; Calamares::GlobalStorage* gs
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
if ( ( location == System::RunLocation::RunInTarget ) && if ( ( location == System::RunLocation::RunInTarget ) && ( !gs || !gs->contains( "rootMountPoint" ) ) )
( !gs || !gs->contains( "rootMountPoint" ) ) )
{ {
cWarning() << "No rootMountPoint in global storage"; cWarning() << "No rootMountPoint in global storage";
return ProcessResult::Code::NoWorkingDirectory; return ProcessResult::Code::NoWorkingDirectory;
@ -197,7 +212,9 @@ System::runCommand(
if ( !workingPath.isEmpty() ) if ( !workingPath.isEmpty() )
{ {
if ( QDir( workingPath ).exists() ) if ( QDir( workingPath ).exists() )
{
process.setWorkingDirectory( QDir( workingPath ).absolutePath() ); process.setWorkingDirectory( QDir( workingPath ).absolutePath() );
}
else else
{ {
cWarning() << "Invalid working directory:" << workingPath; cWarning() << "Invalid working directory:" << workingPath;
@ -219,10 +236,10 @@ System::runCommand(
} }
process.closeWriteChannel(); process.closeWriteChannel();
if ( !process.waitForFinished( timeoutSec > std::chrono::seconds::zero() ? ( std::chrono::milliseconds( timeoutSec ).count() ) : -1 ) ) if ( !process.waitForFinished(
timeoutSec > std::chrono::seconds::zero() ? ( std::chrono::milliseconds( timeoutSec ).count() ) : -1 ) )
{ {
cWarning().noquote().nospace() << "Timed out. Output so far:\n" << cWarning().noquote().nospace() << "Timed out. Output so far:\n" << process.readAllStandardOutput();
process.readAllStandardOutput();
return ProcessResult::Code::TimedOut; return ProcessResult::Code::TimedOut;
} }
@ -242,7 +259,7 @@ System::runCommand(
cDebug() << "Target cmd:" << RedactedList( args ); cDebug() << "Target cmd:" << RedactedList( args );
cDebug().noquote().nospace() << "Target output:\n" << output; cDebug().noquote().nospace() << "Target output:\n" << output;
} }
return ProcessResult(r, output); return ProcessResult( r, output );
} }
QString QString
@ -252,7 +269,8 @@ System::targetPath( const QString& path ) const
if ( doChroot() ) if ( doChroot() )
{ {
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; Calamares::GlobalStorage* gs
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
if ( !gs || !gs->contains( "rootMountPoint" ) ) if ( !gs || !gs->contains( "rootMountPoint" ) )
{ {
@ -309,28 +327,32 @@ System::createTargetFile( const QString& path, const QByteArray& contents ) cons
} }
QPair<quint64, float> QPair< quint64, float >
System::getTotalMemoryB() const System::getTotalMemoryB() const
{ {
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
struct sysinfo i; struct sysinfo i;
int r = sysinfo( &i ); int r = sysinfo( &i );
if (r) if ( r )
return qMakePair(0, 0.0); {
return qMakePair( 0, 0.0 );
}
return qMakePair(quint64( i.mem_unit ) * quint64( i.totalram ), 1.1); return qMakePair( quint64( i.mem_unit ) * quint64( i.totalram ), 1.1 );
#elif defined( Q_OS_FREEBSD ) #elif defined( Q_OS_FREEBSD )
unsigned long memsize; unsigned long memsize;
size_t s = sizeof(memsize); size_t s = sizeof( memsize );
int r = sysctlbyname("vm.kmem_size", &memsize, &s, NULL, 0); int r = sysctlbyname( "vm.kmem_size", &memsize, &s, NULL, 0 );
if (r) if ( r )
return qMakePair(0, 0.0); {
return qMakePair( 0, 0.0 );
}
return qMakePair(memsize, 1.01); return qMakePair( memsize, 1.01 );
#else #else
return qMakePair(0, 0.0); // Unsupported return qMakePair( 0, 0.0 ); // Unsupported
#endif #endif
} }
@ -341,14 +363,14 @@ System::getCpuDescription() const
QString model; QString model;
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
QFile file("/proc/cpuinfo"); QFile file( "/proc/cpuinfo" );
if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
while ( !file.atEnd() ) while ( !file.atEnd() )
{ {
QByteArray line = file.readLine(); QByteArray line = file.readLine();
if ( line.startsWith( "model name" ) && (line.indexOf( ':' ) > 0) ) if ( line.startsWith( "model name" ) && ( line.indexOf( ':' ) > 0 ) )
{ {
model = QString::fromLatin1( line.right(line.length() - line.indexOf( ':' ) ) ); model = QString::fromLatin1( line.right( line.length() - line.indexOf( ':' ) ) );
break; break;
} }
} }
@ -376,40 +398,45 @@ ProcessResult::explainProcess( int ec, const QString& command, const QString& ou
using Calamares::JobResult; using Calamares::JobResult;
if ( ec == 0 ) if ( ec == 0 )
{
return JobResult::ok(); return JobResult::ok();
}
QString outputMessage = output.isEmpty() QString outputMessage = output.isEmpty()
? QCoreApplication::translate( "ProcessResult", "\nThere was no output from the command.") ? QCoreApplication::translate( "ProcessResult", "\nThere was no output from the command." )
: (QCoreApplication::translate( "ProcessResult", "\nOutput:\n") + output); : ( QCoreApplication::translate( "ProcessResult", "\nOutput:\n" ) + output );
if ( ec == static_cast<int>(ProcessResult::Code::Crashed) ) //Crash! if ( ec == static_cast< int >( ProcessResult::Code::Crashed ) ) //Crash!
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command crashed." ), return JobResult::error(
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> crashed." ) QCoreApplication::translate( "ProcessResult", "External command crashed." ),
.arg( command ) QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> crashed." ).arg( command )
+ outputMessage ); + outputMessage );
if ( ec == static_cast<int>(ProcessResult::Code::FailedToStart) ) if ( ec == static_cast< int >( ProcessResult::Code::FailedToStart ) )
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command failed to start." ), return JobResult::error(
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to start." ) QCoreApplication::translate( "ProcessResult", "External command failed to start." ),
.arg( command ) ); QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to start." ).arg( command ) );
if ( ec == static_cast<int>(ProcessResult::Code::NoWorkingDirectory) ) if ( ec == static_cast< int >( ProcessResult::Code::NoWorkingDirectory ) )
return JobResult::error( QCoreApplication::translate( "ProcessResult", "Internal error when starting command." ), return JobResult::error(
QCoreApplication::translate( "ProcessResult", "Internal error when starting command." ),
QCoreApplication::translate( "ProcessResult", "Bad parameters for process job call." ) ); QCoreApplication::translate( "ProcessResult", "Bad parameters for process job call." ) );
if ( ec == static_cast<int>(ProcessResult::Code::TimedOut) ) if ( ec == static_cast< int >( ProcessResult::Code::TimedOut ) )
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command failed to finish." ), return JobResult::error(
QCoreApplication::translate( "ProcessResult", "External command failed to finish." ),
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to finish in %2 seconds." ) QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to finish in %2 seconds." )
.arg( command ) .arg( command )
.arg( timeout.count() ) .arg( timeout.count() )
+ outputMessage ); + outputMessage );
//Any other exit code //Any other exit code
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command finished with errors." ), return JobResult::error(
QCoreApplication::translate( "ProcessResult", "External command finished with errors." ),
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> finished with exit code %2." ) QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> finished with exit code %2." )
.arg( command ) .arg( command )
.arg( ec ) .arg( ec )
+ outputMessage ); + outputMessage );
} }
} // namespace } // namespace CalamaresUtils

View File

@ -40,11 +40,17 @@ public:
FailedToStart = -2, // Must match special return values from QProcess FailedToStart = -2, // Must match special return values from QProcess
NoWorkingDirectory = -3, NoWorkingDirectory = -3,
TimedOut = -4 TimedOut = -4
} ; };
/** @brief Implicit one-argument constructor has no output, only a return code */ /** @brief Implicit one-argument constructor has no output, only a return code */
ProcessResult( Code r ) : QPair< int, QString >( static_cast<int>(r), QString() ) {} ProcessResult( Code r )
ProcessResult( int r, QString s ) : QPair< int, QString >( r, s ) {} : QPair< int, QString >( static_cast< int >( r ), QString() )
{
}
ProcessResult( int r, QString s )
: QPair< int, QString >( r, s )
{
}
int getExitCode() const { return first; } int getExitCode() const { return first; }
QString getOutput() const { return second; } QString getOutput() const { return second; }
@ -62,7 +68,8 @@ public:
* @param timeout Timeout passed to the process runner, for explaining * @param timeout Timeout passed to the process runner, for explaining
* error code -4 (timeout). * error code -4 (timeout).
*/ */
static Calamares::JobResult explainProcess( int errorCode, const QString& command, const QString& output, std::chrono::seconds timeout ); static Calamares::JobResult
explainProcess( int errorCode, const QString& command, const QString& output, std::chrono::seconds timeout );
/// @brief Convenience wrapper for explainProcess() /// @brief Convenience wrapper for explainProcess()
inline Calamares::JobResult explainProcess( const QString& command, std::chrono::seconds timeout ) const inline Calamares::JobResult explainProcess( const QString& command, std::chrono::seconds timeout ) const
@ -75,7 +82,7 @@ public:
{ {
return explainProcess( getExitCode(), command.join( ' ' ), getOutput(), timeout ); return explainProcess( getExitCode(), command.join( ' ' ), getOutput(), timeout );
} }
} ; };
/** /**
* @brief The System class is a singleton with utility functions that perform * @brief The System class is a singleton with utility functions that perform
@ -116,7 +123,11 @@ public:
/** (Typed) Boolean describing where a particular command should be run, /** (Typed) Boolean describing where a particular command should be run,
* whether in the host (live) system or in the (chroot) target system. * whether in the host (live) system or in the (chroot) target system.
*/ */
enum class RunLocation { RunInHost, RunInTarget }; enum class RunLocation
{
RunInHost,
RunInTarget
};
/** /**
* Runs the specified command in the chroot of the target system. * Runs the specified command in the chroot of the target system.
@ -135,37 +146,31 @@ public:
* NoWorkingDirectory = bad arguments * NoWorkingDirectory = bad arguments
* TimedOut = QProcess timeout * TimedOut = QProcess timeout
*/ */
static DLLEXPORT ProcessResult runCommand( static DLLEXPORT ProcessResult runCommand( RunLocation location,
RunLocation location, const QStringList& args,
const QStringList &args,
const QString& workingPath = QString(), const QString& workingPath = QString(),
const QString& stdInput = QString(), const QString& stdInput = QString(),
std::chrono::seconds timeoutSec = std::chrono::seconds(0) ); std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) );
/** @brief Convenience wrapper for runCommand(). /** @brief Convenience wrapper for runCommand().
* Runs the command in the location specified through the boolean * Runs the command in the location specified through the boolean
* doChroot(), which is what you usually want for running commands * doChroot(), which is what you usually want for running commands
* during installation. * during installation.
*/ */
inline ProcessResult targetEnvCommand( inline ProcessResult targetEnvCommand( const QStringList& args,
const QStringList &args,
const QString& workingPath = QString(), const QString& workingPath = QString(),
const QString& stdInput = QString(), const QString& stdInput = QString(),
std::chrono::seconds timeoutSec = std::chrono::seconds(0) ) std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) )
{ {
return runCommand( return runCommand(
m_doChroot ? RunLocation::RunInTarget : RunLocation::RunInHost, m_doChroot ? RunLocation::RunInTarget : RunLocation::RunInHost, args, workingPath, stdInput, timeoutSec );
args,
workingPath,
stdInput,
timeoutSec );
} }
/** @brief Convenience wrapper for targetEnvCommand() which returns only the exit code */ /** @brief Convenience wrapper for targetEnvCommand() which returns only the exit code */
inline int targetEnvCall( const QStringList& args, inline int targetEnvCall( const QStringList& args,
const QString& workingPath = QString(), const QString& workingPath = QString(),
const QString& stdInput = QString(), const QString& stdInput = QString(),
std::chrono::seconds timeoutSec = std::chrono::seconds(0) ) std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) )
{ {
return targetEnvCommand( args, workingPath, stdInput, timeoutSec ).first; return targetEnvCommand( args, workingPath, stdInput, timeoutSec ).first;
} }
@ -174,9 +179,9 @@ public:
inline int targetEnvCall( const QString& command, inline int targetEnvCall( const QString& command,
const QString& workingPath = QString(), const QString& workingPath = QString(),
const QString& stdInput = QString(), const QString& stdInput = QString(),
std::chrono::seconds timeoutSec = std::chrono::seconds(0) ) std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) )
{ {
return targetEnvCall( QStringList{ command }, workingPath, stdInput, timeoutSec ); return targetEnvCall( QStringList { command }, workingPath, stdInput, timeoutSec );
} }
/** @brief Convenience wrapper for targetEnvCommand() which returns only the exit code /** @brief Convenience wrapper for targetEnvCommand() which returns only the exit code
@ -187,7 +192,7 @@ public:
QString& output, QString& output,
const QString& workingPath = QString(), const QString& workingPath = QString(),
const QString& stdInput = QString(), const QString& stdInput = QString(),
std::chrono::seconds timeoutSec = std::chrono::seconds(0) ) std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) )
{ {
auto r = targetEnvCommand( args, workingPath, stdInput, timeoutSec ); auto r = targetEnvCommand( args, workingPath, stdInput, timeoutSec );
output = r.second; output = r.second;
@ -202,9 +207,9 @@ public:
QString& output, QString& output,
const QString& workingPath = QString(), const QString& workingPath = QString(),
const QString& stdInput = QString(), const QString& stdInput = QString(),
std::chrono::seconds timeoutSec = std::chrono::seconds(0) ) std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) )
{ {
return targetEnvOutput( QStringList{ command }, output, workingPath, stdInput, timeoutSec ); return targetEnvOutput( QStringList { command }, output, workingPath, stdInput, timeoutSec );
} }
@ -255,7 +260,7 @@ public:
* *
* @return size, guesstimate-factor * @return size, guesstimate-factor
*/ */
DLLEXPORT QPair<quint64, float> getTotalMemoryB() const; DLLEXPORT QPair< quint64, float > getTotalMemoryB() const;
/** /**
* @brief getCpuDescription returns a string describing the CPU. * @brief getCpuDescription returns a string describing the CPU.
@ -279,6 +284,6 @@ private:
bool m_doChroot; bool m_doChroot;
}; };
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -32,34 +32,44 @@
namespace CalamaresUtils namespace CalamaresUtils
{ {
static CommandLine get_variant_object( const QVariantMap& m ) static CommandLine
get_variant_object( const QVariantMap& m )
{ {
QString command = CalamaresUtils::getString( m, "command" ); QString command = CalamaresUtils::getString( m, "command" );
int timeout = CalamaresUtils::getInteger( m, "timeout", -1 ); int timeout = CalamaresUtils::getInteger( m, "timeout", -1 );
if ( !command.isEmpty() ) if ( !command.isEmpty() )
{
return CommandLine( command, timeout >= 0 ? std::chrono::seconds( timeout ) : CommandLine::TimeoutNotSet() ); return CommandLine( command, timeout >= 0 ? std::chrono::seconds( timeout ) : CommandLine::TimeoutNotSet() );
}
cWarning() << "Bad CommandLine element" << m; cWarning() << "Bad CommandLine element" << m;
return CommandLine(); return CommandLine();
} }
static CommandList_t get_variant_stringlist( const QVariantList& l ) static CommandList_t
get_variant_stringlist( const QVariantList& l )
{ {
CommandList_t retl; CommandList_t retl;
unsigned int count = 0; unsigned int count = 0;
for ( const auto& v : l ) for ( const auto& v : l )
{ {
if ( v.type() == QVariant::String ) if ( v.type() == QVariant::String )
{
retl.append( CommandLine( v.toString(), CommandLine::TimeoutNotSet() ) ); retl.append( CommandLine( v.toString(), CommandLine::TimeoutNotSet() ) );
}
else if ( v.type() == QVariant::Map ) else if ( v.type() == QVariant::Map )
{ {
auto command( get_variant_object( v.toMap() ) ); auto command( get_variant_object( v.toMap() ) );
if ( command.isValid() ) if ( command.isValid() )
{
retl.append( command ); retl.append( command );
}
// Otherwise warning is already given // Otherwise warning is already given
} }
else else
{
cWarning() << "Bad CommandList element" << count << v.type() << v; cWarning() << "Bad CommandList element" << count << v.type() << v;
}
++count; ++count;
} }
return retl; return retl;
@ -78,37 +88,48 @@ CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, std::ch
{ {
const auto v_list = v.toList(); const auto v_list = v.toList();
if ( v_list.count() ) if ( v_list.count() )
{
append( get_variant_stringlist( v_list ) ); append( get_variant_stringlist( v_list ) );
}
else else
{
cWarning() << "Empty CommandList"; cWarning() << "Empty CommandList";
} }
}
else if ( v.type() == QVariant::String ) else if ( v.type() == QVariant::String )
{
append( v.toString() ); append( v.toString() );
}
else if ( v.type() == QVariant::Map ) else if ( v.type() == QVariant::Map )
{ {
auto c( get_variant_object( v.toMap() ) ); auto c( get_variant_object( v.toMap() ) );
if ( c.isValid() ) if ( c.isValid() )
{
append( c ); append( c );
}
// Otherwise warning is already given // Otherwise warning is already given
} }
else else
{
cWarning() << "CommandList does not understand variant" << v.type(); cWarning() << "CommandList does not understand variant" << v.type();
}
} }
CommandList::~CommandList() CommandList::~CommandList() {}
{
}
static inline bool static inline bool
findInCommands( const CommandList& l, const QString& needle ) findInCommands( const CommandList& l, const QString& needle )
{ {
for ( CommandList::const_iterator i = l.cbegin(); i != l.cend(); ++i ) for ( CommandList::const_iterator i = l.cbegin(); i != l.cend(); ++i )
if ( i->command().contains( needle ) ) if ( i->command().contains( needle ) )
{
return true; return true;
}
return false; return false;
} }
Calamares::JobResult CommandList::run() Calamares::JobResult
CommandList::run()
{ {
QLatin1Literal rootMagic( "@@ROOT@@" ); QLatin1Literal rootMagic( "@@ROOT@@" );
QLatin1Literal userMagic( "@@USER@@" ); QLatin1Literal userMagic( "@@USER@@" );
@ -125,8 +146,11 @@ Calamares::JobResult CommandList::run()
if ( !gs || !gs->contains( "rootMountPoint" ) ) if ( !gs || !gs->contains( "rootMountPoint" ) )
{ {
cError() << "No rootMountPoint defined."; cError() << "No rootMountPoint defined.";
return Calamares::JobResult::error( QCoreApplication::translate( "CommandList", "Could not run command." ), return Calamares::JobResult::error(
QCoreApplication::translate( "CommandList", "The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined." ) ); QCoreApplication::translate( "CommandList", "Could not run command." ),
QCoreApplication::translate( "CommandList",
"The command runs in the host environment and needs to know the root "
"path, but no rootMountPoint is defined." ) );
} }
root = gs->value( "rootMountPoint" ).toString(); root = gs->value( "rootMountPoint" ).toString();
} }
@ -137,7 +161,8 @@ Calamares::JobResult CommandList::run()
cError() << "No username defined."; cError() << "No username defined.";
return Calamares::JobResult::error( return Calamares::JobResult::error(
QCoreApplication::translate( "CommandList", "Could not run command." ), QCoreApplication::translate( "CommandList", "Could not run command." ),
QCoreApplication::translate( "CommandList", "The command needs to know the user's name, but no username is defined." ) ); QCoreApplication::translate( "CommandList",
"The command needs to know the user's name, but no username is defined." ) );
} }
QString user = gs->value( "username" ).toString(); // may be blank if unset QString user = gs->value( "username" ).toString(); // may be blank if unset
@ -156,17 +181,20 @@ Calamares::JobResult CommandList::run()
shell_cmd << processed_cmd; shell_cmd << processed_cmd;
std::chrono::seconds timeout = i->timeout() >= std::chrono::seconds::zero() ? i->timeout() : m_timeout; std::chrono::seconds timeout = i->timeout() >= std::chrono::seconds::zero() ? i->timeout() : m_timeout;
ProcessResult r = System::runCommand( ProcessResult r = System::runCommand( location, shell_cmd, QString(), QString(), timeout );
location, shell_cmd, QString(), QString(), timeout );
if ( r.getExitCode() != 0 ) if ( r.getExitCode() != 0 )
{ {
if ( suppress_result ) if ( suppress_result )
{
cDebug() << "Error code" << r.getExitCode() << "ignored by CommandList configuration."; cDebug() << "Error code" << r.getExitCode() << "ignored by CommandList configuration.";
}
else else
{
return r.explainProcess( processed_cmd, timeout ); return r.explainProcess( processed_cmd, timeout );
} }
} }
}
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();
} }
@ -177,4 +205,4 @@ CommandList::append( const QString& s )
append( CommandLine( s, m_timeout ) ); append( CommandLine( s, m_timeout ) );
} }
} // namespace } // namespace CalamaresUtils

View File

@ -35,7 +35,7 @@ namespace CalamaresUtils
*/ */
struct CommandLine : public QPair< QString, std::chrono::seconds > struct CommandLine : public QPair< QString, std::chrono::seconds >
{ {
static inline constexpr std::chrono::seconds TimeoutNotSet() { return std::chrono::seconds(-1); } static inline constexpr std::chrono::seconds TimeoutNotSet() { return std::chrono::seconds( -1 ); }
/// An invalid command line /// An invalid command line
CommandLine() CommandLine()
@ -49,25 +49,16 @@ struct CommandLine : public QPair< QString, std::chrono::seconds >
} }
CommandLine( const QString& s, std::chrono::seconds t ) CommandLine( const QString& s, std::chrono::seconds t )
: QPair( s, t) : QPair( s, t )
{ {
} }
QString command() const QString command() const { return first; }
{
return first;
}
std::chrono::seconds timeout() const std::chrono::seconds timeout() const { return second; }
{
return second;
}
bool isValid() const bool isValid() const { return !first.isEmpty(); }
{ };
return !first.isEmpty();
}
} ;
/** @brief Abbreviation, used internally. */ /** @brief Abbreviation, used internally. */
using CommandList_t = QList< CommandLine >; using CommandList_t = QList< CommandLine >;
@ -88,19 +79,16 @@ public:
CommandList( const QVariant& v, bool doChroot = true, std::chrono::seconds timeout = std::chrono::seconds( 10 ) ); CommandList( const QVariant& v, bool doChroot = true, std::chrono::seconds timeout = std::chrono::seconds( 10 ) );
~CommandList(); ~CommandList();
bool doChroot() const bool doChroot() const { return m_doChroot; }
{
return m_doChroot;
}
Calamares::JobResult run(); Calamares::JobResult run();
using CommandList_t::isEmpty; using CommandList_t::at;
using CommandList_t::count;
using CommandList_t::cbegin; using CommandList_t::cbegin;
using CommandList_t::cend; using CommandList_t::cend;
using CommandList_t::const_iterator; using CommandList_t::const_iterator;
using CommandList_t::at; using CommandList_t::count;
using CommandList_t::isEmpty;
protected: protected:
using CommandList_t::append; using CommandList_t::append;
@ -109,7 +97,7 @@ protected:
private: private:
bool m_doChroot; bool m_doChroot;
std::chrono::seconds m_timeout; std::chrono::seconds m_timeout;
} ; };
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -101,17 +101,25 @@ mungeEnvironment( QStringList& l, const char* name, const char* defaultDirs )
QStringList dirs = QString( qgetenv( name ) ).split( ':' ); QStringList dirs = QString( qgetenv( name ) ).split( ':' );
if ( dirs.isEmpty() ) if ( dirs.isEmpty() )
{
dirs = QString( defaultDirs ).split( ':' ); dirs = QString( defaultDirs ).split( ':' );
}
for ( auto s : dirs ) for ( auto s : dirs )
{ {
if ( s.isEmpty() ) if ( s.isEmpty() )
{
continue; continue;
}
if ( s.endsWith( '/' ) ) if ( s.endsWith( '/' ) )
{
l << ( s + calamaresSubdir ) << s; l << ( s + calamaresSubdir ) << s;
}
else else
{
l << ( s + '/' + calamaresSubdir ) << ( s + '/' ); l << ( s + '/' + calamaresSubdir ) << ( s + '/' );
} }
}
} }
void void
@ -127,7 +135,9 @@ QStringList
extraConfigDirs() extraConfigDirs()
{ {
if ( s_haveExtraDirs ) if ( s_haveExtraDirs )
{
return s_extraConfigDirs; return s_extraConfigDirs;
}
return QStringList(); return QStringList();
} }
@ -135,7 +145,9 @@ QStringList
extraDataDirs() extraDataDirs()
{ {
if ( s_haveExtraDirs ) if ( s_haveExtraDirs )
{
return s_extraDataDirs; return s_extraDataDirs;
}
return QStringList(); return QStringList();
} }
@ -173,12 +185,16 @@ appLogDir()
QString path = QStandardPaths::writableLocation( QStandardPaths::CacheLocation ); QString path = QStandardPaths::writableLocation( QStandardPaths::CacheLocation );
QDir dir( path ); QDir dir( path );
if ( isWritableDir( dir ) ) if ( isWritableDir( dir ) )
{
return dir; return dir;
}
cerr << "warning: Could not find a standard writable location for log dir, falling back to $HOME\n"; cerr << "warning: Could not find a standard writable location for log dir, falling back to $HOME\n";
dir = QDir::home(); dir = QDir::home();
if ( isWritableDir( dir ) ) if ( isWritableDir( dir ) )
{
return dir; return dir;
}
cerr << "warning: Found no writable location for log dir, falling back to the temp dir\n"; cerr << "warning: Found no writable location for log dir, falling back to the temp dir\n";
return QDir::temp(); return QDir::temp();
@ -191,4 +207,4 @@ setQmlModulesDir( const QDir& dir )
s_qmlModulesDir = dir; s_qmlModulesDir = dir;
} }
} // namespace } // namespace CalamaresUtils

View File

@ -31,43 +31,43 @@
namespace CalamaresUtils namespace CalamaresUtils
{ {
DLLEXPORT QDir qmlModulesDir(); DLLEXPORT QDir qmlModulesDir();
/** /**
* @brief appDataDir returns the directory with common application data. * @brief appDataDir returns the directory with common application data.
* Defaults to CMAKE_INSTALL_FULL_DATADIR (usually /usr/share/calamares). * Defaults to CMAKE_INSTALL_FULL_DATADIR (usually /usr/share/calamares).
*/ */
DLLEXPORT QDir appDataDir(); DLLEXPORT QDir appDataDir();
/** /**
* @brief appLogDir returns the directory for Calamares logs. * @brief appLogDir returns the directory for Calamares logs.
* Defaults to QStandardPaths::CacheLocation (usually ~/.cache/Calamares). * Defaults to QStandardPaths::CacheLocation (usually ~/.cache/Calamares).
*/ */
DLLEXPORT QDir appLogDir(); DLLEXPORT QDir appLogDir();
/** /**
* @brief systemLibDir returns the system's lib directory. * @brief systemLibDir returns the system's lib directory.
* Defaults to CMAKE_INSTALL_FULL_LIBDIR (usually /usr/lib64 or /usr/lib). * Defaults to CMAKE_INSTALL_FULL_LIBDIR (usually /usr/lib64 or /usr/lib).
*/ */
DLLEXPORT QDir systemLibDir(); DLLEXPORT QDir systemLibDir();
/** /**
* Override app data dir. Only for testing purposes. * Override app data dir. Only for testing purposes.
*/ */
DLLEXPORT void setAppDataDir( const QDir& dir ); DLLEXPORT void setAppDataDir( const QDir& dir );
DLLEXPORT bool isAppDataDirOverridden(); DLLEXPORT bool isAppDataDirOverridden();
DLLEXPORT void setQmlModulesDir( const QDir& dir ); DLLEXPORT void setQmlModulesDir( const QDir& dir );
/** @brief Setup extra config and data dirs from the XDG variables. /** @brief Setup extra config and data dirs from the XDG variables.
*/ */
DLLEXPORT void setXdgDirs(); DLLEXPORT void setXdgDirs();
/** @brief Are any extra directories configured? */ /** @brief Are any extra directories configured? */
DLLEXPORT bool haveExtraDirs(); DLLEXPORT bool haveExtraDirs();
/** @brief XDG_CONFIG_DIRS, each guaranteed to end with / */ /** @brief XDG_CONFIG_DIRS, each guaranteed to end with / */
DLLEXPORT QStringList extraConfigDirs(); DLLEXPORT QStringList extraConfigDirs();
/** @brief XDG_DATA_DIRS, each guaranteed to end with / */ /** @brief XDG_DATA_DIRS, each guaranteed to end with / */
DLLEXPORT QStringList extraDataDirs(); DLLEXPORT QStringList extraDataDirs();
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -20,8 +20,8 @@
#include "Logger.h" #include "Logger.h"
#include <iostream>
#include <fstream> #include <fstream>
#include <iostream>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
@ -30,8 +30,8 @@
#include <QTime> #include <QTime>
#include <QVariant> #include <QVariant>
#include "utils/Dirs.h"
#include "CalamaresVersion.h" #include "CalamaresVersion.h"
#include "utils/Dirs.h"
#define LOGFILE_SIZE 1024 * 256 #define LOGFILE_SIZE 1024 * 256
@ -48,15 +48,17 @@ namespace Logger
{ {
void void
setupLogLevel(unsigned int level) setupLogLevel( unsigned int level )
{ {
if ( level > LOGVERBOSE ) if ( level > LOGVERBOSE )
{
level = LOGVERBOSE; level = LOGVERBOSE;
}
s_threshold = level + 1; // Comparison is < in log() function s_threshold = level + 1; // Comparison is < in log() function
} }
bool bool
logLevelEnabled(unsigned int level) logLevelEnabled( unsigned int level )
{ {
return level < s_threshold; return level < s_threshold;
} }
@ -77,11 +79,9 @@ log( const char* msg, unsigned int debugLevel )
// If we don't format the date as a Qt::ISODate then we get a crash when // If we don't format the date as a Qt::ISODate then we get a crash when
// logging at exit as Qt tries to use QLocale to format, but QLocale is // logging at exit as Qt tries to use QLocale to format, but QLocale is
// on its way out. // on its way out.
logfile << QDate::currentDate().toString( Qt::ISODate ).toUtf8().data() logfile << QDate::currentDate().toString( Qt::ISODate ).toUtf8().data() << " - "
<< " - " << QTime::currentTime().toString().toUtf8().data() << " ["
<< QTime::currentTime().toString().toUtf8().data() << QString::number( debugLevel ).toUtf8().data() << "]: " << msg << std::endl;
<< " [" << QString::number( debugLevel ).toUtf8().data() << "]: "
<< msg << std::endl;
logfile.flush(); logfile.flush();
} }
@ -90,9 +90,8 @@ log( const char* msg, unsigned int debugLevel )
{ {
QMutexLocker lock( &s_mutex ); QMutexLocker lock( &s_mutex );
std::cout << QTime::currentTime().toString().toUtf8().data() std::cout << QTime::currentTime().toString().toUtf8().data() << " ["
<< " [" << QString::number( debugLevel ).toUtf8().data() << "]: " << QString::number( debugLevel ).toUtf8().data() << "]: " << msg << std::endl;
<< msg << std::endl;
std::cout.flush(); std::cout.flush();
} }
} }
@ -107,7 +106,7 @@ CalamaresLogHandler( QtMsgType type, const QMessageLogContext&, const QString& m
const char* message = ba.constData(); const char* message = ba.constData();
QMutexLocker locker( &s_mutex ); QMutexLocker locker( &s_mutex );
switch( type ) switch ( type )
{ {
case QtDebugMsg: case QtDebugMsg:
log( message, LOGVERBOSE ); log( message, LOGVERBOSE );
@ -164,7 +163,9 @@ setupLogfile()
QMutexLocker lock( &s_mutex ); QMutexLocker lock( &s_mutex );
logfile.open( logFile().toLocal8Bit(), std::ios::app ); logfile.open( logFile().toLocal8Bit(), std::ios::app );
if ( logfile.tellp() ) if ( logfile.tellp() )
{
logfile << "\n\n" << std::endl; logfile << "\n\n" << std::endl;
}
logfile << "=== START CALAMARES " << CALAMARES_VERSION << std::endl; logfile << "=== START CALAMARES " << CALAMARES_VERSION << std::endl;
} }
@ -183,14 +184,13 @@ CLog::~CLog()
log( m_msg.toUtf8().data(), m_debugLevel ); log( m_msg.toUtf8().data(), m_debugLevel );
} }
CDebug::~CDebug() CDebug::~CDebug() {}
{
}
const char Continuation[] = "\n "; const char Continuation[] = "\n ";
const char SubEntry[] = " .. "; const char SubEntry[] = " .. ";
QString toString( const QVariant& v ) QString
toString( const QVariant& v )
{ {
auto t = v.type(); auto t = v.type();
@ -199,11 +199,15 @@ QString toString( const QVariant& v )
QStringList s; QStringList s;
auto l = v.toList(); auto l = v.toList();
for ( auto lit = l.constBegin(); lit != l.constEnd(); ++lit ) for ( auto lit = l.constBegin(); lit != l.constEnd(); ++lit )
{
s << lit->toString(); s << lit->toString();
return s.join(", "); }
return s.join( ", " );
} }
else else
{
return v.toString(); return v.toString();
}
} }
} // namespace } // namespace Logger

View File

@ -27,11 +27,11 @@
namespace Logger namespace Logger
{ {
DLLEXPORT extern const char Continuation[]; DLLEXPORT extern const char Continuation[];
DLLEXPORT extern const char SubEntry[]; DLLEXPORT extern const char SubEntry[];
enum enum
{ {
LOG_DISABLE = 0, LOG_DISABLE = 0,
LOGERROR = 1, LOGERROR = 1,
LOGWARNING = 2, LOGWARNING = 2,
@ -39,47 +39,52 @@ namespace Logger
LOGEXTRA = 5, LOGEXTRA = 5,
LOGDEBUG = 6, LOGDEBUG = 6,
LOGVERBOSE = 8 LOGVERBOSE = 8
} ; };
class DLLEXPORT CLog : public QDebug class DLLEXPORT CLog : public QDebug
{ {
public: public:
explicit CLog( unsigned int debugLevel ); explicit CLog( unsigned int debugLevel );
virtual ~CLog(); virtual ~CLog();
private: private:
QString m_msg; QString m_msg;
unsigned int m_debugLevel; unsigned int m_debugLevel;
}; };
class DLLEXPORT CDebug : public CLog class DLLEXPORT CDebug : public CLog
{ {
public: public:
CDebug( unsigned int debugLevel = LOGDEBUG ) : CLog( debugLevel ) CDebug( unsigned int debugLevel = LOGDEBUG )
: CLog( debugLevel )
{ {
if ( debugLevel <= LOGERROR ) if ( debugLevel <= LOGERROR )
{
*this << "ERROR:"; *this << "ERROR:";
}
else if ( debugLevel <= LOGWARNING ) else if ( debugLevel <= LOGWARNING )
{
*this << "WARNING:"; *this << "WARNING:";
} }
}
virtual ~CDebug(); virtual ~CDebug();
}; };
/** /**
* @brief The full path of the log file. * @brief The full path of the log file.
*/ */
DLLEXPORT QString logFile(); DLLEXPORT QString logFile();
/** /**
* @brief Start logging to the log file. * @brief Start logging to the log file.
* *
* Call this (once) to start logging to the log file (usually * Call this (once) to start logging to the log file (usually
* ~/.cache/calamares/session.log ). An existing log file is * ~/.cache/calamares/session.log ). An existing log file is
* rolled over if it is too large. * rolled over if it is too large.
*/ */
DLLEXPORT void setupLogfile(); DLLEXPORT void setupLogfile();
/** /**
* @brief Set a log level for future logging. * @brief Set a log level for future logging.
* *
* Pass in a value from the LOG* enum, above. Use 0 to * Pass in a value from the LOG* enum, above. Use 0 to
@ -88,15 +93,15 @@ namespace Logger
* *
* Practical values are 0, 1, 2, and 6. * Practical values are 0, 1, 2, and 6.
*/ */
DLLEXPORT void setupLogLevel( unsigned int level ); DLLEXPORT void setupLogLevel( unsigned int level );
/** @brief Return the configured log-level. */ /** @brief Return the configured log-level. */
DLLEXPORT unsigned int logLevel(); DLLEXPORT unsigned int logLevel();
/** @brief Would the given @p level really be logged? */ /** @brief Would the given @p level really be logged? */
DLLEXPORT bool logLevelEnabled( unsigned int level ); DLLEXPORT bool logLevelEnabled( unsigned int level );
/** /**
* @brief Row-oriented formatted logging. * @brief Row-oriented formatted logging.
* *
* Use DebugRow to produce multiple rows of 2-column output * Use DebugRow to produce multiple rows of 2-column output
@ -106,20 +111,21 @@ namespace Logger
* will produce a single timestamped debug line with continuations. * will produce a single timestamped debug line with continuations.
* Each DebugRow produces one line of output, with the two values. * Each DebugRow produces one line of output, with the two values.
*/ */
template<typename T, typename U> template < typename T, typename U >
struct DebugRow struct DebugRow
{
public:
explicit DebugRow( const T& t, const U& u )
: first( t )
, second( u )
{ {
public: }
explicit DebugRow(const T& t, const U& u)
: first(t)
, second(u)
{}
const T& first; const T& first;
const U& second; const U& second;
} ; };
/** /**
* @brief List-oriented formatted logging. * @brief List-oriented formatted logging.
* *
* Use DebugList to produce multiple rows of output in a debugging * Use DebugList to produce multiple rows of output in a debugging
@ -128,16 +134,17 @@ namespace Logger
* will produce a single timestamped debug line with continuations. * will produce a single timestamped debug line with continuations.
* Each element of the list of strings will be logged on a separate line. * Each element of the list of strings will be logged on a separate line.
*/ */
struct DebugList struct DebugList
{ {
explicit DebugList( const QStringList& l ) explicit DebugList( const QStringList& l )
: list(l) : list( l )
{} {
}
const QStringList& list; const QStringList& list;
} ; };
/** /**
* @brief Map-oriented formatted logging. * @brief Map-oriented formatted logging.
* *
* Use DebugMap to produce multiple rows of output in a debugging * Use DebugMap to produce multiple rows of output in a debugging
@ -147,49 +154,54 @@ namespace Logger
* The continued lines will have a key (from the map) and a value * The continued lines will have a key (from the map) and a value
* on each line. * on each line.
*/ */
struct DebugMap struct DebugMap
{ {
public: public:
explicit DebugMap(const QVariantMap& m) explicit DebugMap( const QVariantMap& m )
: map( m ) : map( m )
{} {
}
const QVariantMap& map; const QVariantMap& map;
} ; };
/** @brief output operator for DebugRow */ /** @brief output operator for DebugRow */
template<typename T, typename U> template < typename T, typename U >
inline QDebug& inline QDebug&
operator <<( QDebug& s, const DebugRow<T, U>& t ) operator<<( QDebug& s, const DebugRow< T, U >& t )
{ {
s << Continuation << t.first << ':' << ' ' << t.second; s << Continuation << t.first << ':' << ' ' << t.second;
return s; return s;
} }
/** @brief output operator for DebugList */ /** @brief output operator for DebugList */
inline QDebug& inline QDebug&
operator <<( QDebug& s, const DebugList& c ) operator<<( QDebug& s, const DebugList& c )
{
for ( const auto& i : c.list )
{ {
for( const auto& i : c.list )
s << Continuation << i; s << Continuation << i;
return s;
} }
return s;
}
/** @brief supporting method for outputting a DebugMap */ /** @brief supporting method for outputting a DebugMap */
QString toString( const QVariant& v ); QString toString( const QVariant& v );
/** @brief output operator for DebugMap */ /** @brief output operator for DebugMap */
inline QDebug& inline QDebug&
operator <<( QDebug& s, const DebugMap& t ) operator<<( QDebug& s, const DebugMap& t )
{ {
for ( auto it = t.map.constBegin(); it != t.map.constEnd(); ++it ) for ( auto it = t.map.constBegin(); it != t.map.constEnd(); ++it )
{
s << Continuation << it.key().toUtf8().constData() << ':' << ' ' << toString( it.value() ).toUtf8().constData(); s << Continuation << it.key().toUtf8().constData() << ':' << ' ' << toString( it.value() ).toUtf8().constData();
return s;
} }
} // namespace return s;
}
} // namespace Logger
#define cDebug Logger::CDebug #define cDebug Logger::CDebug
#define cWarning() Logger::CDebug(Logger::LOGWARNING) #define cWarning() Logger::CDebug( Logger::LOGWARNING )
#define cError() Logger::CDebug(Logger::LOGERROR) #define cError() Logger::CDebug( Logger::LOGERROR )
#endif #endif

View File

@ -31,12 +31,12 @@
#include <QString> #include <QString>
#include <vector>
#include <type_traits>
#include <initializer_list> #include <initializer_list>
#include <type_traits>
#include <vector>
/** @brief Type for collecting parts of a named enum. */ /** @brief Type for collecting parts of a named enum. */
template<typename T> template < typename T >
struct NamedEnumTable struct NamedEnumTable
{ {
using string_t = QString; using string_t = QString;
@ -53,7 +53,11 @@ struct NamedEnumTable
* *
* static const NamedEnumTable<Colors> c{ {"red", Colors::Red } }; * static const NamedEnumTable<Colors> c{ {"red", Colors::Red } };
*/ */
NamedEnumTable( const std::initializer_list< pair_t >& v ) : table( v ) { /* static_assert( v.size() > 0 ); */ } NamedEnumTable( const std::initializer_list< pair_t >& v )
: table( v )
{
/* static_assert( v.size() > 0 ); */
}
/** @brief Find a name @p s in the table. /** @brief Find a name @p s in the table.
* *
@ -89,8 +93,8 @@ struct NamedEnumTable
{ {
ok = false; ok = false;
for ( const auto &p : table ) for ( const auto& p : table )
if ( s == p.second) if ( s == p.second )
{ {
ok = true; ok = true;
return p.first; return p.first;
@ -99,13 +103,14 @@ struct NamedEnumTable
// ok is still false // ok is still false
return string_t(); return string_t();
} }
} ; };
/** @brief Smashes an enum value to its underlying type. */ /** @brief Smashes an enum value to its underlying type. */
template<typename E> template < typename E >
constexpr typename std::underlying_type<E>::type smash( const E e ) constexpr typename std::underlying_type< E >::type
smash( const E e )
{ {
return static_cast<typename std::underlying_type<E>::type>( e ); return static_cast< typename std::underlying_type< E >::type >( e );
} }
#endif #endif

View File

@ -42,7 +42,7 @@
#include "NamedEnum.h" #include "NamedEnum.h"
/** @brief Template that takes the enum type to work with and a special none-enum. */ /** @brief Template that takes the enum type to work with and a special none-enum. */
template<typename T, T _none> template < typename T, T _none >
class NamedSuffix class NamedSuffix
{ {
public: public:
@ -52,7 +52,7 @@ public:
/** @brief Empty value. */ /** @brief Empty value. */
NamedSuffix() NamedSuffix()
: m_value(0) : m_value( 0 )
, m_unit( none ) , m_unit( none )
{ {
} }
@ -69,10 +69,10 @@ public:
* This parses the given string @p s by comparing with the suffixes * This parses the given string @p s by comparing with the suffixes
* in @p table and uses the first matching suffix as the unit. * in @p table and uses the first matching suffix as the unit.
*/ */
NamedSuffix( const NamedEnumTable<T>& table, const QString& s ) NamedSuffix( const NamedEnumTable< T >& table, const QString& s )
: NamedSuffix() : NamedSuffix()
{ {
for( const auto& suffix : table.table ) for ( const auto& suffix : table.table )
if ( s.endsWith( suffix.first ) ) if ( s.endsWith( suffix.first ) )
{ {
m_value = s.left( s.length() - suffix.first.length() ).toInt(); m_value = s.left( s.length() - suffix.first.length() ).toInt();

View File

@ -24,8 +24,11 @@
#include "PluginFactory.h" #include "PluginFactory.h"
#include "PluginFactory_p.h" #include "PluginFactory_p.h"
#include <QObjectCleanupHandler>
#include <QDebug> #include <QDebug>
#include <QObjectCleanupHandler>
// *INDENT-OFF*
// clang-format off
Q_GLOBAL_STATIC( QObjectCleanupHandler, factorycleanup ) Q_GLOBAL_STATIC( QObjectCleanupHandler, factorycleanup )

View File

@ -27,8 +27,11 @@
#include "DllMacro.h" #include "DllMacro.h"
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QVariant>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QVariant>
// *INDENT-OFF*
// clang-format off
namespace Calamares namespace Calamares
{ {

View File

@ -32,23 +32,24 @@ namespace Calamares
class PluginFactoryPrivate class PluginFactoryPrivate
{ {
Q_DECLARE_PUBLIC(PluginFactory) Q_DECLARE_PUBLIC( PluginFactory )
protected: protected:
typedef QPair<const QMetaObject *, PluginFactory::CreateInstanceFunction> Plugin; typedef QPair< const QMetaObject*, PluginFactory::CreateInstanceFunction > Plugin;
PluginFactoryPrivate() PluginFactoryPrivate()
: catalogInitialized( false ) : catalogInitialized( false )
, q_ptr( nullptr ) , q_ptr( nullptr )
{} {
}
~PluginFactoryPrivate() {} ~PluginFactoryPrivate() {}
QHash<QString, Plugin> createInstanceHash; QHash< QString, Plugin > createInstanceHash;
QString catalogName; QString catalogName;
bool catalogInitialized; bool catalogInitialized;
PluginFactory *q_ptr; PluginFactory* q_ptr;
}; };
} // namespace } // namespace Calamares
#endif #endif

View File

@ -26,27 +26,30 @@
#include <QTranslator> #include <QTranslator>
namespace CalamaresUtils { namespace CalamaresUtils
{
static QTranslator* s_brandingTranslator = nullptr; static QTranslator* s_brandingTranslator = nullptr;
static QTranslator* s_translator = nullptr; static QTranslator* s_translator = nullptr;
static QString s_translatorLocaleName; static QString s_translatorLocaleName;
void void
installTranslator( const QLocale& locale, installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* parent )
const QString& brandingTranslationsPrefix,
QObject* parent )
{ {
QString localeName = locale.name(); QString localeName = locale.name();
localeName.replace( "-", "_" ); localeName.replace( "-", "_" );
if ( localeName == "C" ) if ( localeName == "C" )
{
localeName = "en"; localeName = "en";
}
// Special case of sr@latin // Special case of sr@latin
// //
// See top-level CMakeLists.txt about special cases for translation loading. // See top-level CMakeLists.txt about special cases for translation loading.
if ( locale.language() == QLocale::Language::Serbian && locale.script() == QLocale::Script::LatinScript ) if ( locale.language() == QLocale::Language::Serbian && locale.script() == QLocale::Script::LatinScript )
{
localeName = QStringLiteral( "sr@latin" ); localeName = QStringLiteral( "sr@latin" );
}
cDebug() << "Looking for translations for" << localeName; cDebug() << "Looking for translations for" << localeName;
@ -56,19 +59,14 @@ installTranslator( const QLocale& locale,
if ( !brandingTranslationsPrefix.isEmpty() ) if ( !brandingTranslationsPrefix.isEmpty() )
{ {
QString brandingTranslationsDirPath( brandingTranslationsPrefix ); QString brandingTranslationsDirPath( brandingTranslationsPrefix );
brandingTranslationsDirPath.truncate( brandingTranslationsPrefix.lastIndexOf( brandingTranslationsDirPath.truncate( brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) );
QDir::separator() ) );
QDir brandingTranslationsDir( brandingTranslationsDirPath ); QDir brandingTranslationsDir( brandingTranslationsDirPath );
if ( brandingTranslationsDir.exists() ) if ( brandingTranslationsDir.exists() )
{ {
QString filenameBase( brandingTranslationsPrefix ); QString filenameBase( brandingTranslationsPrefix );
filenameBase.remove( 0, brandingTranslationsPrefix.lastIndexOf( filenameBase.remove( 0, brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) + 1 );
QDir::separator() ) + 1 );
translator = new QTranslator( parent ); translator = new QTranslator( parent );
if ( translator->load( locale, if ( translator->load( locale, filenameBase, "_", brandingTranslationsDir.absolutePath() ) )
filenameBase,
"_",
brandingTranslationsDir.absolutePath() ) )
{ {
cDebug() << Logger::SubEntry << "Branding using locale:" << localeName; cDebug() << Logger::SubEntry << "Branding using locale:" << localeName;
} }
@ -121,19 +119,22 @@ translatorLocaleName()
} }
void void
Retranslator::attachRetranslator( QObject* parent, Retranslator::attachRetranslator( QObject* parent, std::function< void( void ) > retranslateFunc )
std::function< void ( void ) > retranslateFunc )
{ {
Retranslator* r = nullptr; Retranslator* r = nullptr;
for ( QObject* child : parent->children() ) for ( QObject* child : parent->children() )
{ {
r = qobject_cast< Retranslator* >( child ); r = qobject_cast< Retranslator* >( child );
if ( r ) if ( r )
{
break; break;
} }
}
if ( !r ) if ( !r )
{
r = new Retranslator( parent ); r = new Retranslator( parent );
}
r->m_retranslateFuncList.append( retranslateFunc ); r->m_retranslateFuncList.append( retranslateFunc );
retranslateFunc(); retranslateFunc();
@ -155,9 +156,11 @@ Retranslator::eventFilter( QObject* obj, QEvent* e )
if ( e->type() == QEvent::LanguageChange ) if ( e->type() == QEvent::LanguageChange )
{ {
foreach ( std::function< void() > func, m_retranslateFuncList ) foreach ( std::function< void() > func, m_retranslateFuncList )
{
func(); func();
} }
} }
}
// pass the event on to the base // pass the event on to the base
return QObject::eventFilter( obj, e ); return QObject::eventFilter( obj, e );
} }

View File

@ -32,24 +32,21 @@ class QLocale;
namespace CalamaresUtils namespace CalamaresUtils
{ {
/** /**
* @brief installTranslator changes the application language. * @brief installTranslator changes the application language.
* @param locale the new locale. * @param locale the new locale.
* @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding. * @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding.
* @param parent the parent QObject. * @param parent the parent QObject.
*/ */
DLLEXPORT void installTranslator( const QLocale& locale, DLLEXPORT void installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* parent );
const QString& brandingTranslationsPrefix,
QObject* parent );
DLLEXPORT QString translatorLocaleName(); DLLEXPORT QString translatorLocaleName();
class Retranslator : public QObject class Retranslator : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static void attachRetranslator( QObject* parent, static void attachRetranslator( QObject* parent, std::function< void( void ) > retranslateFunc );
std::function< void( void ) > retranslateFunc );
void addRetranslateFunc( std::function< void( void ) > retranslateFunc ); void addRetranslateFunc( std::function< void( void ) > retranslateFunc );
@ -63,11 +60,10 @@ private:
}; };
} // namespace } // namespace CalamaresUtils
#define CALAMARES_RETRANSLATE(body) \ #define CALAMARES_RETRANSLATE( body ) CalamaresUtils::Retranslator::attachRetranslator( this, [=] { body } );
CalamaresUtils::Retranslator::attachRetranslator( this, [=] { body } ); #define CALAMARES_RETRANSLATE_WIDGET( widget, body ) \
#define CALAMARES_RETRANSLATE_WIDGET(widget,body) \
CalamaresUtils::Retranslator::attachRetranslator( widget, [=] { body } ); CalamaresUtils::Retranslator::attachRetranslator( widget, [=] { body } );
#endif #endif

View File

@ -31,6 +31,11 @@ namespace CalamaresUtils
QString QString
removeDiacritics( const QString& string ) removeDiacritics( const QString& string )
{ {
// *INDENT-OFF*
// clang-format off
// Map these extended-Latin characters to ASCII; keep the
// layout so that one line in *diacriticLetters* corresponds
// to one line of replacements in *noDiacriticLetters*.
static const QString diacriticLetters = QString::fromUtf8( static const QString diacriticLetters = QString::fromUtf8(
"ŠŒŽšœžŸ¥µÀ" "ŠŒŽšœžŸ¥µÀ"
"ÁÂÃÄÅÆÇÈÉÊ" "ÁÂÃÄÅÆÇÈÉÊ"
@ -65,9 +70,11 @@ removeDiacritics( const QString& string )
"r", "A", "a", "E", "e", "L", "l", "N", "n", "S", "r", "A", "a", "E", "e", "L", "l", "N", "n", "S",
"s", "Z", "z", "Z", "z" "s", "Z", "z", "Z", "z"
}; };
// clang-format on
// *INDENT-ON*
QString output; QString output;
for ( const QChar &c : string ) for ( const QChar& c : string )
{ {
int i = diacriticLetters.indexOf( c ); int i = diacriticLetters.indexOf( c );
if ( i < 0 ) if ( i < 0 )
@ -112,14 +119,14 @@ QString
obscure( const QString& string ) obscure( const QString& string )
{ {
QString result; QString result;
const QChar *unicode = string.unicode(); const QChar* unicode = string.unicode();
for ( int i = 0; i < string.length(); ++i ) for ( int i = 0; i < string.length(); ++i )
// yes, no typo. can't encode ' ' or '!' because // yes, no typo. can't encode ' ' or '!' because
// they're the unicode BOM. stupid scrambling. stupid. // they're the unicode BOM. stupid scrambling. stupid.
result += ( unicode[ i ].unicode() <= 0x21 ) ? {
unicode[ i ] : result += ( unicode[ i ].unicode() <= 0x21 ) ? unicode[ i ] : QChar( 0x1001F - unicode[ i ].unicode() );
QChar( 0x1001F - unicode[ i ].unicode() ); }
return result; return result;
} }
} } // namespace CalamaresUtils

View File

@ -34,20 +34,20 @@
*/ */
namespace CalamaresUtils namespace CalamaresUtils
{ {
/** /**
* @brief removeDiacritics replaces letters with diacritics and ligatures with * @brief removeDiacritics replaces letters with diacritics and ligatures with
* alternative forms and digraphs. * alternative forms and digraphs.
* @param string the string to transform. * @param string the string to transform.
* @return the output string with plain characters. * @return the output string with plain characters.
*/ */
DLLEXPORT QString removeDiacritics( const QString& string ); DLLEXPORT QString removeDiacritics( const QString& string );
/** /**
* @brief obscure is a bidirectional obfuscation function, from KStringHandler. * @brief obscure is a bidirectional obfuscation function, from KStringHandler.
* @param string the input string. * @param string the input string.
* @return the obfuscated string. * @return the obfuscated string.
*/ */
DLLEXPORT QString obscure( const QString& string ); DLLEXPORT QString obscure( const QString& string );
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -26,76 +26,88 @@ namespace CalamaresUtils
{ {
/** User defined literals, 1_KiB is 1 KibiByte (= 2^10 bytes) */ /** User defined literals, 1_KiB is 1 KibiByte (= 2^10 bytes) */
constexpr qint64 operator ""_KiB( unsigned long long m ) constexpr qint64 operator""_KiB( unsigned long long m )
{ {
return qint64(m) * 1024; return qint64( m ) * 1024;
} }
/** User defined literals, 1_MiB is 1 MibiByte (= 2^20 bytes) */ /** User defined literals, 1_MiB is 1 MibiByte (= 2^20 bytes) */
constexpr qint64 operator ""_MiB( unsigned long long m ) constexpr qint64 operator""_MiB( unsigned long long m )
{ {
return operator ""_KiB(m) * 1024; return operator""_KiB(m)*1024;
} }
/** User defined literals, 1_GiB is 1 GibiByte (= 2^30 bytes) */ /** User defined literals, 1_GiB is 1 GibiByte (= 2^30 bytes) */
constexpr qint64 operator ""_GiB( unsigned long long m ) constexpr qint64 operator""_GiB( unsigned long long m )
{ {
return operator ""_MiB(m) * 1024; return operator""_MiB(m)*1024;
} }
constexpr qint64 KiBtoBytes( unsigned long long m ) constexpr qint64
KiBtoBytes( unsigned long long m )
{ {
return operator ""_KiB( m ); return operator""_KiB( m );
} }
constexpr qint64 MiBtoBytes( unsigned long long m ) constexpr qint64
MiBtoBytes( unsigned long long m )
{ {
return operator ""_MiB( m ); return operator""_MiB( m );
} }
constexpr qint64 GiBtoBytes( unsigned long long m ) constexpr qint64
GiBtoBytes( unsigned long long m )
{ {
return operator ""_GiB( m ); return operator""_GiB( m );
} }
constexpr qint64 KiBtoBytes( double m ) constexpr qint64
KiBtoBytes( double m )
{ {
return qint64(m * 1024); return qint64( m * 1024 );
} }
constexpr qint64 MiBtoBytes( double m ) constexpr qint64
MiBtoBytes( double m )
{ {
return qint64(m * 1024 * 1024); return qint64( m * 1024 * 1024 );
} }
constexpr qint64 GiBtoBytes( double m ) constexpr qint64
GiBtoBytes( double m )
{ {
return qint64(m * 1024 * 1024 * 1024); return qint64( m * 1024 * 1024 * 1024 );
} }
constexpr int BytesToMiB( qint64 b ) constexpr int
BytesToMiB( qint64 b )
{ {
return int( b / 1024 / 1024 ); return int( b / 1024 / 1024 );
} }
constexpr int BytesToGiB( qint64 b ) constexpr int
BytesToGiB( qint64 b )
{ {
return int( b / 1024 / 1024 / 1024 ); return int( b / 1024 / 1024 / 1024 );
} }
constexpr qint64 alignBytesToBlockSize( qint64 bytes, qint64 blocksize ) constexpr qint64
alignBytesToBlockSize( qint64 bytes, qint64 blocksize )
{ {
qint64 blocks = bytes / blocksize; qint64 blocks = bytes / blocksize;
if ( blocks * blocksize != bytes ) if ( blocks * blocksize != bytes )
{
++blocks; ++blocks;
}
return blocks * blocksize; return blocks * blocksize;
} }
constexpr qint64 bytesToSectors( qint64 bytes, qint64 blocksize ) constexpr qint64
bytesToSectors( qint64 bytes, qint64 blocksize )
{ {
return alignBytesToBlockSize( alignBytesToBlockSize( bytes, blocksize), MiBtoBytes(1ULL) ) / blocksize; return alignBytesToBlockSize( alignBytesToBlockSize( bytes, blocksize ), MiBtoBytes( 1ULL ) ) / blocksize;
} }
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -39,21 +39,25 @@ getBool( const QVariantMap& map, const QString& key, bool d )
{ {
auto v = map.value( key ); auto v = map.value( key );
if ( v.type() == QVariant::Bool ) if ( v.type() == QVariant::Bool )
{
result = v.toBool(); result = v.toBool();
} }
}
return result; return result;
} }
QString QString
getString(const QVariantMap& map, const QString& key) getString( const QVariantMap& map, const QString& key )
{ {
if ( map.contains( key ) ) if ( map.contains( key ) )
{ {
auto v = map.value( key ); auto v = map.value( key );
if ( v.type() == QVariant::String ) if ( v.type() == QVariant::String )
{
return v.toString(); return v.toString();
} }
}
return QString(); return QString();
} }
@ -65,8 +69,10 @@ getInteger( const QVariantMap& map, const QString& key, int d )
{ {
auto v = map.value( key ); auto v = map.value( key );
if ( v.type() == QVariant::Int ) if ( v.type() == QVariant::Int )
{
result = v.toInt(); result = v.toInt();
} }
}
return result; return result;
} }
@ -79,10 +85,14 @@ getDouble( const QVariantMap& map, const QString& key, double d )
{ {
auto v = map.value( key ); auto v = map.value( key );
if ( v.type() == QVariant::Int ) if ( v.type() == QVariant::Int )
{
result = v.toInt(); result = v.toInt();
}
else if ( v.type() == QVariant::Double ) else if ( v.type() == QVariant::Double )
{
result = v.toDouble(); result = v.toDouble();
} }
}
return result; return result;
} }
@ -104,4 +114,4 @@ getSubMap( const QVariantMap& map, const QString& key, bool& success )
return QVariantMap(); return QVariantMap();
} }
} } // namespace CalamaresUtils

View File

@ -27,28 +27,28 @@
namespace CalamaresUtils namespace CalamaresUtils
{ {
/** /**
* Get a bool value from a mapping with a given key; returns the default * Get a bool value from a mapping with a given key; returns the default
* if no value is stored in the map. * if no value is stored in the map.
*/ */
DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d ); DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d );
/** /**
* Get a string value from a mapping; returns empty QString if no value. * Get a string value from a mapping; returns empty QString if no value.
*/ */
DLLEXPORT QString getString( const QVariantMap& map, const QString& key ); DLLEXPORT QString getString( const QVariantMap& map, const QString& key );
/** /**
* Get an integer value from a mapping; returns @p d if no value. * Get an integer value from a mapping; returns @p d if no value.
*/ */
DLLEXPORT int getInteger( const QVariantMap& map, const QString& key, int d ); DLLEXPORT int getInteger( const QVariantMap& map, const QString& key, int d );
/** /**
* Get a double value from a mapping (integers are converted); returns @p d if no value. * Get a double value from a mapping (integers are converted); returns @p d if no value.
*/ */
DLLEXPORT double getDouble( const QVariantMap& map, const QString& key, double d ); DLLEXPORT double getDouble( const QVariantMap& map, const QString& key, double d );
/** /**
* Returns a sub-map (i.e. a nested map) from the given mapping with the * Returns a sub-map (i.e. a nested map) from the given mapping with the
* given key. @p success is set to true if the @p key exists * given key. @p success is set to true if the @p key exists
* in @p map and converts to a map, false otherwise. * in @p map and converts to a map, false otherwise.
@ -56,7 +56,7 @@ namespace CalamaresUtils
* Returns an empty map if there is no such key or it is not a map-value. * Returns an empty map if there is no such key or it is not a map-value.
* (e.g. if @p success is false). * (e.g. if @p success is false).
*/ */
DLLEXPORT QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success ); DLLEXPORT QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success );
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -70,13 +70,21 @@ yamlScalarToVariant( const YAML::Node& scalarNode )
std::string stdScalar = scalarNode.as< std::string >(); std::string stdScalar = scalarNode.as< std::string >();
QString scalarString = QString::fromStdString( stdScalar ); QString scalarString = QString::fromStdString( stdScalar );
if ( _yamlScalarTrueValues.exactMatch( scalarString ) ) if ( _yamlScalarTrueValues.exactMatch( scalarString ) )
{
return QVariant( true ); return QVariant( true );
}
if ( _yamlScalarFalseValues.exactMatch( scalarString ) ) if ( _yamlScalarFalseValues.exactMatch( scalarString ) )
{
return QVariant( false ); return QVariant( false );
}
if ( QRegExp( "[-+]?\\d+" ).exactMatch( scalarString ) ) if ( QRegExp( "[-+]?\\d+" ).exactMatch( scalarString ) )
{
return QVariant( scalarString.toInt() ); return QVariant( scalarString.toInt() );
}
if ( QRegExp( "[-+]?\\d*\\.?\\d+" ).exactMatch( scalarString ) ) if ( QRegExp( "[-+]?\\d*\\.?\\d+" ).exactMatch( scalarString ) )
{
return QVariant( scalarString.toDouble() ); return QVariant( scalarString.toDouble() );
}
return QVariant( scalarString ); return QVariant( scalarString );
} }
@ -85,8 +93,7 @@ QVariant
yamlSequenceToVariant( const YAML::Node& sequenceNode ) yamlSequenceToVariant( const YAML::Node& sequenceNode )
{ {
QVariantList vl; QVariantList vl;
for ( YAML::const_iterator it = sequenceNode.begin(); for ( YAML::const_iterator it = sequenceNode.begin(); it != sequenceNode.end(); ++it )
it != sequenceNode.end(); ++it )
{ {
vl << yamlToVariant( *it ); vl << yamlToVariant( *it );
} }
@ -98,17 +105,15 @@ QVariant
yamlMapToVariant( const YAML::Node& mapNode ) yamlMapToVariant( const YAML::Node& mapNode )
{ {
QVariantMap vm; QVariantMap vm;
for ( YAML::const_iterator it = mapNode.begin(); for ( YAML::const_iterator it = mapNode.begin(); it != mapNode.end(); ++it )
it != mapNode.end(); ++it )
{ {
vm.insert( QString::fromStdString( it->first.as< std::string >() ), vm.insert( QString::fromStdString( it->first.as< std::string >() ), yamlToVariant( it->second ) );
yamlToVariant( it->second ) );
} }
return vm; return vm;
} }
QStringList QStringList
yamlToStringList(const YAML::Node& listNode) yamlToStringList( const YAML::Node& listNode )
{ {
QStringList l; QStringList l;
listNode >> l; listNode >> l;
@ -117,7 +122,7 @@ yamlToStringList(const YAML::Node& listNode)
void void
explainYamlException( const YAML::Exception& e, const QByteArray& yamlData, const char *label ) explainYamlException( const YAML::Exception& e, const QByteArray& yamlData, const char* label )
{ {
cWarning() << "YAML error " << e.what() << "in" << label << '.'; cWarning() << "YAML error " << e.what() << "in" << label << '.';
explainYamlException( e, yamlData ); explainYamlException( e, yamlData );
@ -142,7 +147,9 @@ explainYamlException( const YAML::Exception& e, const QByteArray& yamlData )
linestart = yamlData.indexOf( '\n', linestart ); linestart = yamlData.indexOf( '\n', linestart );
// No more \ns found, weird // No more \ns found, weird
if ( linestart < 0 ) if ( linestart < 0 )
{
break; break;
}
linestart += 1; // Skip that \n linestart += 1; // Skip that \n
} }
int lineend = linestart; int lineend = linestart;
@ -150,34 +157,43 @@ explainYamlException( const YAML::Exception& e, const QByteArray& yamlData )
{ {
lineend = yamlData.indexOf( '\n', linestart ); lineend = yamlData.indexOf( '\n', linestart );
if ( lineend < 0 ) if ( lineend < 0 )
{
lineend = yamlData.length(); lineend = yamlData.length();
} }
}
int rangestart = linestart; int rangestart = linestart;
int rangeend = lineend; int rangeend = lineend;
// Adjust range (linestart..lineend) so it's not too long // Adjust range (linestart..lineend) so it's not too long
if ( ( linestart >= 0 ) && ( e.mark.column > 30 ) ) if ( ( linestart >= 0 ) && ( e.mark.column > 30 ) )
{
rangestart += ( e.mark.column - 30 ); rangestart += ( e.mark.column - 30 );
}
if ( ( linestart >= 0 ) && ( rangeend - rangestart > 40 ) ) if ( ( linestart >= 0 ) && ( rangeend - rangestart > 40 ) )
{
rangeend = rangestart + 40; rangeend = rangestart + 40;
}
if ( linestart >= 0 ) if ( linestart >= 0 )
cWarning() << "offending YAML data:" << yamlData.mid( rangestart, rangeend-rangestart ).constData(); {
cWarning() << "offending YAML data:" << yamlData.mid( rangestart, rangeend - rangestart ).constData();
}
} }
} }
QVariantMap QVariantMap
loadYaml(const QFileInfo& fi, bool* ok) loadYaml( const QFileInfo& fi, bool* ok )
{ {
return loadYaml( fi.absoluteFilePath(), ok ); return loadYaml( fi.absoluteFilePath(), ok );
} }
QVariantMap QVariantMap
loadYaml(const QString& filename, bool* ok) loadYaml( const QString& filename, bool* ok )
{ {
if ( ok ) if ( ok )
{
*ok = false; *ok = false;
}
QFile yamlFile( filename ); QFile yamlFile( filename );
QVariant yamlContents; QVariant yamlContents;
@ -197,12 +213,12 @@ loadYaml(const QString& filename, bool* ok)
} }
if ( yamlContents.isValid() && if ( yamlContents.isValid() && !yamlContents.isNull() && yamlContents.type() == QVariant::Map )
!yamlContents.isNull() &&
yamlContents.type() == QVariant::Map )
{ {
if ( ok ) if ( ok )
{
*ok = true; *ok = true;
}
return yamlContents.toMap(); return yamlContents.toMap();
} }
@ -214,7 +230,9 @@ static void
writeIndent( QFile& f, int indent ) writeIndent( QFile& f, int indent )
{ {
while ( indent-- > 0 ) while ( indent-- > 0 )
{
f.write( " " ); f.write( " " );
}
} }
// forward declaration // forward declaration
@ -229,7 +247,9 @@ static void
dumpYamlElement( QFile& f, const QVariant& value, int indent ) dumpYamlElement( QFile& f, const QVariant& value, int indent )
{ {
if ( value.type() == QVariant::Type::Bool ) if ( value.type() == QVariant::Type::Bool )
{
f.write( value.toBool() ? "true" : "false" ); f.write( value.toBool() ? "true" : "false" );
}
else if ( value.type() == QVariant::Type::String ) else if ( value.type() == QVariant::Type::String )
{ {
f.write( quote ); f.write( quote );
@ -251,17 +271,19 @@ dumpYamlElement( QFile& f, const QVariant& value, int indent )
{ {
++c; ++c;
f.write( newline ); f.write( newline );
writeIndent( f, indent+1 ); writeIndent( f, indent + 1 );
f.write( "- " ); f.write( "- " );
dumpYamlElement( f, it, indent+1 ); dumpYamlElement( f, it, indent + 1 );
} }
if ( !c ) // i.e. list was empty if ( !c ) // i.e. list was empty
{
f.write( "[]" ); f.write( "[]" );
} }
}
else if ( value.type() == QVariant::Type::Map ) else if ( value.type() == QVariant::Type::Map )
{ {
f.write( newline ); f.write( newline );
dumpYaml( f, value.toMap(), indent+1 ); dumpYaml( f, value.toMap(), indent + 1 );
} }
else else
{ {
@ -293,12 +315,13 @@ saveYaml( const QString& filename, const QVariantMap& map )
{ {
QFile f( filename ); QFile f( filename );
if ( !f.open( QFile::WriteOnly ) ) if ( !f.open( QFile::WriteOnly ) )
{
return false; return false;
}
f.write( "# YAML dump\n---\n" ); f.write( "# YAML dump\n---\n" );
return dumpYaml( f, map, 0 ); return dumpYaml( f, map, 0 );
} }
} // namespace CalamaresUtils
} // namespace

View File

@ -73,10 +73,10 @@ bool saveYaml( const QString& filename, const QVariantMap& map );
* what is going on in terms of the data passed to the parser. * what is going on in terms of the data passed to the parser.
* Uses @p label when labeling the data source (e.g. "netinstall data") * Uses @p label when labeling the data source (e.g. "netinstall data")
*/ */
void explainYamlException( const YAML::Exception& e, const QByteArray& data, const char *label ); void explainYamlException( const YAML::Exception& e, const QByteArray& data, const char* label );
void explainYamlException( const YAML::Exception& e, const QByteArray& data, const QString& label ); void explainYamlException( const YAML::Exception& e, const QByteArray& data, const QString& label );
void explainYamlException( const YAML::Exception& e, const QByteArray& data ); void explainYamlException( const YAML::Exception& e, const QByteArray& data );
} // namespace } // namespace CalamaresUtils
#endif #endif

View File

@ -57,7 +57,7 @@ Utils::target_env_call( const QString& command,
int timeout ) const int timeout ) const
{ {
return CalamaresUtils::System::instance()-> return CalamaresUtils::System::instance()->
targetEnvCall( command, QString(), stdin, timeout ); targetEnvCall( command, QString(), stdin, std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
} }
@ -67,7 +67,7 @@ Utils::target_env_call( const QStringList& args,
int timeout ) const int timeout ) const
{ {
return CalamaresUtils::System::instance()-> return CalamaresUtils::System::instance()->
targetEnvCall( args, QString(), stdin, timeout ); targetEnvCall( args, QString(), stdin, std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
} }
@ -102,7 +102,7 @@ Utils::check_target_env_output( const QString& command,
output, output,
QString(), QString(),
stdin, stdin,
timeout ); std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
_handle_check_target_env_call_error( ec, command ); _handle_check_target_env_call_error( ec, command );
return output; return output;
} }
@ -119,7 +119,7 @@ Utils::check_target_env_output( const QStringList& args,
output, output,
QString(), QString(),
stdin, stdin,
timeout ); std::chrono::seconds( timeout > 0 ? timeout : 0 ) );
_handle_check_target_env_call_error( ec, args.join( ' ' ) ); _handle_check_target_env_call_error( ec, args.join( ' ' ) );
return output; return output;
} }