Merge branch 'master' into software-chooser
This commit is contained in:
commit
3560ea6622
@ -2,6 +2,7 @@
|
||||
BasedOnStyle: WebKit
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignEscapedNewlines: Left
|
||||
AllowAllParametersOfDeclarationOnNextLine: 'false'
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: 'false'
|
||||
|
@ -35,7 +35,7 @@
|
||||
# One special target is "show-version", which can be built
|
||||
# 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
|
||||
VERSION 3.2.12
|
||||
LANGUAGES C CXX )
|
||||
@ -96,10 +96,10 @@ set( CALAMARES_DESCRIPTION_SUMMARY
|
||||
# (sr@latin in particular) may need special handling in CalamaresUtils.cpp.
|
||||
#
|
||||
# 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
|
||||
# checks for new languages and misspelled ones are done (that is,
|
||||
# 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" )
|
||||
|
||||
# Enable IN_LIST
|
||||
if( POLICY CMP0057 )
|
||||
cmake_policy( SET CMP0057 NEW )
|
||||
endif()
|
||||
# CMake 3.9, 3.10 compatibility
|
||||
if( POLICY CMP0071 )
|
||||
cmake_policy( SET CMP0071 NEW )
|
||||
@ -249,6 +253,15 @@ include( CMakeColors )
|
||||
### DEPENDENCIES
|
||||
#
|
||||
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 )
|
||||
if( INSTALL_POLKIT )
|
||||
find_package( PolkitQt5-1 REQUIRED )
|
||||
|
@ -37,7 +37,7 @@ style_some()
|
||||
if test "x$any_dirs" = "xyes" ; then
|
||||
for d in "$@"
|
||||
do
|
||||
if test -d "$@" ; then
|
||||
if test -d "$d" ; then
|
||||
style_some $( find "$d" -maxdepth 1 -type f -name '*.cpp' -o -name '*.h' )
|
||||
else
|
||||
style_some "$d"
|
||||
|
@ -34,6 +34,7 @@ set( libSources
|
||||
locale/Label.cpp
|
||||
locale/LabelModel.cpp
|
||||
locale/Lookup.cpp
|
||||
locale/TranslatableConfiguration.cpp
|
||||
|
||||
# Partition service
|
||||
partition/PartitionSize.cpp
|
||||
|
@ -24,11 +24,11 @@ namespace Calamares
|
||||
|
||||
CppJob::CppJob( QObject* parent )
|
||||
: Job( parent )
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CppJob::~CppJob()
|
||||
{}
|
||||
CppJob::~CppJob() {}
|
||||
|
||||
|
||||
void
|
||||
@ -44,4 +44,4 @@ CppJob::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
Q_UNUSED( configurationMap )
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Calamares
|
||||
|
@ -45,6 +45,6 @@ protected:
|
||||
QString m_instanceKey;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_CPPJOB_H
|
||||
#endif // CALAMARES_CPPJOB_H
|
||||
|
@ -22,11 +22,11 @@
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef DLLEXPORT
|
||||
# if defined (DLLEXPORT_PRO)
|
||||
# define DLLEXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define DLLEXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#if defined( DLLEXPORT_PRO )
|
||||
#define DLLEXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
#define DLLEXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "JobQueue.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Yaml.h"
|
||||
#include "utils/Units.h"
|
||||
#include "utils/Yaml.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
@ -40,7 +40,8 @@ namespace bp = boost::python;
|
||||
|
||||
using CalamaresUtils::operator""_MiB;
|
||||
|
||||
namespace Calamares {
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
GlobalStorage::GlobalStorage()
|
||||
: QObject( nullptr )
|
||||
@ -102,13 +103,15 @@ GlobalStorage::debugDump() const
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalStorage::save(const QString& filename)
|
||||
GlobalStorage::save( const QString& filename )
|
||||
{
|
||||
QFile f( filename );
|
||||
if ( !f.open( QFile::WriteOnly ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
f.write( QJsonDocument::fromVariant( m ).toJson() ) ;
|
||||
f.write( QJsonDocument::fromVariant( m ).toJson() );
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
@ -118,18 +121,24 @@ GlobalStorage::load( const QString& filename )
|
||||
{
|
||||
QFile f( filename );
|
||||
if ( !f.open( QFile::ReadOnly ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonParseError e;
|
||||
QJsonDocument d = QJsonDocument::fromJson( f.read( 1_MiB ), &e );
|
||||
if ( d.isNull() )
|
||||
{
|
||||
cWarning() << filename << e.errorString();
|
||||
}
|
||||
else if ( !d.isObject() )
|
||||
{
|
||||
cWarning() << filename << "Not suitable JSON.";
|
||||
}
|
||||
else
|
||||
{
|
||||
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 );
|
||||
}
|
||||
@ -150,12 +159,14 @@ GlobalStorage::loadYaml( const QString& filename )
|
||||
bool ok = false;
|
||||
auto gs = CalamaresUtils::loadYaml( filename, &ok );
|
||||
if ( ok )
|
||||
{
|
||||
m = gs;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
|
||||
@ -172,7 +183,7 @@ Calamares::GlobalStorage* GlobalStoragePythonWrapper::s_gs_instance = nullptr;
|
||||
GlobalStoragePythonWrapper::GlobalStoragePythonWrapper( Calamares::GlobalStorage* gs )
|
||||
: m_gs( gs ? gs : s_gs_instance )
|
||||
{
|
||||
if (!m_gs)
|
||||
if ( !m_gs )
|
||||
{
|
||||
s_gs_instance = new Calamares::GlobalStorage;
|
||||
m_gs = s_gs_instance;
|
||||
@ -194,11 +205,9 @@ GlobalStoragePythonWrapper::count() const
|
||||
|
||||
|
||||
void
|
||||
GlobalStoragePythonWrapper::insert( const std::string& key,
|
||||
const bp::object& value )
|
||||
GlobalStoragePythonWrapper::insert( const std::string& key, const bp::object& value )
|
||||
{
|
||||
m_gs->insert( QString::fromStdString( key ),
|
||||
CalamaresPython::variantFromPyObject( value ) );
|
||||
m_gs->insert( QString::fromStdString( key ), CalamaresPython::variantFromPyObject( value ) );
|
||||
}
|
||||
|
||||
bp::list
|
||||
@ -207,7 +216,9 @@ GlobalStoragePythonWrapper::keys() const
|
||||
bp::list pyList;
|
||||
const auto keys = m_gs->keys();
|
||||
for ( const QString& key : keys )
|
||||
{
|
||||
pyList.append( key.toStdString() );
|
||||
}
|
||||
return pyList;
|
||||
}
|
||||
|
||||
@ -225,6 +236,6 @@ GlobalStoragePythonWrapper::value( const std::string& key ) const
|
||||
return CalamaresPython::variantToPyObject( m_gs->value( QString::fromStdString( key ) ) );
|
||||
}
|
||||
|
||||
} // namespace CalamaresPython
|
||||
} // namespace CalamaresPython
|
||||
|
||||
#endif // WITH_PYTHON
|
||||
#endif // WITH_PYTHON
|
||||
|
@ -34,8 +34,8 @@ namespace api
|
||||
class object;
|
||||
}
|
||||
class list;
|
||||
}
|
||||
}
|
||||
} // namespace python
|
||||
} // namespace boost
|
||||
#endif
|
||||
|
||||
namespace Calamares
|
||||
@ -96,7 +96,7 @@ private:
|
||||
friend DebugWindow;
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
namespace CalamaresPython
|
||||
@ -124,7 +124,7 @@ private:
|
||||
static Calamares::GlobalStorage* s_gs_instance; // See globalStorageInstance()
|
||||
};
|
||||
|
||||
} // namespace CalamaresPython
|
||||
} // namespace CalamaresPython
|
||||
#endif
|
||||
|
||||
#endif // CALAMARES_GLOBALSTORAGE_H
|
||||
#endif // CALAMARES_GLOBALSTORAGE_H
|
||||
|
@ -84,7 +84,8 @@ JobResult::JobResult( const QString& message, const QString& details, int number
|
||||
: m_message( message )
|
||||
, m_details( details )
|
||||
, m_number( number )
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Job::Job( QObject* parent )
|
||||
@ -93,8 +94,7 @@ Job::Job( QObject* parent )
|
||||
}
|
||||
|
||||
|
||||
Job::~Job()
|
||||
{}
|
||||
Job::~Job() {}
|
||||
|
||||
|
||||
qreal
|
||||
@ -118,4 +118,4 @@ Job::prettyStatusMessage() const
|
||||
}
|
||||
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
@ -25,7 +25,8 @@
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace Calamares {
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
class DLLEXPORT JobResult
|
||||
{
|
||||
@ -43,7 +44,7 @@ public:
|
||||
GenericError = -1,
|
||||
PythonUncaughtException = 1,
|
||||
InvalidConfiguration = 2
|
||||
} ;
|
||||
};
|
||||
|
||||
JobResult( const JobResult& rhs ) = delete;
|
||||
JobResult( JobResult&& rhs );
|
||||
@ -102,6 +103,6 @@ private:
|
||||
using job_ptr = QSharedPointer< Job >;
|
||||
using JobList = QList< job_ptr >;
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_JOB_H
|
||||
#endif // CALAMARES_JOB_H
|
||||
|
@ -36,7 +36,8 @@ GoodJob::exec()
|
||||
JobResult
|
||||
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
|
||||
|
@ -21,7 +21,8 @@
|
||||
|
||||
#include "Job.h"
|
||||
|
||||
namespace Calamares {
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
/** @brief A Job with a name
|
||||
*
|
||||
@ -39,9 +40,10 @@ public:
|
||||
}
|
||||
|
||||
virtual QString prettyName() const override;
|
||||
|
||||
protected:
|
||||
const QString m_name;
|
||||
} ;
|
||||
};
|
||||
|
||||
/// @brief Job does nothing, always succeeds
|
||||
class DLLEXPORT GoodJob : public NamedJob
|
||||
@ -53,7 +55,7 @@ public:
|
||||
}
|
||||
|
||||
virtual JobResult exec() override;
|
||||
} ;
|
||||
};
|
||||
|
||||
|
||||
/// @brief Job does nothing, always fails
|
||||
@ -66,8 +68,8 @@ public:
|
||||
}
|
||||
|
||||
virtual JobResult exec() override;
|
||||
} ;
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_JOB_EXAMPLE_H
|
||||
#endif // CALAMARES_JOB_EXAMPLE_H
|
||||
|
@ -19,8 +19,8 @@
|
||||
|
||||
#include "JobQueue.h"
|
||||
|
||||
#include "Job.h"
|
||||
#include "GlobalStorage.h"
|
||||
#include "Job.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include "CalamaresConfig.h"
|
||||
@ -50,14 +50,14 @@ public:
|
||||
m_jobs = jobs;
|
||||
|
||||
qreal totalJobsWeight = 0.0;
|
||||
for( auto job : m_jobs )
|
||||
for ( auto job : m_jobs )
|
||||
{
|
||||
totalJobsWeight += job->getJobWeight();
|
||||
}
|
||||
for( auto job : m_jobs )
|
||||
for ( auto job : m_jobs )
|
||||
{
|
||||
qreal jobWeight = qreal( job->getJobWeight() / totalJobsWeight );
|
||||
m_jobWeights.append( jobWeight ) ;
|
||||
m_jobWeights.append( jobWeight );
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public:
|
||||
QString details;
|
||||
|
||||
m_jobIndex = 0;
|
||||
for( auto job : m_jobs )
|
||||
for ( auto job : m_jobs )
|
||||
{
|
||||
if ( anyFailed && !job->isEmergency() )
|
||||
{
|
||||
@ -87,12 +87,18 @@ public:
|
||||
details = result.details();
|
||||
}
|
||||
if ( !anyFailed )
|
||||
{
|
||||
++m_jobIndex;
|
||||
}
|
||||
}
|
||||
if ( anyFailed )
|
||||
{
|
||||
emitFailed( message, details );
|
||||
}
|
||||
else
|
||||
{
|
||||
emitProgress();
|
||||
}
|
||||
emitFinished();
|
||||
}
|
||||
|
||||
@ -109,49 +115,39 @@ private:
|
||||
jobPercent = qBound( qreal( 0 ), jobPercent, qreal( 1 ) );
|
||||
|
||||
int jobCount = m_jobs.size();
|
||||
QString message = m_jobIndex < jobCount
|
||||
? m_jobs.at( m_jobIndex )->prettyStatusMessage()
|
||||
: tr( "Done" );
|
||||
QString message = m_jobIndex < jobCount ? m_jobs.at( m_jobIndex )->prettyStatusMessage() : tr( "Done" );
|
||||
|
||||
qreal cumulativeProgress = 0.0;
|
||||
for( auto jobWeight : m_jobWeights.mid( 0, m_jobIndex ) )
|
||||
for ( auto jobWeight : m_jobWeights.mid( 0, m_jobIndex ) )
|
||||
{
|
||||
cumulativeProgress += jobWeight;
|
||||
}
|
||||
qreal percent = m_jobIndex < jobCount
|
||||
? cumulativeProgress + ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent )
|
||||
: 1.0;
|
||||
qreal percent
|
||||
= m_jobIndex < jobCount ? cumulativeProgress + ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent ) : 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 Overall: " << ( cumulativeProgress * 100 ) << "% (accumulated) + "
|
||||
<< ( ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent ) * 100 ) << "% (this job) = "
|
||||
<< ( percent * 100 ) << "% (total)";
|
||||
cDebug( Logger::LOGVERBOSE ) << "[JOBQUEUE]: Progress for Job[" << m_jobIndex
|
||||
<< "]: " << ( jobPercent * 100 ) << "% completed";
|
||||
cDebug( Logger::LOGVERBOSE ) << "[JOBQUEUE]: Progress Overall: " << ( cumulativeProgress * 100 )
|
||||
<< "% (accumulated) + "
|
||||
<< ( ( ( m_jobWeights.at( m_jobIndex ) ) * jobPercent ) * 100 )
|
||||
<< "% (this job) = " << ( percent * 100 ) << "% (total)";
|
||||
}
|
||||
QMetaObject::invokeMethod( m_queue, "progress", Qt::QueuedConnection,
|
||||
Q_ARG( qreal, percent ),
|
||||
Q_ARG( QString, message )
|
||||
);
|
||||
QMetaObject::invokeMethod(
|
||||
m_queue, "progress", Qt::QueuedConnection, Q_ARG( qreal, percent ), Q_ARG( QString, message ) );
|
||||
}
|
||||
|
||||
void emitFailed( const QString& message, const QString& details )
|
||||
{
|
||||
QMetaObject::invokeMethod( m_queue, "failed", Qt::QueuedConnection,
|
||||
Q_ARG( QString, message ),
|
||||
Q_ARG( QString, details )
|
||||
);
|
||||
QMetaObject::invokeMethod(
|
||||
m_queue, "failed", Qt::QueuedConnection, Q_ARG( QString, message ), Q_ARG( QString, details ) );
|
||||
}
|
||||
|
||||
void emitFinished()
|
||||
{
|
||||
QMetaObject::invokeMethod( m_queue, "finished", Qt::QueuedConnection );
|
||||
}
|
||||
void emitFinished() { QMetaObject::invokeMethod( m_queue, "finished", Qt::QueuedConnection ); }
|
||||
};
|
||||
|
||||
JobThread::~JobThread()
|
||||
{
|
||||
}
|
||||
JobThread::~JobThread() {}
|
||||
|
||||
|
||||
JobQueue* JobQueue::s_instance = nullptr;
|
||||
@ -186,8 +182,10 @@ JobQueue::~JobQueue()
|
||||
if ( m_thread->isRunning() )
|
||||
{
|
||||
m_thread->terminate();
|
||||
if ( !m_thread->wait(300) )
|
||||
if ( !m_thread->wait( 300 ) )
|
||||
{
|
||||
cError() << "Could not terminate job thread (expect a crash now).";
|
||||
}
|
||||
delete m_thread;
|
||||
}
|
||||
|
||||
@ -222,4 +220,4 @@ JobQueue::enqueue( const JobList& jobs )
|
||||
emit queueChanged( m_jobs );
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
@ -59,6 +59,6 @@ private:
|
||||
GlobalStorage* m_storage;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_JOBQUEUE_H
|
||||
#endif // CALAMARES_JOBQUEUE_H
|
||||
|
@ -22,11 +22,11 @@
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef PLUGINDLLEXPORT
|
||||
# if defined (PLUGINDLLEXPORT_PRO)
|
||||
# define PLUGINDLLEXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define PLUGINDLLEXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#if defined( PLUGINDLLEXPORT_PRO )
|
||||
#define PLUGINDLLEXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
#define PLUGINDLLEXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -25,7 +25,8 @@
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
|
||||
namespace Calamares {
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
|
||||
ProcessJob::ProcessJob( const QString& command,
|
||||
@ -38,27 +39,24 @@ ProcessJob::ProcessJob( const QString& command,
|
||||
, m_workingPath( workingPath )
|
||||
, m_runInChroot( runInChroot )
|
||||
, m_timeoutSec( secondsTimeout )
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ProcessJob::~ProcessJob()
|
||||
{}
|
||||
ProcessJob::~ProcessJob() {}
|
||||
|
||||
|
||||
QString
|
||||
ProcessJob::prettyName() const
|
||||
{
|
||||
return ( m_runInChroot ? tr( "Run command '%1' in target system." ) : tr( " Run command '%1'." ) )
|
||||
.arg( m_command );
|
||||
return ( m_runInChroot ? tr( "Run command '%1' in target system." ) : tr( " Run command '%1'." ) ).arg( m_command );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
ProcessJob::prettyStatusMessage() const
|
||||
{
|
||||
return tr( "Running command %1 %2" )
|
||||
.arg( m_command )
|
||||
.arg( m_runInChroot ? "in chroot." : " ." );
|
||||
return tr( "Running command %1 %2" ).arg( m_command ).arg( m_runInChroot ? "in chroot." : " ." );
|
||||
}
|
||||
|
||||
|
||||
@ -68,20 +66,16 @@ ProcessJob::exec()
|
||||
using CalamaresUtils::System;
|
||||
|
||||
if ( m_runInChroot )
|
||||
return CalamaresUtils::System::instance()->
|
||||
targetEnvCommand( { m_command },
|
||||
m_workingPath,
|
||||
QString(),
|
||||
m_timeoutSec )
|
||||
.explainProcess( m_command, m_timeoutSec );
|
||||
return CalamaresUtils::System::instance()
|
||||
->targetEnvCommand( { m_command }, m_workingPath, QString(), m_timeoutSec )
|
||||
.explainProcess( m_command, m_timeoutSec );
|
||||
else
|
||||
return
|
||||
System::runCommand( System::RunLocation::RunInHost,
|
||||
{ "/bin/sh", "-c", m_command },
|
||||
m_workingPath,
|
||||
QString(),
|
||||
m_timeoutSec )
|
||||
return System::runCommand( System::RunLocation::RunInHost,
|
||||
{ "/bin/sh", "-c", m_command },
|
||||
m_workingPath,
|
||||
QString(),
|
||||
m_timeoutSec )
|
||||
.explainProcess( m_command, m_timeoutSec );
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace Calamares {
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
class ProcessJob : public Job
|
||||
{
|
||||
@ -33,7 +34,7 @@ public:
|
||||
explicit ProcessJob( const QString& command,
|
||||
const QString& workingPath,
|
||||
bool runInChroot = false,
|
||||
std::chrono::seconds secondsTimeout = std::chrono::seconds(30),
|
||||
std::chrono::seconds secondsTimeout = std::chrono::seconds( 30 ),
|
||||
QObject* parent = nullptr );
|
||||
virtual ~ProcessJob() override;
|
||||
|
||||
@ -48,6 +49,6 @@ private:
|
||||
std::chrono::seconds m_timeoutSec;
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_PROCESSJOB_H
|
||||
#endif // CALAMARES_PROCESSJOB_H
|
||||
|
@ -72,25 +72,39 @@ variantFromPyObject( const boost::python::object& pyObject )
|
||||
{
|
||||
std::string pyType = bp::extract< std::string >( pyObject.attr( "__class__" ).attr( "__name__" ) );
|
||||
if ( pyType == "dict" )
|
||||
{
|
||||
return variantMapFromPyDict( bp::extract< bp::dict >( pyObject ) );
|
||||
}
|
||||
|
||||
else if ( pyType == "list" )
|
||||
{
|
||||
return variantListFromPyList( bp::extract< bp::list >( pyObject ) );
|
||||
}
|
||||
|
||||
else if ( pyType == "int" )
|
||||
{
|
||||
return QVariant( bp::extract< int >( pyObject ) );
|
||||
}
|
||||
|
||||
else if ( pyType == "float" )
|
||||
{
|
||||
return QVariant( bp::extract< double >( pyObject ) );
|
||||
}
|
||||
|
||||
else if ( pyType == "str" )
|
||||
{
|
||||
return QVariant( QString::fromStdString( bp::extract< std::string >( pyObject ) ) );
|
||||
}
|
||||
|
||||
else if ( pyType == "bool" )
|
||||
{
|
||||
return QVariant( bp::extract< bool >( pyObject ) );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -99,7 +113,9 @@ variantListToPyList( const QVariantList& variantList )
|
||||
{
|
||||
bp::list pyList;
|
||||
for ( const QVariant& variant : variantList )
|
||||
{
|
||||
pyList.append( variantToPyObject( variant ) );
|
||||
}
|
||||
return pyList;
|
||||
}
|
||||
|
||||
@ -109,7 +125,9 @@ variantListFromPyList( const boost::python::list& pyList )
|
||||
{
|
||||
QVariantList list;
|
||||
for ( int i = 0; i < bp::len( pyList ); ++i )
|
||||
{
|
||||
list.append( variantFromPyObject( pyList[ i ] ) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -119,7 +137,9 @@ variantMapToPyDict( const QVariantMap& variantMap )
|
||||
{
|
||||
bp::dict pyDict;
|
||||
for ( auto it = variantMap.constBegin(); it != variantMap.constEnd(); ++it )
|
||||
{
|
||||
pyDict[ it.key().toStdString() ] = variantToPyObject( it.value() );
|
||||
}
|
||||
return pyDict;
|
||||
}
|
||||
|
||||
@ -152,7 +172,9 @@ variantHashToPyDict( const QVariantHash& variantHash )
|
||||
{
|
||||
bp::dict pyDict;
|
||||
for ( auto it = variantHash.constBegin(); it != variantHash.constEnd(); ++it )
|
||||
{
|
||||
pyDict[ it.key().toStdString() ] = variantToPyObject( it.value() );
|
||||
}
|
||||
return pyDict;
|
||||
}
|
||||
|
||||
@ -181,17 +203,21 @@ variantHashFromPyDict( const boost::python::dict& pyDict )
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
QFileInfo fi( dir.absoluteFilePath( name ) );
|
||||
if ( fi.exists() && fi.isReadable() )
|
||||
{
|
||||
list.append( fi.dir().absolutePath() );
|
||||
}
|
||||
}
|
||||
|
||||
Helper::Helper( QObject* parent )
|
||||
@ -201,7 +227,9 @@ Helper::Helper( QObject* parent )
|
||||
if ( !s_instance )
|
||||
{
|
||||
if ( !Py_IsInitialized() )
|
||||
{
|
||||
Py_Initialize();
|
||||
}
|
||||
|
||||
m_mainModule = bp::import( "__main__" );
|
||||
m_mainNamespace = m_mainModule.attr( "__dict__" );
|
||||
@ -209,8 +237,7 @@ Helper::Helper( QObject* parent )
|
||||
// If we're running from the build dir
|
||||
add_if_lib_exists( QDir::current(), "libcalamares.so", m_pythonPaths );
|
||||
|
||||
QDir calaPythonPath( CalamaresUtils::systemLibDir().absolutePath() +
|
||||
QDir::separator() + "calamares" );
|
||||
QDir calaPythonPath( CalamaresUtils::systemLibDir().absolutePath() + QDir::separator() + "calamares" );
|
||||
add_if_lib_exists( calaPythonPath, "libcalamares.so", m_pythonPaths );
|
||||
|
||||
bp::object sys = bp::import( "sys" );
|
||||
@ -251,7 +278,7 @@ Helper::createCleanNamespace()
|
||||
QString
|
||||
Helper::handleLastError()
|
||||
{
|
||||
PyObject* type = nullptr, *val = nullptr, *traceback_p = nullptr;
|
||||
PyObject *type = nullptr, *val = nullptr, *traceback_p = nullptr;
|
||||
PyErr_Fetch( &type, &val, &traceback_p );
|
||||
|
||||
Logger::CDebug debug;
|
||||
@ -264,10 +291,14 @@ Helper::handleLastError()
|
||||
bp::str pystr( h_type );
|
||||
bp::extract< std::string > extracted( pystr );
|
||||
if ( extracted.check() )
|
||||
{
|
||||
typeMsg = QString::fromStdString( extracted() ).trimmed();
|
||||
}
|
||||
|
||||
if ( typeMsg.isEmpty() )
|
||||
{
|
||||
typeMsg = tr( "Unknown exception type" );
|
||||
}
|
||||
debug << typeMsg << '\n';
|
||||
}
|
||||
|
||||
@ -278,10 +309,14 @@ Helper::handleLastError()
|
||||
bp::str pystr( h_val );
|
||||
bp::extract< std::string > extracted( pystr );
|
||||
if ( extracted.check() )
|
||||
{
|
||||
valMsg = QString::fromStdString( extracted() ).trimmed();
|
||||
}
|
||||
|
||||
if ( valMsg.isEmpty() )
|
||||
{
|
||||
valMsg = tr( "unparseable Python error" );
|
||||
}
|
||||
|
||||
// Special-case: CalledProcessError has an attribute "output" with the command output,
|
||||
// add that to the printed message.
|
||||
@ -318,22 +353,32 @@ Helper::handleLastError()
|
||||
bp::object pystr( bp::str( "\n" ).join( tb_list ) );
|
||||
bp::extract< std::string > extracted( pystr );
|
||||
if ( extracted.check() )
|
||||
{
|
||||
tbMsg = QString::fromStdString( extracted() ).trimmed();
|
||||
}
|
||||
|
||||
if ( tbMsg.isEmpty() )
|
||||
{
|
||||
tbMsg = tr( "unparseable Python traceback" );
|
||||
}
|
||||
debug << tbMsg << '\n';
|
||||
}
|
||||
|
||||
if ( typeMsg.isEmpty() && valMsg.isEmpty() && tbMsg.isEmpty() )
|
||||
{
|
||||
return tr( "Unfetchable Python error." );
|
||||
}
|
||||
|
||||
|
||||
QStringList msgList;
|
||||
if ( !typeMsg.isEmpty() )
|
||||
{
|
||||
msgList.append( QString( "<strong>%1</strong>" ).arg( typeMsg.toHtmlEscaped() ) );
|
||||
}
|
||||
if ( !valMsg.isEmpty() )
|
||||
{
|
||||
msgList.append( valMsg.toHtmlEscaped() );
|
||||
}
|
||||
|
||||
if ( !tbMsg.isEmpty() )
|
||||
{
|
||||
@ -346,4 +391,4 @@ Helper::handleLastError()
|
||||
}
|
||||
|
||||
|
||||
} // namespace CalamaresPython
|
||||
} // namespace CalamaresPython
|
||||
|
@ -32,17 +32,17 @@
|
||||
namespace CalamaresPython
|
||||
{
|
||||
|
||||
boost::python::object variantToPyObject( const QVariant& variant );
|
||||
QVariant variantFromPyObject( const boost::python::object& pyObject );
|
||||
boost::python::object variantToPyObject( const QVariant& variant );
|
||||
QVariant variantFromPyObject( const boost::python::object& pyObject );
|
||||
|
||||
boost::python::list variantListToPyList( const QVariantList& variantList );
|
||||
QVariantList variantListFromPyList( const boost::python::list& pyList );
|
||||
boost::python::list variantListToPyList( const QVariantList& variantList );
|
||||
QVariantList variantListFromPyList( const boost::python::list& pyList );
|
||||
|
||||
boost::python::dict variantMapToPyDict( const QVariantMap& variantMap );
|
||||
QVariantMap variantMapFromPyDict( const boost::python::dict& pyDict );
|
||||
boost::python::dict variantMapToPyDict( const QVariantMap& variantMap );
|
||||
QVariantMap variantMapFromPyDict( const boost::python::dict& pyDict );
|
||||
|
||||
boost::python::dict variantHashToPyDict( const QVariantHash& variantHash );
|
||||
QVariantHash variantHashFromPyDict( const boost::python::dict& pyDict );
|
||||
boost::python::dict variantHashToPyDict( const QVariantHash& variantHash );
|
||||
QVariantHash variantHashFromPyDict( const boost::python::dict& pyDict );
|
||||
|
||||
|
||||
class Helper : public QObject
|
||||
@ -66,6 +66,6 @@ private:
|
||||
QStringList m_pythonPaths;
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace CalamaresPython
|
||||
|
||||
#endif // CALAMARES_PYTHONJOBHELPER_H
|
||||
#endif // CALAMARES_PYTHONJOBHELPER_H
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
#include "PythonJob.h"
|
||||
|
||||
#include "PythonHelper.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "PythonHelper.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
@ -35,27 +35,19 @@
|
||||
|
||||
namespace bp = boost::python;
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( mount_overloads,
|
||||
CalamaresPython::mount,
|
||||
2, 4 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_str_overloads,
|
||||
CalamaresPython::target_env_call,
|
||||
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( mount_overloads, CalamaresPython::mount, 2, 4 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_str_overloads, CalamaresPython::target_env_call, 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,
|
||||
CalamaresPython::check_target_env_output,
|
||||
1, 3 );
|
||||
1,
|
||||
3 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( check_target_env_output_list_overloads,
|
||||
CalamaresPython::check_target_env_output,
|
||||
1, 3 );
|
||||
1,
|
||||
3 );
|
||||
BOOST_PYTHON_MODULE( libcalamares )
|
||||
{
|
||||
bp::object package = bp::scope();
|
||||
@ -68,25 +60,24 @@ BOOST_PYTHON_MODULE( libcalamares )
|
||||
bp::scope().attr( "VERSION_SHORT" ) = CALAMARES_VERSION_SHORT;
|
||||
|
||||
bp::class_< CalamaresPython::PythonJobInterface >( "Job", bp::init< Calamares::PythonJob* >() )
|
||||
.def_readonly( "module_name", &CalamaresPython::PythonJobInterface::moduleName )
|
||||
.def_readonly( "pretty_name", &CalamaresPython::PythonJobInterface::prettyName )
|
||||
.def_readonly( "working_path", &CalamaresPython::PythonJobInterface::workingPath )
|
||||
.def_readonly( "module_name", &CalamaresPython::PythonJobInterface::moduleName )
|
||||
.def_readonly( "pretty_name", &CalamaresPython::PythonJobInterface::prettyName )
|
||||
.def_readonly( "working_path", &CalamaresPython::PythonJobInterface::workingPath )
|
||||
.def_readonly( "configuration", &CalamaresPython::PythonJobInterface::configuration )
|
||||
.def(
|
||||
"setprogress",
|
||||
&CalamaresPython::PythonJobInterface::setprogress,
|
||||
bp::args( "progress" ),
|
||||
"Reports the progress status of this job to Calamares, "
|
||||
"as a real number between 0 and 1."
|
||||
);
|
||||
.def( "setprogress",
|
||||
&CalamaresPython::PythonJobInterface::setprogress,
|
||||
bp::args( "progress" ),
|
||||
"Reports the progress status of this job to Calamares, "
|
||||
"as a real number between 0 and 1." );
|
||||
|
||||
bp::class_< CalamaresPython::GlobalStoragePythonWrapper >( "GlobalStorage", bp::init< Calamares::GlobalStorage* >() )
|
||||
.def( "contains", &CalamaresPython::GlobalStoragePythonWrapper::contains )
|
||||
.def( "count", &CalamaresPython::GlobalStoragePythonWrapper::count )
|
||||
.def( "insert", &CalamaresPython::GlobalStoragePythonWrapper::insert )
|
||||
.def( "keys", &CalamaresPython::GlobalStoragePythonWrapper::keys )
|
||||
.def( "remove", &CalamaresPython::GlobalStoragePythonWrapper::remove )
|
||||
.def( "value", &CalamaresPython::GlobalStoragePythonWrapper::value );
|
||||
bp::class_< CalamaresPython::GlobalStoragePythonWrapper >( "GlobalStorage",
|
||||
bp::init< Calamares::GlobalStorage* >() )
|
||||
.def( "contains", &CalamaresPython::GlobalStoragePythonWrapper::contains )
|
||||
.def( "count", &CalamaresPython::GlobalStoragePythonWrapper::count )
|
||||
.def( "insert", &CalamaresPython::GlobalStoragePythonWrapper::insert )
|
||||
.def( "keys", &CalamaresPython::GlobalStoragePythonWrapper::keys )
|
||||
.def( "remove", &CalamaresPython::GlobalStoragePythonWrapper::remove )
|
||||
.def( "value", &CalamaresPython::GlobalStoragePythonWrapper::value );
|
||||
|
||||
// libcalamares.utils submodule starts here
|
||||
bp::object utilsModule( bp::handle<>( bp::borrowed( PyImport_AddModule( "libcalamares.utils" ) ) ) );
|
||||
@ -95,151 +86,88 @@ BOOST_PYTHON_MODULE( libcalamares )
|
||||
Q_UNUSED( utilsScope )
|
||||
|
||||
bp::def(
|
||||
"debug",
|
||||
&CalamaresPython::debug,
|
||||
bp::args( "s" ),
|
||||
"Writes the given string to the Calamares debug stream."
|
||||
);
|
||||
bp::def(
|
||||
"warning",
|
||||
&CalamaresPython::warning,
|
||||
bp::args( "s" ),
|
||||
"Writes the given string to the Calamares warning stream."
|
||||
);
|
||||
"debug", &CalamaresPython::debug, bp::args( "s" ), "Writes the given string to the Calamares debug stream." );
|
||||
bp::def( "warning",
|
||||
&CalamaresPython::warning,
|
||||
bp::args( "s" ),
|
||||
"Writes the given string to the Calamares warning stream." );
|
||||
|
||||
bp::def(
|
||||
"mount",
|
||||
&CalamaresPython::mount,
|
||||
mount_overloads(
|
||||
bp::args( "device_path",
|
||||
"mount_point",
|
||||
"filesystem_name",
|
||||
"options" ),
|
||||
"Runs the mount utility with the specified parameters.\n"
|
||||
"Returns the program's exit code, or:\n"
|
||||
"-1 = QProcess crash\n"
|
||||
"-2 = QProcess cannot start\n"
|
||||
"-3 = bad arguments"
|
||||
)
|
||||
);
|
||||
bp::def( "mount",
|
||||
&CalamaresPython::mount,
|
||||
mount_overloads( bp::args( "device_path", "mount_point", "filesystem_name", "options" ),
|
||||
"Runs the mount utility with the specified parameters.\n"
|
||||
"Returns the program's exit code, or:\n"
|
||||
"-1 = QProcess crash\n"
|
||||
"-2 = QProcess cannot start\n"
|
||||
"-3 = bad arguments" ) );
|
||||
bp::def(
|
||||
"target_env_call",
|
||||
static_cast< int (*)( const std::string&,
|
||||
const std::string&,
|
||||
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"
|
||||
"Returns the program's exit code, or:\n"
|
||||
"-1 = QProcess crash\n"
|
||||
"-2 = QProcess cannot start\n"
|
||||
"-3 = bad arguments\n"
|
||||
"-4 = QProcess timeout"
|
||||
)
|
||||
);
|
||||
bp::def(
|
||||
"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"
|
||||
"Returns the program's exit code, or:\n"
|
||||
"-1 = QProcess crash\n"
|
||||
"-2 = QProcess cannot start\n"
|
||||
"-3 = bad arguments\n"
|
||||
"-4 = QProcess timeout"
|
||||
)
|
||||
);
|
||||
static_cast< int ( * )( const std::string&, const std::string&, 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"
|
||||
"Returns the program's exit code, or:\n"
|
||||
"-1 = QProcess crash\n"
|
||||
"-2 = QProcess cannot start\n"
|
||||
"-3 = bad arguments\n"
|
||||
"-4 = QProcess timeout" ) );
|
||||
bp::def( "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"
|
||||
"Returns the program's exit code, or:\n"
|
||||
"-1 = QProcess crash\n"
|
||||
"-2 = QProcess cannot start\n"
|
||||
"-3 = bad arguments\n"
|
||||
"-4 = QProcess timeout" ) );
|
||||
|
||||
bp::def( "check_target_env_call",
|
||||
static_cast< int ( * )( const std::string&, const std::string&, 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"
|
||||
"Returns 0, which is program's exit code if the program exited "
|
||||
"successfully, or raises a subprocess.CalledProcessError." ) );
|
||||
bp::def(
|
||||
"check_target_env_call",
|
||||
static_cast< int (*)( const std::string&,
|
||||
const std::string&,
|
||||
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"
|
||||
"Returns 0, which is program's exit code if the program exited "
|
||||
"successfully, or raises a subprocess.CalledProcessError."
|
||||
)
|
||||
);
|
||||
bp::def(
|
||||
"check_target_env_call",
|
||||
static_cast< int (*)( const bp::list&,
|
||||
const std::string&,
|
||||
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"
|
||||
"Returns 0, which is program's exit code if the program exited "
|
||||
"successfully, or raises a subprocess.CalledProcessError."
|
||||
)
|
||||
);
|
||||
static_cast< int ( * )( const bp::list&, const std::string&, 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"
|
||||
"Returns 0, which is program's exit code if the program exited "
|
||||
"successfully, or raises a subprocess.CalledProcessError." ) );
|
||||
|
||||
bp::def(
|
||||
"check_target_env_output",
|
||||
static_cast< std::string (*)( const std::string&,
|
||||
const std::string&,
|
||||
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"
|
||||
"Returns the program's standard output, and raises a "
|
||||
"subprocess.CalledProcessError if something went wrong."
|
||||
)
|
||||
);
|
||||
bp::def(
|
||||
"check_target_env_output",
|
||||
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"
|
||||
"Returns the program's standard output, and raises a "
|
||||
"subprocess.CalledProcessError if something went wrong."
|
||||
)
|
||||
);
|
||||
bp::def(
|
||||
"obscure",
|
||||
&CalamaresPython::obscure,
|
||||
bp::args( "s" ),
|
||||
"Simple string obfuscation function based on KStringHandler::obscure.\n"
|
||||
"Returns a string, generated using a simple symmetric encryption.\n"
|
||||
"Applying the function to a string obscured by this function will result "
|
||||
"in the original string."
|
||||
);
|
||||
bp::def( "check_target_env_output",
|
||||
static_cast< std::string ( * )( const std::string&, const std::string&, 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"
|
||||
"Returns the program's standard output, and raises a "
|
||||
"subprocess.CalledProcessError if something went wrong." ) );
|
||||
bp::def( "check_target_env_output",
|
||||
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"
|
||||
"Returns the program's standard output, and raises a "
|
||||
"subprocess.CalledProcessError if something went wrong." ) );
|
||||
bp::def( "obscure",
|
||||
&CalamaresPython::obscure,
|
||||
bp::args( "s" ),
|
||||
"Simple string obfuscation function based on KStringHandler::obscure.\n"
|
||||
"Returns a string, generated using a simple symmetric encryption.\n"
|
||||
"Applying the function to a string obscured by this function will result "
|
||||
"in the original string." );
|
||||
|
||||
|
||||
bp::def(
|
||||
"gettext_languages",
|
||||
&CalamaresPython::gettext_languages,
|
||||
"Returns list of languages (most to least-specific) for gettext."
|
||||
);
|
||||
bp::def( "gettext_languages",
|
||||
&CalamaresPython::gettext_languages,
|
||||
"Returns list of languages (most to least-specific) for gettext." );
|
||||
|
||||
bp::def(
|
||||
"gettext_path",
|
||||
&CalamaresPython::gettext_path,
|
||||
"Returns path for gettext search."
|
||||
);
|
||||
bp::def( "gettext_path", &CalamaresPython::gettext_path, "Returns path for gettext search." );
|
||||
}
|
||||
|
||||
|
||||
namespace Calamares {
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
|
||||
PythonJob::PythonJob( const QString& scriptFile,
|
||||
@ -255,8 +183,7 @@ PythonJob::PythonJob( const QString& scriptFile,
|
||||
}
|
||||
|
||||
|
||||
PythonJob::~PythonJob()
|
||||
{}
|
||||
PythonJob::~PythonJob() {}
|
||||
|
||||
|
||||
QString
|
||||
@ -270,10 +197,13 @@ QString
|
||||
PythonJob::prettyStatusMessage() const
|
||||
{
|
||||
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
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -282,24 +212,20 @@ PythonJob::exec()
|
||||
{
|
||||
// We assume m_scriptFile to be relative to m_workingPath.
|
||||
QDir workingDir( m_workingPath );
|
||||
if ( !workingDir.exists() ||
|
||||
!workingDir.isReadable() )
|
||||
if ( !workingDir.exists() || !workingDir.isReadable() )
|
||||
{
|
||||
return JobResult::error( tr( "Bad working directory path" ),
|
||||
tr( "Working directory %1 for python job %2 is not readable." )
|
||||
.arg( m_workingPath )
|
||||
.arg( prettyName() ) );
|
||||
return JobResult::error(
|
||||
tr( "Bad working directory path" ),
|
||||
tr( "Working directory %1 for python job %2 is not readable." ).arg( m_workingPath ).arg( prettyName() ) );
|
||||
}
|
||||
|
||||
QFileInfo scriptFI( workingDir.absoluteFilePath( m_scriptFile ) );
|
||||
if ( !scriptFI.exists() ||
|
||||
!scriptFI.isFile() ||
|
||||
!scriptFI.isReadable() )
|
||||
if ( !scriptFI.exists() || !scriptFI.isFile() || !scriptFI.isReadable() )
|
||||
{
|
||||
return JobResult::error( tr( "Bad main script file" ),
|
||||
tr( "Main script file %1 for python job %2 is not readable." )
|
||||
.arg( scriptFI.absoluteFilePath() )
|
||||
.arg( prettyName() ) );
|
||||
.arg( scriptFI.absoluteFilePath() )
|
||||
.arg( prettyName() ) );
|
||||
}
|
||||
|
||||
try
|
||||
@ -310,15 +236,14 @@ PythonJob::exec()
|
||||
bp::dict calamaresNamespace = bp::extract< bp::dict >( calamaresModule.attr( "__dict__" ) );
|
||||
|
||||
calamaresNamespace[ "job" ] = CalamaresPython::PythonJobInterface( this );
|
||||
calamaresNamespace[ "globalstorage" ] = CalamaresPython::GlobalStoragePythonWrapper(
|
||||
JobQueue::instance()->globalStorage() );
|
||||
calamaresNamespace[ "globalstorage" ]
|
||||
= CalamaresPython::GlobalStoragePythonWrapper( JobQueue::instance()->globalStorage() );
|
||||
|
||||
bp::object execResult = bp::exec_file( scriptFI.absoluteFilePath().toLocal8Bit().data(),
|
||||
scriptNamespace,
|
||||
scriptNamespace );
|
||||
bp::object execResult
|
||||
= bp::exec_file( scriptFI.absoluteFilePath().toLocal8Bit().data(), scriptNamespace, scriptNamespace );
|
||||
|
||||
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();
|
||||
if ( !prettyNameFunc.is_none() )
|
||||
@ -337,14 +262,16 @@ PythonJob::exec()
|
||||
|
||||
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() )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
m_description.truncate( i_newline );
|
||||
}
|
||||
cDebug() << "Job description from __doc__" << prettyName() << "=" << m_description;
|
||||
emit progress( 0 );
|
||||
}
|
||||
@ -356,7 +283,7 @@ PythonJob::exec()
|
||||
{
|
||||
return JobResult::ok();
|
||||
}
|
||||
else // Something happened in the Python job
|
||||
else // Something happened in the Python job
|
||||
{
|
||||
bp::tuple resultTuple = bp::extract< bp::tuple >( runResult );
|
||||
QString message = QString::fromStdString( bp::extract< std::string >( resultTuple[ 0 ] ) );
|
||||
@ -374,9 +301,7 @@ PythonJob::exec()
|
||||
bp::handle_exception();
|
||||
PyErr_Clear();
|
||||
return JobResult::internalError(
|
||||
tr( "Boost.Python error in job \"%1\"." ).arg( prettyName() ),
|
||||
msg,
|
||||
JobResult::PythonUncaughtException );
|
||||
tr( "Boost.Python error in job \"%1\"." ).arg( prettyName() ), msg, JobResult::PythonUncaughtException );
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,10 +317,12 @@ CalamaresPython::Helper*
|
||||
PythonJob::helper()
|
||||
{
|
||||
auto ptr = CalamaresPython::Helper::s_instance;
|
||||
if (!ptr)
|
||||
if ( !ptr )
|
||||
{
|
||||
ptr = new CalamaresPython::Helper;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
@ -27,9 +27,10 @@ namespace CalamaresPython
|
||||
{
|
||||
class PythonJobInterface;
|
||||
class Helper;
|
||||
}
|
||||
} // namespace CalamaresPython
|
||||
|
||||
namespace Calamares {
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
class PythonJob : public Job
|
||||
{
|
||||
@ -57,6 +58,6 @@ private:
|
||||
QVariantMap m_configurationMap;
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // CALAMARES_PYTHONJOB_H
|
||||
#endif // CALAMARES_PYTHONJOB_H
|
||||
|
@ -20,8 +20,8 @@
|
||||
#include "PythonJobApi.h"
|
||||
|
||||
#include "PythonHelper.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/String.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
@ -40,15 +40,19 @@ static int
|
||||
_handle_check_target_env_call_error( const CalamaresUtils::ProcessResult& ec, const QString& cmd )
|
||||
{
|
||||
if ( !ec.first )
|
||||
{
|
||||
return ec.first;
|
||||
}
|
||||
|
||||
QString raise = QString( "import subprocess\n"
|
||||
"e = subprocess.CalledProcessError(%1,\"%2\")\n" )
|
||||
.arg( ec.first )
|
||||
.arg( cmd );
|
||||
.arg( ec.first )
|
||||
.arg( cmd );
|
||||
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::throw_error_already_set();
|
||||
return ec.first;
|
||||
@ -63,11 +67,10 @@ mount( const std::string& device_path,
|
||||
const std::string& filesystem_name,
|
||||
const std::string& options )
|
||||
{
|
||||
return CalamaresUtils::System::instance()->
|
||||
mount( QString::fromStdString( device_path ),
|
||||
QString::fromStdString( mount_point ),
|
||||
QString::fromStdString( filesystem_name ),
|
||||
QString::fromStdString( options ) );
|
||||
return CalamaresUtils::System::instance()->mount( QString::fromStdString( device_path ),
|
||||
QString::fromStdString( mount_point ),
|
||||
QString::fromStdString( filesystem_name ),
|
||||
QString::fromStdString( options ) );
|
||||
}
|
||||
|
||||
|
||||
@ -77,66 +80,50 @@ _bp_list_to_qstringlist( const bp::list& args )
|
||||
QStringList list;
|
||||
for ( int i = 0; i < bp::len( args ); ++i )
|
||||
{
|
||||
list.append( QString::fromStdString(
|
||||
bp::extract< std::string >( args[ i ] ) ) );
|
||||
list.append( QString::fromStdString( bp::extract< std::string >( args[ i ] ) ) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static inline CalamaresUtils::ProcessResult
|
||||
_target_env_command(
|
||||
const QStringList& args,
|
||||
const std::string& stdin,
|
||||
int timeout )
|
||||
_target_env_command( const QStringList& args, const std::string& stdin, int timeout )
|
||||
{
|
||||
// Since Python doesn't give us the type system for distinguishing
|
||||
// seconds from other integral types, massage to seconds here.
|
||||
return CalamaresUtils::System::instance()->
|
||||
targetEnvCommand( args,
|
||||
QString(),
|
||||
QString::fromStdString( stdin ),
|
||||
std::chrono::seconds( timeout ) );
|
||||
return CalamaresUtils::System::instance()->targetEnvCommand(
|
||||
args, QString(), QString::fromStdString( stdin ), std::chrono::seconds( timeout ) );
|
||||
}
|
||||
|
||||
int
|
||||
target_env_call( const std::string& command,
|
||||
const std::string& stdin,
|
||||
int timeout )
|
||||
target_env_call( const std::string& command, const std::string& stdin, int timeout )
|
||||
{
|
||||
return _target_env_command(
|
||||
QStringList{ QString::fromStdString( command ) }, stdin, timeout ).first;
|
||||
return _target_env_command( QStringList { QString::fromStdString( command ) }, stdin, timeout ).first;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
target_env_call( const bp::list& args,
|
||||
const std::string& stdin,
|
||||
int timeout )
|
||||
target_env_call( const bp::list& args, const std::string& stdin, int timeout )
|
||||
{
|
||||
return _target_env_command(
|
||||
_bp_list_to_qstringlist( args ), stdin, timeout ).first;
|
||||
return _target_env_command( _bp_list_to_qstringlist( args ), stdin, timeout ).first;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
check_target_env_call( const std::string& command,
|
||||
const std::string& stdin,
|
||||
int timeout )
|
||||
check_target_env_call( const std::string& command, const std::string& stdin, int timeout )
|
||||
{
|
||||
auto ec = _target_env_command(
|
||||
QStringList{ QString::fromStdString( command ) }, stdin, timeout );
|
||||
auto ec = _target_env_command( QStringList { QString::fromStdString( command ) }, stdin, timeout );
|
||||
return _handle_check_target_env_call_error( ec, QString::fromStdString( command ) );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
check_target_env_call( const bp::list& args,
|
||||
const std::string& stdin,
|
||||
int timeout )
|
||||
check_target_env_call( const bp::list& args, const std::string& stdin, int timeout )
|
||||
{
|
||||
auto ec = _target_env_command( _bp_list_to_qstringlist( args ), stdin, timeout );
|
||||
if ( !ec.first )
|
||||
{
|
||||
return ec.first;
|
||||
}
|
||||
|
||||
QStringList failedCmdList = _bp_list_to_qstringlist( args );
|
||||
return _handle_check_target_env_call_error( ec, failedCmdList.join( ' ' ) );
|
||||
@ -144,25 +131,19 @@ check_target_env_call( const bp::list& args,
|
||||
|
||||
|
||||
std::string
|
||||
check_target_env_output( const std::string& command,
|
||||
const std::string& stdin,
|
||||
int timeout )
|
||||
check_target_env_output( const std::string& command, const std::string& stdin, int timeout )
|
||||
{
|
||||
auto ec = _target_env_command(
|
||||
QStringList{ QString::fromStdString( command ) }, stdin, timeout );
|
||||
auto ec = _target_env_command( QStringList { QString::fromStdString( command ) }, stdin, timeout );
|
||||
_handle_check_target_env_call_error( ec, QString::fromStdString( command ) );
|
||||
return ec.second.toStdString();
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
check_target_env_output( const bp::list& args,
|
||||
const std::string& stdin,
|
||||
int timeout )
|
||||
check_target_env_output( const bp::list& args, const std::string& stdin, int timeout )
|
||||
{
|
||||
QStringList list = _bp_list_to_qstringlist( args );
|
||||
auto ec = _target_env_command(
|
||||
list, stdin, timeout );
|
||||
auto ec = _target_env_command( list, stdin, timeout );
|
||||
_handle_check_target_env_call_error( ec, list.join( ' ' ) );
|
||||
return ec.second.toStdString();
|
||||
}
|
||||
@ -194,7 +175,9 @@ void
|
||||
PythonJobInterface::setprogress( qreal progress )
|
||||
{
|
||||
if ( progress >= 0 && progress <= 1 )
|
||||
{
|
||||
m_parent->emitProgress( progress );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -216,7 +199,8 @@ _gettext_languages()
|
||||
// own GlobalStoragePythonWrapper, which then holds a
|
||||
// GlobalStorage object for all of Python.
|
||||
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" );
|
||||
if ( localeConf_.canConvert< QVariantMap >() )
|
||||
@ -246,7 +230,9 @@ gettext_languages()
|
||||
{
|
||||
bp::list pyList;
|
||||
for ( auto lang : _gettext_languages() )
|
||||
{
|
||||
pyList.append( lang.toStdString() );
|
||||
}
|
||||
return pyList;
|
||||
}
|
||||
|
||||
@ -257,7 +243,9 @@ _add_localedirs( QStringList& pathList, const QString& candidate )
|
||||
{
|
||||
pathList.prepend( candidate );
|
||||
if ( QDir( candidate ).cd( "lang" ) )
|
||||
{
|
||||
pathList.prepend( candidate + "/lang" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,16 +254,19 @@ gettext_path()
|
||||
{
|
||||
// TODO: distinguish between -d runs and normal runs
|
||||
// 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();
|
||||
_add_localedirs( candidatePaths, extra ); // Often /usr/local/bin
|
||||
_add_localedirs( candidatePaths, extra ); // Often /usr/local/bin
|
||||
if ( !extra.isEmpty() )
|
||||
{
|
||||
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, QDir().canonicalPath() ); // .
|
||||
_add_localedirs( candidatePaths, QDir().canonicalPath() ); // .
|
||||
|
||||
cDebug() << "Determining gettext path from" << candidatePaths;
|
||||
|
||||
@ -296,4 +287,4 @@ gettext_path()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} // namespace CalamaresPython
|
||||
|
@ -35,29 +35,19 @@ int mount( const std::string& device_path,
|
||||
const std::string& filesystem_name = std::string(),
|
||||
const std::string& options = std::string() );
|
||||
|
||||
int target_env_call( const std::string& command,
|
||||
const std::string& stdin = std::string(),
|
||||
int timeout = 0 );
|
||||
int target_env_call( const std::string& command, const std::string& stdin = std::string(), int timeout = 0 );
|
||||
|
||||
int target_env_call( const boost::python::list& args,
|
||||
const std::string& stdin = std::string(),
|
||||
int timeout = 0 );
|
||||
int target_env_call( const boost::python::list& args, const std::string& stdin = std::string(), int timeout = 0 );
|
||||
|
||||
int check_target_env_call( const std::string& command,
|
||||
const std::string& stdin = std::string(),
|
||||
int timeout = 0 );
|
||||
int check_target_env_call( const std::string& command, const std::string& stdin = std::string(), int timeout = 0 );
|
||||
|
||||
int check_target_env_call( const boost::python::list& args,
|
||||
const std::string& stdin = std::string(),
|
||||
int timeout = 0 );
|
||||
int check_target_env_call( const boost::python::list& args, const std::string& stdin = std::string(), int timeout = 0 );
|
||||
|
||||
std::string check_target_env_output( const std::string& command,
|
||||
const std::string& stdin = std::string(),
|
||||
int timeout = 0 );
|
||||
std::string
|
||||
check_target_env_output( const std::string& command, const std::string& stdin = std::string(), int timeout = 0 );
|
||||
|
||||
std::string check_target_env_output( const boost::python::list& args,
|
||||
const std::string& stdin = std::string(),
|
||||
int timeout = 0 );
|
||||
std::string
|
||||
check_target_env_output( const boost::python::list& args, const std::string& stdin = std::string(), int timeout = 0 );
|
||||
|
||||
std::string obscure( const std::string& string );
|
||||
|
||||
@ -85,6 +75,6 @@ private:
|
||||
Calamares::PythonJob* m_parent;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace CalamaresPython
|
||||
|
||||
#endif // PYTHONJOBAPI_H
|
||||
#endif // PYTHONJOBAPI_H
|
||||
|
@ -40,8 +40,10 @@ static QString
|
||||
requireString( const YAML::Node& config, const char* key )
|
||||
{
|
||||
auto v = config[ key ];
|
||||
if ( hasValue(v) )
|
||||
if ( hasValue( v ) )
|
||||
{
|
||||
return QString::fromStdString( v.as< std::string >() );
|
||||
}
|
||||
else
|
||||
{
|
||||
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 )
|
||||
{
|
||||
auto v = config[ key ];
|
||||
if ( hasValue(v) )
|
||||
if ( hasValue( v ) )
|
||||
{
|
||||
return v.as< bool >();
|
||||
}
|
||||
else
|
||||
{
|
||||
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.
|
||||
if ( debugMode )
|
||||
{
|
||||
QString buildDirModules = QDir::current().absolutePath() +
|
||||
QDir::separator() + "src" +
|
||||
QDir::separator() + "modules";
|
||||
QString buildDirModules
|
||||
= QDir::current().absolutePath() + QDir::separator() + "src" + QDir::separator() + "modules";
|
||||
if ( QDir( buildDirModules ).exists() )
|
||||
{
|
||||
output.append( buildDirModules );
|
||||
}
|
||||
}
|
||||
|
||||
// Install path is set in CalamaresAddPlugin.cmake
|
||||
output.append( CalamaresUtils::systemLibDir().absolutePath() +
|
||||
QDir::separator() + "calamares" +
|
||||
QDir::separator() + "modules" );
|
||||
output.append( CalamaresUtils::systemLibDir().absolutePath() + QDir::separator() + "calamares"
|
||||
+ QDir::separator() + "modules" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -106,7 +110,9 @@ interpretModulesSearch( const bool debugMode, const QStringList& rawPaths, QStri
|
||||
output.append( d.absolutePath() );
|
||||
}
|
||||
else
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "module-search entry non-existent" << path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,15 +130,17 @@ interpretInstances( const YAML::Node& node, Settings::InstanceDescriptionList& c
|
||||
for ( const QVariant& instancesVListItem : instances )
|
||||
{
|
||||
if ( instancesVListItem.type() != QVariant::Map )
|
||||
{
|
||||
continue;
|
||||
QVariantMap instancesVListItemMap =
|
||||
instancesVListItem.toMap();
|
||||
}
|
||||
QVariantMap instancesVListItemMap = instancesVListItem.toMap();
|
||||
Settings::InstanceDescription instanceMap;
|
||||
for ( auto it = instancesVListItemMap.constBegin();
|
||||
it != instancesVListItemMap.constEnd(); ++it )
|
||||
for ( auto it = instancesVListItemMap.constBegin(); it != instancesVListItemMap.constEnd(); ++it )
|
||||
{
|
||||
if ( it.value().type() != QVariant::String )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
instanceMap.insert( it.key(), it.value().toString() );
|
||||
}
|
||||
customInstances.append( instanceMap );
|
||||
@ -149,37 +157,43 @@ interpretSequence( const YAML::Node& node, Settings::ModuleSequence& moduleSeque
|
||||
{
|
||||
QVariant sequenceV = CalamaresUtils::yamlToVariant( node );
|
||||
if ( !( sequenceV.type() == QVariant::List ) )
|
||||
{
|
||||
throw YAML::Exception( YAML::Mark(), "sequence key does not have a list-value" );
|
||||
}
|
||||
|
||||
const auto sequence = sequenceV.toList();
|
||||
for ( const QVariant& sequenceVListItem : sequence )
|
||||
{
|
||||
if ( sequenceVListItem.type() != QVariant::Map )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString thisActionS = sequenceVListItem.toMap().firstKey();
|
||||
ModuleAction thisAction;
|
||||
if ( thisActionS == "show" )
|
||||
{
|
||||
thisAction = ModuleAction::Show;
|
||||
}
|
||||
else if ( thisActionS == "exec" )
|
||||
{
|
||||
thisAction = ModuleAction::Exec;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QStringList thisActionRoster = sequenceVListItem
|
||||
.toMap()
|
||||
.value( thisActionS )
|
||||
.toStringList();
|
||||
moduleSequence.append( qMakePair( thisAction,
|
||||
thisActionRoster ) );
|
||||
QStringList thisActionRoster = sequenceVListItem.toMap().value( thisActionS ).toStringList();
|
||||
moduleSequence.append( qMakePair( thisAction, thisActionRoster ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw YAML::Exception( YAML::Mark(), "sequence key is missing" );
|
||||
}
|
||||
}
|
||||
|
||||
Settings::Settings( const QString& settingsFilePath,
|
||||
bool debugMode,
|
||||
QObject* parent )
|
||||
Settings::Settings( const QString& settingsFilePath, bool debugMode, QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_debug( debugMode )
|
||||
, m_doChroot( true )
|
||||
@ -198,7 +212,8 @@ Settings::Settings( const QString& settingsFilePath,
|
||||
YAML::Node config = YAML::Load( ba.constData() );
|
||||
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 );
|
||||
interpretSequence( config[ "sequence" ], m_modulesSequence );
|
||||
|
||||
@ -283,4 +298,4 @@ Settings::disableCancelDuringExec() const
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} // namespace Calamares
|
||||
|
@ -36,9 +36,7 @@ class DLLEXPORT Settings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Settings( const QString& settingsFilePath,
|
||||
bool debugMode,
|
||||
QObject* parent = nullptr );
|
||||
explicit Settings( const QString& settingsFilePath, bool debugMode, QObject* parent = nullptr );
|
||||
|
||||
static Settings* instance();
|
||||
|
||||
@ -88,6 +86,6 @@ private:
|
||||
bool m_disableCancelDuringExec;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Calamares
|
||||
|
||||
#endif // SETTINGS_H
|
||||
#endif // SETTINGS_H
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
// BEGIN Generated from CLDR data
|
||||
// *INDENT-OFF*
|
||||
// clang-format off
|
||||
|
||||
|
||||
struct CountryData
|
||||
|
@ -50,18 +50,24 @@ Label::setLabels( const QString& locale, LabelFormat format )
|
||||
QString countryName;
|
||||
|
||||
if ( languageName.isEmpty() )
|
||||
{
|
||||
languageName = QString( "* %1 (%2)" ).arg( locale, englishName );
|
||||
}
|
||||
|
||||
bool needsCountryName = ( format == LabelFormat::AlwaysWithCountry ) ||
|
||||
(locale.contains( '_' ) && QLocale::countriesForLanguage( m_locale.language() ).count() > 1 );
|
||||
bool needsCountryName = ( format == LabelFormat::AlwaysWithCountry )
|
||||
|| ( locale.contains( '_' ) && QLocale::countriesForLanguage( m_locale.language() ).count() > 1 );
|
||||
|
||||
if ( needsCountryName )
|
||||
{
|
||||
countryName = m_locale.nativeCountryName();
|
||||
}
|
||||
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" ) )
|
||||
{
|
||||
@ -69,8 +75,10 @@ QLocale Label::getLocale( const QString& localeName )
|
||||
return QLocale( loc.language(), QLocale::Script::LatinScript, loc.country() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return QLocale( localeName );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -39,7 +39,11 @@ class Label
|
||||
{
|
||||
public:
|
||||
/** @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. */
|
||||
Label();
|
||||
@ -54,56 +58,33 @@ public:
|
||||
|
||||
/** @brief Define a sorting order.
|
||||
*
|
||||
* English (@see isEnglish() -- it means en_US) is sorted at the top.
|
||||
* Locales are sorted by their id, which means the ISO 2-letter code + country.
|
||||
*/
|
||||
bool operator <( const Label& other ) const
|
||||
{
|
||||
return m_localeId < other.m_localeId;
|
||||
}
|
||||
bool operator<( const Label& other ) const { return m_localeId < other.m_localeId; }
|
||||
|
||||
/** @brief Is this locale English?
|
||||
*
|
||||
* en_US and en (American English) is defined as English. The Queen's
|
||||
* English -- proper English -- is relegated to non-English status.
|
||||
*/
|
||||
bool isEnglish() const
|
||||
{
|
||||
return m_localeId == QLatin1Literal( "en_US" ) || m_localeId == QLatin1Literal( "en" );
|
||||
}
|
||||
bool isEnglish() const { return m_localeId == QLatin1Literal( "en_US" ) || m_localeId == QLatin1Literal( "en" ); }
|
||||
|
||||
/** @brief Get the human-readable name for this locale. */
|
||||
QString label() const
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
QString label() const { return m_label; }
|
||||
/** @brief Get the *English* human-readable name for this locale. */
|
||||
QString englishLabel() const
|
||||
{
|
||||
return m_englishLabel;
|
||||
}
|
||||
QString englishLabel() const { return m_englishLabel; }
|
||||
|
||||
/** @brief Get the Qt locale. */
|
||||
QLocale locale() const
|
||||
{
|
||||
return m_locale;
|
||||
}
|
||||
QLocale locale() const { return m_locale; }
|
||||
|
||||
QString name() const
|
||||
{
|
||||
return m_locale.name();
|
||||
}
|
||||
QString name() const { return m_locale.name(); }
|
||||
QString id() const { return m_localeId; }
|
||||
|
||||
/// @brief Convenience accessor to the language part of the locale
|
||||
QLocale::Language language() const
|
||||
{
|
||||
return m_locale.language();
|
||||
}
|
||||
QLocale::Language language() const { return m_locale.language(); }
|
||||
|
||||
/// @brief Convenience accessor to the country part (if any) of the locale
|
||||
QLocale::Country country() const
|
||||
{
|
||||
return m_locale.country();
|
||||
}
|
||||
QLocale::Country country() const { return m_locale.country(); }
|
||||
|
||||
/** @brief Get a Qt locale for the given @p localeName
|
||||
*
|
||||
@ -119,9 +100,9 @@ protected:
|
||||
QString m_localeId; // the locale identifier, e.g. "en_GB"
|
||||
QString m_label; // the native name of the locale
|
||||
QString m_englishLabel;
|
||||
} ;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
||||
|
@ -34,12 +34,12 @@ LabelModel::LabelModel( const QStringList& locales, QObject* parent )
|
||||
m_locales.reserve( locales.count() );
|
||||
|
||||
for ( const auto& l : locales )
|
||||
{
|
||||
m_locales.push_back( Label( l ) );
|
||||
}
|
||||
}
|
||||
|
||||
LabelModel::~LabelModel()
|
||||
{
|
||||
}
|
||||
LabelModel::~LabelModel() {}
|
||||
|
||||
int
|
||||
LabelModel::rowCount( const QModelIndex& ) const
|
||||
@ -51,10 +51,14 @@ QVariant
|
||||
LabelModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
if ( ( role != LabelRole ) && ( role != EnglishLabelRole ) )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if ( !index.isValid() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const auto& locale = m_locales.at( index.row() );
|
||||
switch ( role )
|
||||
@ -75,59 +79,62 @@ LabelModel::locale( int row ) const
|
||||
{
|
||||
for ( const auto& l : m_locales )
|
||||
if ( l.isEnglish() )
|
||||
{
|
||||
return l;
|
||||
return m_locales[0];
|
||||
}
|
||||
return m_locales[ 0 ];
|
||||
}
|
||||
return m_locales[row];
|
||||
return m_locales[ row ];
|
||||
}
|
||||
|
||||
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 -1;
|
||||
}
|
||||
|
||||
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 predicate( l.locale() );
|
||||
} );
|
||||
return find( [&]( const Label& l ) { return predicate( l.locale() ); } );
|
||||
}
|
||||
|
||||
int
|
||||
LabelModel::find( const QLocale& locale ) const
|
||||
{
|
||||
return find( [&]( const Label& l )
|
||||
{
|
||||
return locale == l.locale();
|
||||
} );
|
||||
return find( [&]( const Label& l ) { return locale == l.locale(); } );
|
||||
}
|
||||
|
||||
int
|
||||
LabelModel::find( const QString& countryCode ) const
|
||||
{
|
||||
if ( countryCode.length() != 2 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -58,8 +58,8 @@ public:
|
||||
*
|
||||
* 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 Label& )> predicate ) const;
|
||||
int find( std::function< bool( const QLocale& ) > 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
|
||||
int find( const QLocale& ) const;
|
||||
/// @brief Looks for an item that best matches the 2-letter country code
|
||||
@ -67,7 +67,7 @@ public:
|
||||
|
||||
private:
|
||||
QVector< Label > m_locales;
|
||||
} ;
|
||||
};
|
||||
|
||||
/** @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.
|
||||
*/
|
||||
DLLEXPORT LabelModel* availableTranslations();
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
#endif
|
||||
|
@ -28,13 +28,13 @@ namespace Locale
|
||||
struct TwoChar
|
||||
{
|
||||
TwoChar( const QString& code )
|
||||
: cc1(0)
|
||||
, cc2(0)
|
||||
: cc1( 0 )
|
||||
, cc2( 0 )
|
||||
{
|
||||
if ( code.length() == 2 )
|
||||
{
|
||||
cc1 = code[0].toLatin1();
|
||||
cc2 = code[1].toLatin1();
|
||||
cc1 = code[ 0 ].toLatin1();
|
||||
cc2 = code[ 1 ].toLatin1();
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,52 +42,65 @@ struct TwoChar
|
||||
char cc2;
|
||||
};
|
||||
|
||||
static const CountryData* lookup( TwoChar c )
|
||||
static const CountryData*
|
||||
lookup( TwoChar c )
|
||||
{
|
||||
if ( !c.cc1 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CountryData* p = 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); }
|
||||
);
|
||||
const CountryData* p
|
||||
= 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 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
QLocale::Country countryForCode(const QString& code)
|
||||
QLocale::Country
|
||||
countryForCode( const QString& code )
|
||||
{
|
||||
const CountryData* p = lookup( TwoChar( code ) );
|
||||
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 ) );
|
||||
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 ) );
|
||||
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 );
|
||||
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,
|
||||
[c=country]( const CountryData& d ){ return d.c == c; }
|
||||
);
|
||||
const CountryData* p = std::find_if( country_data_table,
|
||||
country_data_table + country_data_size,
|
||||
[c = country]( const CountryData& d ) { return d.c == c; } );
|
||||
if ( p == country_data_table + country_data_size )
|
||||
{
|
||||
return QLocale::Language::AnyLanguage;
|
||||
}
|
||||
return p->l;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -28,28 +28,28 @@ namespace CalamaresUtils
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
/* All the functions in this file do lookups of locale data
|
||||
* 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
|
||||
* locale).
|
||||
*/
|
||||
/* All the functions in this file do lookups of locale data
|
||||
* 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
|
||||
* locale).
|
||||
*/
|
||||
|
||||
/// @brief Map a 2-letter code to a Country, or AnyCountry if not found
|
||||
DLLEXPORT QLocale::Country countryForCode( const QString& code );
|
||||
/** @brief Map a Country to a Language, or AnyLanguage if not found
|
||||
*
|
||||
* This is a *likely* language for the given country, based on the
|
||||
* CLDR tables. For instance, this maps Belgium to Dutch.
|
||||
*/
|
||||
DLLEXPORT QLocale::Language languageForCountry( QLocale::Country country );
|
||||
/// @brief Map a 2-letter code to a Language, or AnyLanguage if not found
|
||||
DLLEXPORT QLocale::Language languageForCountry( const QString& code );
|
||||
/// @brief Map a 2-letter code to a Country, or AnyCountry if not found
|
||||
DLLEXPORT QLocale::Country countryForCode( const QString& code );
|
||||
/** @brief Map a Country to a Language, or AnyLanguage if not found
|
||||
*
|
||||
* This is a *likely* language for the given country, based on the
|
||||
* CLDR tables. For instance, this maps Belgium to Dutch.
|
||||
*/
|
||||
DLLEXPORT QLocale::Language languageForCountry( QLocale::Country country );
|
||||
/// @brief Map a 2-letter code to a Language, or AnyLanguage if not found
|
||||
DLLEXPORT QLocale::Language languageForCountry( const QString& code );
|
||||
|
||||
/// @brief Get both Country and Language for a 2-letter code
|
||||
DLLEXPORT QPair< QLocale::Country, QLocale::Language > countryData( const QString& code );
|
||||
/// @brief Get a likely locale for a 2-letter country code
|
||||
DLLEXPORT QLocale countryLocale( const QString& code );
|
||||
}
|
||||
} // namespace
|
||||
/// @brief Get both Country and Language for a 2-letter code
|
||||
DLLEXPORT QPair< QLocale::Country, QLocale::Language > countryData( const QString& code );
|
||||
/// @brief Get a likely locale for a 2-letter country code
|
||||
DLLEXPORT QLocale countryLocale( const QString& code );
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
||||
|
@ -19,19 +19,18 @@
|
||||
#include "Tests.h"
|
||||
|
||||
#include "locale/LabelModel.h"
|
||||
#include "locale/TranslatableConfiguration.h"
|
||||
|
||||
#include "CalamaresVersion.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
QTEST_GUILESS_MAIN( LocaleTests )
|
||||
|
||||
LocaleTests::LocaleTests()
|
||||
{
|
||||
}
|
||||
LocaleTests::LocaleTests() {}
|
||||
|
||||
LocaleTests::~LocaleTests()
|
||||
{
|
||||
}
|
||||
LocaleTests::~LocaleTests() {}
|
||||
|
||||
void
|
||||
LocaleTests::initTestCase()
|
||||
@ -82,6 +81,90 @@ LocaleTests::testEsperanto()
|
||||
QVERIFY( locale.language() == QLocale::Lithuanian ? locale.country() == QLocale::Lithuania : true );
|
||||
QVERIFY( locale.language() != QLocale::C );
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 12, 2 )
|
||||
QCOMPARE( QLocale( "eo" ).language(), QLocale::C );
|
||||
#else
|
||||
QCOMPARE( QLocale( "eo" ).language(), QLocale::Esperanto );
|
||||
#endif
|
||||
}
|
||||
|
||||
static const QStringList&
|
||||
someLanguages()
|
||||
{
|
||||
static QStringList languages { "nl", "de", "da", "nb", "sr@latin", "ar", "ru" };
|
||||
return languages;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocaleTests::testTranslatableLanguages()
|
||||
{
|
||||
QStringList availableLanguages = QString( CALAMARES_TRANSLATION_LANGUAGES ).split( ';' );
|
||||
cDebug() << "Translation languages:" << availableLanguages;
|
||||
for ( const auto& language : someLanguages() )
|
||||
{
|
||||
// Could be QVERIFY, but then we don't see what language code fails
|
||||
QCOMPARE( availableLanguages.contains( language ) ? language : QString(), language );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testTranslatableConfig1()
|
||||
{
|
||||
QCOMPARE( QLocale().name(), "C" ); // Otherwise plain get() is dubious
|
||||
CalamaresUtils::Locale::TranslatedString ts1( "Hello" );
|
||||
QCOMPARE( ts1.count(), 1 );
|
||||
|
||||
QCOMPARE( ts1.get(), "Hello" );
|
||||
QCOMPARE( ts1.get( QLocale( "nl" ) ), "Hello" );
|
||||
|
||||
QVariantMap map;
|
||||
map.insert( "description", "description (no language)" );
|
||||
CalamaresUtils::Locale::TranslatedString ts2( map, "description" );
|
||||
QCOMPARE( ts2.count(), 1 );
|
||||
|
||||
QCOMPARE( ts2.get(), "description (no language)" );
|
||||
QCOMPARE( ts2.get( QLocale( "nl" ) ), "description (no language)" );
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testTranslatableConfig2()
|
||||
{
|
||||
QCOMPARE( QLocale().name(), "C" ); // Otherwise plain get() is dubious
|
||||
QVariantMap map;
|
||||
|
||||
for ( const auto& language : someLanguages() )
|
||||
{
|
||||
map.insert( QString( "description[%1]" ).arg( language ),
|
||||
QString( "description (language %1)" ).arg( language ) );
|
||||
if ( language != "nl" )
|
||||
{
|
||||
map.insert( QString( "name[%1]" ).arg( language ), QString( "name (language %1)" ).arg( language ) );
|
||||
}
|
||||
}
|
||||
|
||||
CalamaresUtils::Locale::TranslatedString ts1( map, "description" );
|
||||
// The +1 is because "" is always also inserted
|
||||
QCOMPARE( ts1.count(), someLanguages().count() + 1 );
|
||||
|
||||
QCOMPARE( ts1.get(), "description" ); // it wasn't set
|
||||
QCOMPARE( ts1.get( QLocale( "nl" ) ), "description (language nl)" );
|
||||
for ( const auto& language : someLanguages() )
|
||||
{
|
||||
// Skip Serbian (latin) because QLocale() constructed with it
|
||||
// doesn't retain the @latin part.
|
||||
if ( language == "sr@latin" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Could be QVERIFY, but then we don't see what language code fails
|
||||
QCOMPARE( ts1.get( language ) == QString( "description (language %1)" ).arg( language ) ? language : QString(),
|
||||
language );
|
||||
}
|
||||
QCOMPARE( ts1.get( QLocale( QLocale::Language::Serbian, QLocale::Script::LatinScript, QLocale::Country::Serbia ) ),
|
||||
"description (language sr@latin)" );
|
||||
|
||||
CalamaresUtils::Locale::TranslatedString ts2( map, "name" );
|
||||
// We skipped dutch this time
|
||||
QCOMPARE( ts2.count(), someLanguages().count() );
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ private Q_SLOTS:
|
||||
|
||||
void testLanguageModelCount();
|
||||
void testEsperanto();
|
||||
void testTranslatableLanguages();
|
||||
void testTranslatableConfig1();
|
||||
void testTranslatableConfig2();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
112
src/libcalamares/locale/TranslatableConfiguration.cpp
Normal file
112
src/libcalamares/locale/TranslatableConfiguration.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TranslatableConfiguration.h"
|
||||
|
||||
#include "LabelModel.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatch>
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
TranslatedString::TranslatedString( const QString& string )
|
||||
{
|
||||
m_strings[ QString() ] = string;
|
||||
}
|
||||
TranslatedString::TranslatedString( const QVariantMap& map, const QString& key )
|
||||
{
|
||||
// Get the un-decorated value for the key
|
||||
QString value = CalamaresUtils::getString( map, key );
|
||||
if ( value.isEmpty() )
|
||||
{
|
||||
value = key;
|
||||
}
|
||||
m_strings[ QString() ] = value;
|
||||
|
||||
for ( auto it = map.constKeyValueBegin(); it != map.constKeyValueEnd(); ++it )
|
||||
{
|
||||
QString subkey = ( *it ).first;
|
||||
if ( subkey == key )
|
||||
{
|
||||
// Already obtained, above
|
||||
}
|
||||
else if ( subkey.startsWith( key ) )
|
||||
{
|
||||
QRegularExpressionMatch match;
|
||||
if ( subkey.indexOf( QRegularExpression( "\\[([a-zA-Z_@]*)\\]" ), 0, &match ) > 0 )
|
||||
{
|
||||
QString language = match.captured( 1 );
|
||||
m_strings[ language ] = ( *it ).second.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
TranslatedString::get() const
|
||||
{
|
||||
return get( QLocale() );
|
||||
}
|
||||
|
||||
QString
|
||||
TranslatedString::get( const QLocale& locale ) const
|
||||
{
|
||||
QString localeName = locale.name();
|
||||
// Special case, sr@latin doesn't have the @latin reflected in the name
|
||||
if ( locale.language() == QLocale::Language::Serbian && locale.script() == QLocale::Script::LatinScript )
|
||||
{
|
||||
localeName = QStringLiteral( "sr@latin" );
|
||||
}
|
||||
|
||||
cDebug() << "Getting locale" << localeName;
|
||||
if ( m_strings.contains( localeName ) )
|
||||
{
|
||||
return m_strings[ localeName ];
|
||||
}
|
||||
int index = localeName.indexOf( '@' );
|
||||
if ( index > 0 )
|
||||
{
|
||||
localeName.truncate( index );
|
||||
if ( m_strings.contains( localeName ) )
|
||||
{
|
||||
return m_strings[ localeName ];
|
||||
}
|
||||
}
|
||||
|
||||
index = localeName.indexOf( '_' );
|
||||
if ( index > 0 )
|
||||
{
|
||||
localeName.truncate( index );
|
||||
if ( m_strings.contains( localeName ) )
|
||||
{
|
||||
return m_strings[ localeName ];
|
||||
}
|
||||
}
|
||||
|
||||
return m_strings[ QString() ];
|
||||
}
|
||||
|
||||
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
63
src/libcalamares/locale/TranslatableConfiguration.h
Normal file
63
src/libcalamares/locale/TranslatableConfiguration.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOCALE_TRANSLATABLECONFIGURATION_H
|
||||
#define LOCALE_TRANSLATABLECONFIGURATION_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include <QLocale>
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
/** @brief A human-readable string from a configuration file
|
||||
*
|
||||
* The configuration files can contain human-readable strings,
|
||||
* but those need their own translations and are not supported
|
||||
* by QObject::tr or anything else.
|
||||
*/
|
||||
class DLLEXPORT TranslatedString
|
||||
{
|
||||
public:
|
||||
/** @brief Get all the translations connected to @p key
|
||||
*/
|
||||
TranslatedString( const QVariantMap& map, const QString& key );
|
||||
/** @brief Not-actually-translated string.
|
||||
*/
|
||||
TranslatedString( const QString& string );
|
||||
|
||||
int count() const { return m_strings.count(); }
|
||||
|
||||
/// @brief Gets the string in the current locale
|
||||
QString get() const;
|
||||
|
||||
/// @brief Gets the string from the given locale
|
||||
QString get( const QLocale& ) const;
|
||||
|
||||
private:
|
||||
// Maps locale name to human-readable string, "" is English
|
||||
QMap< QString, QString > m_strings;
|
||||
};
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
@ -231,6 +231,8 @@ cpp_header_comment = """/* GENERATED FILE DO NOT EDIT
|
||||
*/
|
||||
|
||||
// BEGIN Generated from CLDR data
|
||||
// *INDENT-OFF*
|
||||
// clang-format off
|
||||
|
||||
"""
|
||||
|
||||
|
@ -26,16 +26,13 @@ namespace CalamaresUtils
|
||||
namespace Partition
|
||||
{
|
||||
|
||||
static const NamedEnumTable<SizeUnit>&
|
||||
static const NamedEnumTable< SizeUnit >&
|
||||
unitSuffixes()
|
||||
{
|
||||
static const NamedEnumTable<SizeUnit> names{
|
||||
{ QStringLiteral( "%" ), SizeUnit::Percent },
|
||||
{ QStringLiteral( "K" ), SizeUnit::KiB },
|
||||
{ QStringLiteral( "KiB" ), SizeUnit::KiB },
|
||||
{ QStringLiteral( "M" ), SizeUnit::MiB },
|
||||
{ QStringLiteral( "MiB" ), SizeUnit::MiB },
|
||||
{ QStringLiteral( "G" ), SizeUnit::GiB },
|
||||
static const NamedEnumTable< SizeUnit > names {
|
||||
{ QStringLiteral( "%" ), SizeUnit::Percent }, { QStringLiteral( "K" ), SizeUnit::KiB },
|
||||
{ QStringLiteral( "KiB" ), SizeUnit::KiB }, { QStringLiteral( "M" ), SizeUnit::MiB },
|
||||
{ QStringLiteral( "MiB" ), SizeUnit::MiB }, { QStringLiteral( "G" ), SizeUnit::GiB },
|
||||
{ QStringLiteral( "GiB" ), SizeUnit::GiB }
|
||||
};
|
||||
|
||||
@ -55,7 +52,9 @@ PartitionSize::PartitionSize( const QString& s )
|
||||
{
|
||||
m_value = s.toInt();
|
||||
if ( m_value > 0 )
|
||||
{
|
||||
m_unit = SizeUnit::Byte;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_value <= 0 )
|
||||
@ -69,9 +68,13 @@ qint64
|
||||
PartitionSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ( totalSectors < 1 || sectorSize < 1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch ( m_unit )
|
||||
{
|
||||
@ -79,14 +82,18 @@ PartitionSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const
|
||||
return -1;
|
||||
case SizeUnit::Percent:
|
||||
if ( value() == 100 )
|
||||
{
|
||||
return totalSectors; // Common-case, avoid futzing around
|
||||
}
|
||||
else
|
||||
{
|
||||
return totalSectors * value() / 100;
|
||||
}
|
||||
case SizeUnit::Byte:
|
||||
case SizeUnit::KiB:
|
||||
case SizeUnit::MiB:
|
||||
case SizeUnit::GiB:
|
||||
return CalamaresUtils::bytesToSectors ( toBytes(), sectorSize );
|
||||
return CalamaresUtils::bytesToSectors( toBytes(), sectorSize );
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -96,7 +103,9 @@ qint64
|
||||
PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch ( m_unit )
|
||||
{
|
||||
@ -104,11 +113,17 @@ PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const
|
||||
return -1;
|
||||
case SizeUnit::Percent:
|
||||
if ( totalSectors < 1 || sectorSize < 1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ( value() == 100 )
|
||||
{
|
||||
return totalSectors * sectorSize; // Common-case, avoid futzing around
|
||||
}
|
||||
else
|
||||
{
|
||||
return totalSectors * value() / 100;
|
||||
}
|
||||
case SizeUnit::Byte:
|
||||
case SizeUnit::KiB:
|
||||
case SizeUnit::MiB:
|
||||
@ -124,7 +139,9 @@ qint64
|
||||
PartitionSize::toBytes( qint64 totalBytes ) const
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch ( m_unit )
|
||||
{
|
||||
@ -132,11 +149,17 @@ PartitionSize::toBytes( qint64 totalBytes ) const
|
||||
return -1;
|
||||
case SizeUnit::Percent:
|
||||
if ( totalBytes < 1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ( value() == 100 )
|
||||
{
|
||||
return totalBytes; // Common-case, avoid futzing around
|
||||
}
|
||||
else
|
||||
{
|
||||
return totalBytes * value() / 100;
|
||||
}
|
||||
case SizeUnit::Byte:
|
||||
case SizeUnit::KiB:
|
||||
case SizeUnit::MiB:
|
||||
@ -152,7 +175,9 @@ qint64
|
||||
PartitionSize::toBytes() const
|
||||
{
|
||||
if ( !isValid() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch ( m_unit )
|
||||
{
|
||||
@ -162,20 +187,22 @@ PartitionSize::toBytes() const
|
||||
case SizeUnit::Byte:
|
||||
return value();
|
||||
case SizeUnit::KiB:
|
||||
return CalamaresUtils::KiBtoBytes( static_cast<unsigned long long>( value() ) );
|
||||
return CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( value() ) );
|
||||
case SizeUnit::MiB:
|
||||
return CalamaresUtils::MiBtoBytes( static_cast<unsigned long long>( value() ) );
|
||||
return CalamaresUtils::MiBtoBytes( static_cast< unsigned long long >( value() ) );
|
||||
case SizeUnit::GiB:
|
||||
return CalamaresUtils::GiBtoBytes( static_cast<unsigned long long>( value() ) );
|
||||
return CalamaresUtils::GiBtoBytes( static_cast< unsigned long long >( value() ) );
|
||||
}
|
||||
NOTREACHED return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
PartitionSize::operator< ( const PartitionSize& other ) const
|
||||
PartitionSize::operator<( const PartitionSize& other ) const
|
||||
{
|
||||
if ( !unitsComparable( m_unit, other.m_unit ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ( m_unit )
|
||||
{
|
||||
@ -187,16 +214,18 @@ PartitionSize::operator< ( const PartitionSize& other ) const
|
||||
case SizeUnit::KiB:
|
||||
case SizeUnit::MiB:
|
||||
case SizeUnit::GiB:
|
||||
return ( toBytes() < other.toBytes () );
|
||||
return ( toBytes() < other.toBytes() );
|
||||
}
|
||||
NOTREACHED return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PartitionSize::operator> ( const PartitionSize& other ) const
|
||||
PartitionSize::operator>( const PartitionSize& other ) const
|
||||
{
|
||||
if ( !unitsComparable( m_unit, other.m_unit ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ( m_unit )
|
||||
{
|
||||
@ -208,16 +237,18 @@ PartitionSize::operator> ( const PartitionSize& other ) const
|
||||
case SizeUnit::KiB:
|
||||
case SizeUnit::MiB:
|
||||
case SizeUnit::GiB:
|
||||
return ( toBytes() > other.toBytes () );
|
||||
return ( toBytes() > other.toBytes() );
|
||||
}
|
||||
NOTREACHED return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PartitionSize::operator== ( const PartitionSize& other ) const
|
||||
PartitionSize::operator==( const PartitionSize& other ) const
|
||||
{
|
||||
if ( !unitsComparable( m_unit, other.m_unit ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ( m_unit )
|
||||
{
|
||||
@ -229,10 +260,10 @@ PartitionSize::operator== ( const PartitionSize& other ) const
|
||||
case SizeUnit::KiB:
|
||||
case SizeUnit::MiB:
|
||||
case SizeUnit::GiB:
|
||||
return ( toBytes() == other.toBytes () );
|
||||
return ( toBytes() == other.toBytes() );
|
||||
}
|
||||
NOTREACHED return false;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Partition
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -20,8 +20,8 @@
|
||||
#ifndef PARTITION_PARTITIONSIZE_H
|
||||
#define PARTITION_PARTITIONSIZE_H
|
||||
|
||||
#include "utils/Units.h"
|
||||
#include "utils/NamedSuffix.h"
|
||||
#include "utils/Units.h"
|
||||
|
||||
// Qt
|
||||
#include <QString>
|
||||
@ -47,21 +47,24 @@ enum class SizeUnit
|
||||
* the available drive space are on). This class handles parsing
|
||||
* of such strings from the config file.
|
||||
*/
|
||||
class PartitionSize : public NamedSuffix<SizeUnit, SizeUnit::None>
|
||||
class PartitionSize : public NamedSuffix< SizeUnit, SizeUnit::None >
|
||||
{
|
||||
public:
|
||||
PartitionSize() : NamedSuffix() { }
|
||||
PartitionSize( int v, SizeUnit u ) : NamedSuffix( v, u ) { }
|
||||
PartitionSize()
|
||||
: NamedSuffix()
|
||||
{
|
||||
}
|
||||
PartitionSize( int v, SizeUnit u )
|
||||
: NamedSuffix( v, u )
|
||||
{
|
||||
}
|
||||
PartitionSize( const QString& );
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return ( unit() != SizeUnit::None ) && ( value() > 0 );
|
||||
}
|
||||
bool isValid() const { 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 .
|
||||
*
|
||||
@ -109,14 +112,13 @@ public:
|
||||
*/
|
||||
static constexpr bool unitsComparable( const SizeUnit u1, const SizeUnit u2 )
|
||||
{
|
||||
return !( ( u1 == SizeUnit::None || u2 == SizeUnit::None ) ||
|
||||
( u1 == SizeUnit::Percent && u2 != SizeUnit::Percent ) ||
|
||||
( u1 != SizeUnit::Percent && u2 == SizeUnit::Percent ) );
|
||||
return !( ( u1 == SizeUnit::None || u2 == SizeUnit::None )
|
||||
|| ( u1 == SizeUnit::Percent && u2 != SizeUnit::Percent )
|
||||
|| ( u1 != SizeUnit::Percent && u2 == SizeUnit::Percent ) );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Partition
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif // PARTITION_PARTITIONSIZE_H
|
||||
#endif // PARTITION_PARTITIONSIZE_H
|
||||
|
@ -31,13 +31,9 @@ Q_DECLARE_METATYPE( SizeUnit )
|
||||
|
||||
QTEST_GUILESS_MAIN( PartitionSizeTests )
|
||||
|
||||
PartitionSizeTests::PartitionSizeTests()
|
||||
{
|
||||
}
|
||||
PartitionSizeTests::PartitionSizeTests() {}
|
||||
|
||||
PartitionSizeTests::~PartitionSizeTests()
|
||||
{
|
||||
}
|
||||
PartitionSizeTests::~PartitionSizeTests() {}
|
||||
|
||||
void
|
||||
PartitionSizeTests::initTestCase()
|
||||
@ -47,36 +43,38 @@ PartitionSizeTests::initTestCase()
|
||||
void
|
||||
PartitionSizeTests::testUnitComparison_data()
|
||||
{
|
||||
QTest::addColumn<SizeUnit>("u1");
|
||||
QTest::addColumn<SizeUnit>("u2");
|
||||
QTest::addColumn<bool>("comparable");
|
||||
QTest::addColumn< SizeUnit >( "u1" );
|
||||
QTest::addColumn< SizeUnit >( "u2" );
|
||||
QTest::addColumn< bool >( "comparable" );
|
||||
|
||||
QTest::newRow("nones") << SizeUnit::None << SizeUnit::None << false;
|
||||
QTest::newRow("none+%") << SizeUnit::None << SizeUnit::Percent<< false;
|
||||
QTest::newRow("%+none") << SizeUnit::Percent << SizeUnit::None << false;
|
||||
QTest::newRow("KiB+none") << SizeUnit::KiB << SizeUnit::None << false;
|
||||
QTest::newRow("none+MiB") << SizeUnit::None << SizeUnit::MiB << false;
|
||||
QTest::newRow( "nones" ) << SizeUnit::None << SizeUnit::None << false;
|
||||
QTest::newRow( "none+%" ) << SizeUnit::None << SizeUnit::Percent << false;
|
||||
QTest::newRow( "%+none" ) << SizeUnit::Percent << SizeUnit::None << false;
|
||||
QTest::newRow( "KiB+none" ) << SizeUnit::KiB << SizeUnit::None << false;
|
||||
QTest::newRow( "none+MiB" ) << SizeUnit::None << SizeUnit::MiB << false;
|
||||
|
||||
QTest::newRow("KiB+KiB") << SizeUnit::KiB << SizeUnit::KiB << true;
|
||||
QTest::newRow("KiB+MiB") << SizeUnit::KiB << SizeUnit::MiB << true;
|
||||
QTest::newRow("KiB+GiB") << SizeUnit::KiB << SizeUnit::GiB << true;
|
||||
QTest::newRow("MiB+MiB") << SizeUnit::MiB << SizeUnit::MiB << true;
|
||||
QTest::newRow("MiB+GiB") << SizeUnit::MiB << SizeUnit::GiB << true;
|
||||
QTest::newRow("GiB+GiB") << SizeUnit::GiB << SizeUnit::GiB << true;
|
||||
QTest::newRow( "KiB+KiB" ) << SizeUnit::KiB << SizeUnit::KiB << true;
|
||||
QTest::newRow( "KiB+MiB" ) << SizeUnit::KiB << SizeUnit::MiB << true;
|
||||
QTest::newRow( "KiB+GiB" ) << SizeUnit::KiB << SizeUnit::GiB << true;
|
||||
QTest::newRow( "MiB+MiB" ) << SizeUnit::MiB << SizeUnit::MiB << true;
|
||||
QTest::newRow( "MiB+GiB" ) << SizeUnit::MiB << SizeUnit::GiB << true;
|
||||
QTest::newRow( "GiB+GiB" ) << SizeUnit::GiB << SizeUnit::GiB << true;
|
||||
|
||||
QTest::newRow("%+None") << SizeUnit::Percent << SizeUnit::None << false;
|
||||
QTest::newRow("%+%") << SizeUnit::Percent << SizeUnit::Percent << true;
|
||||
QTest::newRow("%+KiB") << SizeUnit::Percent << SizeUnit::KiB << false;
|
||||
QTest::newRow( "%+None" ) << SizeUnit::Percent << SizeUnit::None << false;
|
||||
QTest::newRow( "%+%" ) << SizeUnit::Percent << SizeUnit::Percent << true;
|
||||
QTest::newRow( "%+KiB" ) << SizeUnit::Percent << SizeUnit::KiB << false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
original_compare( SizeUnit m_unit, SizeUnit other_m_unit )
|
||||
{
|
||||
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 ) )
|
||||
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 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -104,33 +102,33 @@ PartitionSizeTests::testUnitComparison()
|
||||
void
|
||||
PartitionSizeTests::testUnitNormalisation_data()
|
||||
{
|
||||
QTest::addColumn<SizeUnit>("u1");
|
||||
QTest::addColumn<int>("v");
|
||||
QTest::addColumn<long>("bytes");
|
||||
QTest::addColumn< SizeUnit >( "u1" );
|
||||
QTest::addColumn< int >( "v" );
|
||||
QTest::addColumn< long >( "bytes" );
|
||||
|
||||
QTest::newRow("none") << SizeUnit::None << 16 << -1L;
|
||||
QTest::newRow("none") << SizeUnit::None << 0 << -1L;
|
||||
QTest::newRow("none") << SizeUnit::None << -2 << -1L;
|
||||
QTest::newRow( "none" ) << SizeUnit::None << 16 << -1L;
|
||||
QTest::newRow( "none" ) << SizeUnit::None << 0 << -1L;
|
||||
QTest::newRow( "none" ) << SizeUnit::None << -2 << -1L;
|
||||
|
||||
QTest::newRow("percent") << SizeUnit::Percent << 0 << -1L;
|
||||
QTest::newRow("percent") << SizeUnit::Percent << 16 << -1L;
|
||||
QTest::newRow("percent") << SizeUnit::Percent << -2 << -1L;
|
||||
QTest::newRow( "percent" ) << SizeUnit::Percent << 0 << -1L;
|
||||
QTest::newRow( "percent" ) << SizeUnit::Percent << 16 << -1L;
|
||||
QTest::newRow( "percent" ) << SizeUnit::Percent << -2 << -1L;
|
||||
|
||||
QTest::newRow("KiB") << SizeUnit::KiB << 0 << -1L;
|
||||
QTest::newRow("KiB") << SizeUnit::KiB << 1 << 1024L;
|
||||
QTest::newRow("KiB") << SizeUnit::KiB << 1000 << 1024000L;
|
||||
QTest::newRow("KiB") << SizeUnit::KiB << 1024 << 1024 * 1024L;
|
||||
QTest::newRow("KiB") << SizeUnit::KiB << -2 << -1L;
|
||||
QTest::newRow( "KiB" ) << SizeUnit::KiB << 0 << -1L;
|
||||
QTest::newRow( "KiB" ) << SizeUnit::KiB << 1 << 1024L;
|
||||
QTest::newRow( "KiB" ) << SizeUnit::KiB << 1000 << 1024000L;
|
||||
QTest::newRow( "KiB" ) << SizeUnit::KiB << 1024 << 1024 * 1024L;
|
||||
QTest::newRow( "KiB" ) << SizeUnit::KiB << -2 << -1L;
|
||||
|
||||
QTest::newRow("MiB") << SizeUnit::MiB << 0 << -1L;
|
||||
QTest::newRow("MiB") << SizeUnit::MiB << 1 << 1024 * 1024L;
|
||||
QTest::newRow("MiB") << SizeUnit::MiB << 1000 << 1024 * 1024000L;
|
||||
QTest::newRow("MiB") << SizeUnit::MiB << 1024 << 1024 * 1024 * 1024L;
|
||||
QTest::newRow("MiB") << SizeUnit::MiB << -2 << -1L;
|
||||
QTest::newRow( "MiB" ) << SizeUnit::MiB << 0 << -1L;
|
||||
QTest::newRow( "MiB" ) << SizeUnit::MiB << 1 << 1024 * 1024L;
|
||||
QTest::newRow( "MiB" ) << SizeUnit::MiB << 1000 << 1024 * 1024000L;
|
||||
QTest::newRow( "MiB" ) << SizeUnit::MiB << 1024 << 1024 * 1024 * 1024L;
|
||||
QTest::newRow( "MiB" ) << SizeUnit::MiB << -2 << -1L;
|
||||
|
||||
QTest::newRow("GiB") << SizeUnit::GiB << 0 << -1L;
|
||||
QTest::newRow("GiB") << SizeUnit::GiB << 1 << 1024 * 1024 * 1024L;
|
||||
QTest::newRow("GiB") << SizeUnit::GiB << 2 << 2048 * 1024 * 1024L;
|
||||
QTest::newRow( "GiB" ) << SizeUnit::GiB << 0 << -1L;
|
||||
QTest::newRow( "GiB" ) << SizeUnit::GiB << 1 << 1024 * 1024 * 1024L;
|
||||
QTest::newRow( "GiB" ) << SizeUnit::GiB << 2 << 2048 * 1024 * 1024L;
|
||||
}
|
||||
|
||||
void
|
||||
@ -140,5 +138,5 @@ PartitionSizeTests::testUnitNormalisation()
|
||||
QFETCH( int, v );
|
||||
QFETCH( long, bytes );
|
||||
|
||||
QCOMPARE( PartitionSize( v, u1 ).toBytes(), static_cast<qint64>( bytes ) );
|
||||
QCOMPARE( PartitionSize( v, u1 ).toBytes(), static_cast< qint64 >( bytes ) );
|
||||
}
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
#include "CalamaresUtilsSystem.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
@ -34,8 +34,11 @@
|
||||
#endif
|
||||
|
||||
#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/sysctl.h>
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
/** @brief When logging commands, don't log everything.
|
||||
@ -48,12 +51,12 @@
|
||||
struct RedactedList
|
||||
{
|
||||
RedactedList( const QStringList& l )
|
||||
: list(l)
|
||||
: list( l )
|
||||
{
|
||||
}
|
||||
|
||||
const QStringList& list;
|
||||
} ;
|
||||
};
|
||||
|
||||
QDebug&
|
||||
operator<<( QDebug& s, const RedactedList& l )
|
||||
@ -63,12 +66,18 @@ operator<<( QDebug& s, const RedactedList& l )
|
||||
{
|
||||
for ( const auto& item : l.list )
|
||||
if ( item.startsWith( "$6$" ) )
|
||||
{
|
||||
s << "<password>";
|
||||
}
|
||||
else
|
||||
{
|
||||
s << item;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s << l.list;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -92,8 +101,7 @@ System::System( bool doChroot, QObject* parent )
|
||||
}
|
||||
|
||||
|
||||
System::~System()
|
||||
{}
|
||||
System::~System() {}
|
||||
|
||||
|
||||
System*
|
||||
@ -111,18 +119,22 @@ System::instance()
|
||||
|
||||
int
|
||||
System::mount( const QString& devicePath,
|
||||
const QString& mountPoint,
|
||||
const QString& filesystemName,
|
||||
const QString& options )
|
||||
const QString& mountPoint,
|
||||
const QString& filesystemName,
|
||||
const QString& options )
|
||||
{
|
||||
if ( devicePath.isEmpty() || mountPoint.isEmpty() )
|
||||
{
|
||||
if ( devicePath.isEmpty() )
|
||||
{
|
||||
cWarning() << "Can't mount an empty device.";
|
||||
}
|
||||
if ( mountPoint.isEmpty() )
|
||||
{
|
||||
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 );
|
||||
@ -132,7 +144,7 @@ System::mount( const QString& devicePath,
|
||||
if ( !ok )
|
||||
{
|
||||
cWarning() << "Could not create mountpoint" << mountPoint;
|
||||
return static_cast<int>(ProcessResult::Code::NoWorkingDirectory);
|
||||
return static_cast< int >( ProcessResult::Code::NoWorkingDirectory );
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,28 +152,31 @@ System::mount( const QString& devicePath,
|
||||
QStringList args = { devicePath, mountPoint };
|
||||
|
||||
if ( !filesystemName.isEmpty() )
|
||||
{
|
||||
args << "-t" << filesystemName;
|
||||
}
|
||||
|
||||
if ( !options.isEmpty() )
|
||||
{
|
||||
args << "-o" << options;
|
||||
}
|
||||
|
||||
return QProcess::execute( program, args );
|
||||
}
|
||||
|
||||
ProcessResult
|
||||
System::runCommand(
|
||||
System::RunLocation location,
|
||||
const QStringList& args,
|
||||
const QString& workingPath,
|
||||
const QString& stdInput,
|
||||
std::chrono::seconds timeoutSec )
|
||||
System::runCommand( System::RunLocation location,
|
||||
const QStringList& args,
|
||||
const QString& workingPath,
|
||||
const QString& stdInput,
|
||||
std::chrono::seconds timeoutSec )
|
||||
{
|
||||
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 ) &&
|
||||
( !gs || !gs->contains( "rootMountPoint" ) ) )
|
||||
if ( ( location == System::RunLocation::RunInTarget ) && ( !gs || !gs->contains( "rootMountPoint" ) ) )
|
||||
{
|
||||
cWarning() << "No rootMountPoint in global storage";
|
||||
return ProcessResult::Code::NoWorkingDirectory;
|
||||
@ -197,7 +212,9 @@ System::runCommand(
|
||||
if ( !workingPath.isEmpty() )
|
||||
{
|
||||
if ( QDir( workingPath ).exists() )
|
||||
{
|
||||
process.setWorkingDirectory( QDir( workingPath ).absolutePath() );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Invalid working directory:" << workingPath;
|
||||
@ -219,10 +236,10 @@ System::runCommand(
|
||||
}
|
||||
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" <<
|
||||
process.readAllStandardOutput();
|
||||
cWarning().noquote().nospace() << "Timed out. Output so far:\n" << process.readAllStandardOutput();
|
||||
return ProcessResult::Code::TimedOut;
|
||||
}
|
||||
|
||||
@ -242,7 +259,7 @@ System::runCommand(
|
||||
cDebug() << "Target cmd:" << RedactedList( args );
|
||||
cDebug().noquote().nospace() << "Target output:\n" << output;
|
||||
}
|
||||
return ProcessResult(r, output);
|
||||
return ProcessResult( r, output );
|
||||
}
|
||||
|
||||
QString
|
||||
@ -252,7 +269,8 @@ System::targetPath( const QString& path ) const
|
||||
|
||||
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" ) )
|
||||
{
|
||||
@ -309,28 +327,32 @@ System::createTargetFile( const QString& path, const QByteArray& contents ) cons
|
||||
}
|
||||
|
||||
|
||||
QPair<quint64, float>
|
||||
QPair< quint64, float >
|
||||
System::getTotalMemoryB() const
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
struct sysinfo i;
|
||||
int r = sysinfo( &i );
|
||||
|
||||
if (r)
|
||||
return qMakePair(0, 0.0);
|
||||
if ( r )
|
||||
{
|
||||
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 )
|
||||
unsigned long memsize;
|
||||
size_t s = sizeof(memsize);
|
||||
size_t s = sizeof( memsize );
|
||||
|
||||
int r = sysctlbyname("vm.kmem_size", &memsize, &s, NULL, 0);
|
||||
if (r)
|
||||
return qMakePair(0, 0.0);
|
||||
int r = sysctlbyname( "vm.kmem_size", &memsize, &s, NULL, 0 );
|
||||
if ( r )
|
||||
{
|
||||
return qMakePair( 0, 0.0 );
|
||||
}
|
||||
|
||||
return qMakePair(memsize, 1.01);
|
||||
return qMakePair( memsize, 1.01 );
|
||||
#else
|
||||
return qMakePair(0, 0.0); // Unsupported
|
||||
return qMakePair( 0, 0.0 ); // Unsupported
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -341,14 +363,14 @@ System::getCpuDescription() const
|
||||
QString model;
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
QFile file("/proc/cpuinfo");
|
||||
if ( file.open(QIODevice::ReadOnly | QIODevice::Text) )
|
||||
QFile file( "/proc/cpuinfo" );
|
||||
if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
|
||||
while ( !file.atEnd() )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -376,40 +398,45 @@ ProcessResult::explainProcess( int ec, const QString& command, const QString& ou
|
||||
using Calamares::JobResult;
|
||||
|
||||
if ( ec == 0 )
|
||||
{
|
||||
return JobResult::ok();
|
||||
}
|
||||
|
||||
QString outputMessage = output.isEmpty()
|
||||
? QCoreApplication::translate( "ProcessResult", "\nThere was no output from the command.")
|
||||
: (QCoreApplication::translate( "ProcessResult", "\nOutput:\n") + output);
|
||||
? QCoreApplication::translate( "ProcessResult", "\nThere was no output from the command." )
|
||||
: ( QCoreApplication::translate( "ProcessResult", "\nOutput:\n" ) + output );
|
||||
|
||||
if ( ec == static_cast<int>(ProcessResult::Code::Crashed) ) //Crash!
|
||||
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command crashed." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> crashed." )
|
||||
.arg( command )
|
||||
+ outputMessage );
|
||||
if ( ec == static_cast< int >( ProcessResult::Code::Crashed ) ) //Crash!
|
||||
return JobResult::error(
|
||||
QCoreApplication::translate( "ProcessResult", "External command crashed." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> crashed." ).arg( command )
|
||||
+ outputMessage );
|
||||
|
||||
if ( ec == static_cast<int>(ProcessResult::Code::FailedToStart) )
|
||||
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command failed to start." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to start." )
|
||||
.arg( command ) );
|
||||
if ( ec == static_cast< int >( ProcessResult::Code::FailedToStart ) )
|
||||
return JobResult::error(
|
||||
QCoreApplication::translate( "ProcessResult", "External command failed to start." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to start." ).arg( command ) );
|
||||
|
||||
if ( ec == static_cast<int>(ProcessResult::Code::NoWorkingDirectory) )
|
||||
return JobResult::error( QCoreApplication::translate( "ProcessResult", "Internal error when starting command." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Bad parameters for process job call." ) );
|
||||
if ( ec == static_cast< int >( ProcessResult::Code::NoWorkingDirectory ) )
|
||||
return JobResult::error(
|
||||
QCoreApplication::translate( "ProcessResult", "Internal error when starting command." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Bad parameters for process job call." ) );
|
||||
|
||||
if ( ec == static_cast<int>(ProcessResult::Code::TimedOut) )
|
||||
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command failed to finish." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to finish in %2 seconds." )
|
||||
.arg( command )
|
||||
.arg( timeout.count() )
|
||||
+ outputMessage );
|
||||
if ( ec == static_cast< int >( ProcessResult::Code::TimedOut ) )
|
||||
return JobResult::error(
|
||||
QCoreApplication::translate( "ProcessResult", "External command failed to finish." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> failed to finish in %2 seconds." )
|
||||
.arg( command )
|
||||
.arg( timeout.count() )
|
||||
+ outputMessage );
|
||||
|
||||
//Any other exit code
|
||||
return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command finished with errors." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> finished with exit code %2." )
|
||||
.arg( command )
|
||||
.arg( ec )
|
||||
+ outputMessage );
|
||||
return JobResult::error(
|
||||
QCoreApplication::translate( "ProcessResult", "External command finished with errors." ),
|
||||
QCoreApplication::translate( "ProcessResult", "Command <i>%1</i> finished with exit code %2." )
|
||||
.arg( command )
|
||||
.arg( ec )
|
||||
+ outputMessage );
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -36,15 +36,21 @@ class ProcessResult : public QPair< int, QString >
|
||||
public:
|
||||
enum class Code : int
|
||||
{
|
||||
Crashed = -1, // Must match special return values from QProcess
|
||||
Crashed = -1, // Must match special return values from QProcess
|
||||
FailedToStart = -2, // Must match special return values from QProcess
|
||||
NoWorkingDirectory = -3,
|
||||
TimedOut = -4
|
||||
} ;
|
||||
};
|
||||
|
||||
/** @brief Implicit one-argument constructor has no output, only a return code */
|
||||
ProcessResult( Code r ) : QPair< int, QString >( static_cast<int>(r), QString() ) {}
|
||||
ProcessResult( int r, QString s ) : QPair< int, QString >( r, s ) {}
|
||||
ProcessResult( Code r )
|
||||
: QPair< int, QString >( static_cast< int >( r ), QString() )
|
||||
{
|
||||
}
|
||||
ProcessResult( int r, QString s )
|
||||
: QPair< int, QString >( r, s )
|
||||
{
|
||||
}
|
||||
|
||||
int getExitCode() const { return first; }
|
||||
QString getOutput() const { return second; }
|
||||
@ -62,7 +68,8 @@ public:
|
||||
* @param timeout Timeout passed to the process runner, for explaining
|
||||
* 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()
|
||||
inline Calamares::JobResult explainProcess( const QString& command, std::chrono::seconds timeout ) const
|
||||
@ -75,7 +82,7 @@ public:
|
||||
{
|
||||
return explainProcess( getExitCode(), command.join( ' ' ), getOutput(), timeout );
|
||||
}
|
||||
} ;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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,
|
||||
* 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.
|
||||
@ -135,37 +146,31 @@ public:
|
||||
* NoWorkingDirectory = bad arguments
|
||||
* TimedOut = QProcess timeout
|
||||
*/
|
||||
static DLLEXPORT ProcessResult runCommand(
|
||||
RunLocation location,
|
||||
const QStringList &args,
|
||||
const QString& workingPath = QString(),
|
||||
const QString& stdInput = QString(),
|
||||
std::chrono::seconds timeoutSec = std::chrono::seconds(0) );
|
||||
static DLLEXPORT ProcessResult runCommand( RunLocation location,
|
||||
const QStringList& args,
|
||||
const QString& workingPath = QString(),
|
||||
const QString& stdInput = QString(),
|
||||
std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) );
|
||||
|
||||
/** @brief Convenience wrapper for runCommand().
|
||||
* Runs the command in the location specified through the boolean
|
||||
* doChroot(), which is what you usually want for running commands
|
||||
* during installation.
|
||||
*/
|
||||
inline ProcessResult targetEnvCommand(
|
||||
const QStringList &args,
|
||||
const QString& workingPath = QString(),
|
||||
const QString& stdInput = QString(),
|
||||
std::chrono::seconds timeoutSec = std::chrono::seconds(0) )
|
||||
inline ProcessResult targetEnvCommand( const QStringList& args,
|
||||
const QString& workingPath = QString(),
|
||||
const QString& stdInput = QString(),
|
||||
std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) )
|
||||
{
|
||||
return runCommand(
|
||||
m_doChroot ? RunLocation::RunInTarget : RunLocation::RunInHost,
|
||||
args,
|
||||
workingPath,
|
||||
stdInput,
|
||||
timeoutSec );
|
||||
m_doChroot ? RunLocation::RunInTarget : RunLocation::RunInHost, args, workingPath, stdInput, timeoutSec );
|
||||
}
|
||||
|
||||
/** @brief Convenience wrapper for targetEnvCommand() which returns only the exit code */
|
||||
inline int targetEnvCall( const QStringList& args,
|
||||
const QString& workingPath = 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;
|
||||
}
|
||||
@ -174,9 +179,9 @@ public:
|
||||
inline int targetEnvCall( const QString& command,
|
||||
const QString& workingPath = 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
|
||||
@ -184,10 +189,10 @@ public:
|
||||
* Places the called program's output in the @p output string.
|
||||
*/
|
||||
int targetEnvOutput( const QStringList& args,
|
||||
QString& output,
|
||||
const QString& workingPath = QString(),
|
||||
const QString& stdInput = QString(),
|
||||
std::chrono::seconds timeoutSec = std::chrono::seconds(0) )
|
||||
QString& output,
|
||||
const QString& workingPath = QString(),
|
||||
const QString& stdInput = QString(),
|
||||
std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) )
|
||||
{
|
||||
auto r = targetEnvCommand( args, workingPath, stdInput, timeoutSec );
|
||||
output = r.second;
|
||||
@ -202,9 +207,9 @@ public:
|
||||
QString& output,
|
||||
const QString& workingPath = 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
|
||||
*/
|
||||
DLLEXPORT QPair<quint64, float> getTotalMemoryB() const;
|
||||
DLLEXPORT QPair< quint64, float > getTotalMemoryB() const;
|
||||
|
||||
/**
|
||||
* @brief getCpuDescription returns a string describing the CPU.
|
||||
@ -279,6 +284,6 @@ private:
|
||||
bool m_doChroot;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
||||
|
@ -32,34 +32,44 @@
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
|
||||
static CommandLine get_variant_object( const QVariantMap& m )
|
||||
static CommandLine
|
||||
get_variant_object( const QVariantMap& m )
|
||||
{
|
||||
QString command = CalamaresUtils::getString( m, "command" );
|
||||
int timeout = CalamaresUtils::getInteger( m, "timeout", -1 );
|
||||
|
||||
if ( !command.isEmpty() )
|
||||
{
|
||||
return CommandLine( command, timeout >= 0 ? std::chrono::seconds( timeout ) : CommandLine::TimeoutNotSet() );
|
||||
}
|
||||
cWarning() << "Bad CommandLine element" << m;
|
||||
return CommandLine();
|
||||
}
|
||||
|
||||
static CommandList_t get_variant_stringlist( const QVariantList& l )
|
||||
static CommandList_t
|
||||
get_variant_stringlist( const QVariantList& l )
|
||||
{
|
||||
CommandList_t retl;
|
||||
unsigned int count = 0;
|
||||
for ( const auto& v : l )
|
||||
{
|
||||
if ( v.type() == QVariant::String )
|
||||
{
|
||||
retl.append( CommandLine( v.toString(), CommandLine::TimeoutNotSet() ) );
|
||||
}
|
||||
else if ( v.type() == QVariant::Map )
|
||||
{
|
||||
auto command( get_variant_object( v.toMap() ) );
|
||||
if ( command.isValid() )
|
||||
{
|
||||
retl.append( command );
|
||||
}
|
||||
// Otherwise warning is already given
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Bad CommandList element" << count << v.type() << v;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
return retl;
|
||||
@ -78,37 +88,48 @@ CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, std::ch
|
||||
{
|
||||
const auto v_list = v.toList();
|
||||
if ( v_list.count() )
|
||||
{
|
||||
append( get_variant_stringlist( v_list ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Empty CommandList";
|
||||
}
|
||||
}
|
||||
else if ( v.type() == QVariant::String )
|
||||
{
|
||||
append( v.toString() );
|
||||
}
|
||||
else if ( v.type() == QVariant::Map )
|
||||
{
|
||||
auto c( get_variant_object( v.toMap() ) );
|
||||
if ( c.isValid() )
|
||||
{
|
||||
append( c );
|
||||
}
|
||||
// Otherwise warning is already given
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "CommandList does not understand variant" << v.type();
|
||||
}
|
||||
}
|
||||
|
||||
CommandList::~CommandList()
|
||||
{
|
||||
}
|
||||
CommandList::~CommandList() {}
|
||||
|
||||
static inline bool
|
||||
findInCommands( const CommandList& l, const QString& needle )
|
||||
{
|
||||
for ( CommandList::const_iterator i = l.cbegin(); i != l.cend(); ++i )
|
||||
if ( i->command().contains( needle ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Calamares::JobResult CommandList::run()
|
||||
Calamares::JobResult
|
||||
CommandList::run()
|
||||
{
|
||||
QLatin1Literal rootMagic( "@@ROOT@@" );
|
||||
QLatin1Literal userMagic( "@@USER@@" );
|
||||
@ -125,8 +146,11 @@ Calamares::JobResult CommandList::run()
|
||||
if ( !gs || !gs->contains( "rootMountPoint" ) )
|
||||
{
|
||||
cError() << "No rootMountPoint defined.";
|
||||
return Calamares::JobResult::error( 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." ) );
|
||||
return Calamares::JobResult::error(
|
||||
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();
|
||||
}
|
||||
@ -137,7 +161,8 @@ Calamares::JobResult CommandList::run()
|
||||
cError() << "No username defined.";
|
||||
return Calamares::JobResult::error(
|
||||
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
|
||||
|
||||
@ -156,15 +181,18 @@ Calamares::JobResult CommandList::run()
|
||||
shell_cmd << processed_cmd;
|
||||
|
||||
std::chrono::seconds timeout = i->timeout() >= std::chrono::seconds::zero() ? i->timeout() : m_timeout;
|
||||
ProcessResult r = System::runCommand(
|
||||
location, shell_cmd, QString(), QString(), timeout );
|
||||
ProcessResult r = System::runCommand( location, shell_cmd, QString(), QString(), timeout );
|
||||
|
||||
if ( r.getExitCode() != 0 )
|
||||
{
|
||||
if ( suppress_result )
|
||||
{
|
||||
cDebug() << "Error code" << r.getExitCode() << "ignored by CommandList configuration.";
|
||||
}
|
||||
else
|
||||
{
|
||||
return r.explainProcess( processed_cmd, timeout );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,4 +205,4 @@ CommandList::append( const QString& s )
|
||||
append( CommandLine( s, m_timeout ) );
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -35,7 +35,7 @@ namespace CalamaresUtils
|
||||
*/
|
||||
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
|
||||
CommandLine()
|
||||
@ -49,25 +49,16 @@ struct CommandLine : public QPair< QString, std::chrono::seconds >
|
||||
}
|
||||
|
||||
CommandLine( const QString& s, std::chrono::seconds t )
|
||||
: QPair( s, t)
|
||||
: QPair( s, t )
|
||||
{
|
||||
}
|
||||
|
||||
QString command() const
|
||||
{
|
||||
return first;
|
||||
}
|
||||
QString command() const { return first; }
|
||||
|
||||
std::chrono::seconds timeout() const
|
||||
{
|
||||
return second;
|
||||
}
|
||||
std::chrono::seconds timeout() const { return second; }
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return !first.isEmpty();
|
||||
}
|
||||
} ;
|
||||
bool isValid() const { return !first.isEmpty(); }
|
||||
};
|
||||
|
||||
/** @brief Abbreviation, used internally. */
|
||||
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();
|
||||
|
||||
bool doChroot() const
|
||||
{
|
||||
return m_doChroot;
|
||||
}
|
||||
bool doChroot() const { return m_doChroot; }
|
||||
|
||||
Calamares::JobResult run();
|
||||
|
||||
using CommandList_t::isEmpty;
|
||||
using CommandList_t::count;
|
||||
using CommandList_t::at;
|
||||
using CommandList_t::cbegin;
|
||||
using CommandList_t::cend;
|
||||
using CommandList_t::const_iterator;
|
||||
using CommandList_t::at;
|
||||
using CommandList_t::count;
|
||||
using CommandList_t::isEmpty;
|
||||
|
||||
protected:
|
||||
using CommandList_t::append;
|
||||
@ -109,7 +97,7 @@ protected:
|
||||
private:
|
||||
bool m_doChroot;
|
||||
std::chrono::seconds m_timeout;
|
||||
} ;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
#endif
|
||||
|
@ -101,16 +101,24 @@ mungeEnvironment( QStringList& l, const char* name, const char* defaultDirs )
|
||||
|
||||
QStringList dirs = QString( qgetenv( name ) ).split( ':' );
|
||||
if ( dirs.isEmpty() )
|
||||
{
|
||||
dirs = QString( defaultDirs ).split( ':' );
|
||||
}
|
||||
|
||||
for ( auto s : dirs )
|
||||
{
|
||||
if ( s.isEmpty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( s.endsWith( '/' ) )
|
||||
{
|
||||
l << ( s + calamaresSubdir ) << s;
|
||||
}
|
||||
else
|
||||
{
|
||||
l << ( s + '/' + calamaresSubdir ) << ( s + '/' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +135,9 @@ QStringList
|
||||
extraConfigDirs()
|
||||
{
|
||||
if ( s_haveExtraDirs )
|
||||
{
|
||||
return s_extraConfigDirs;
|
||||
}
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
@ -135,7 +145,9 @@ QStringList
|
||||
extraDataDirs()
|
||||
{
|
||||
if ( s_haveExtraDirs )
|
||||
{
|
||||
return s_extraDataDirs;
|
||||
}
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
@ -173,12 +185,16 @@ appLogDir()
|
||||
QString path = QStandardPaths::writableLocation( QStandardPaths::CacheLocation );
|
||||
QDir dir( path );
|
||||
if ( isWritableDir( dir ) )
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
|
||||
cerr << "warning: Could not find a standard writable location for log dir, falling back to $HOME\n";
|
||||
dir = QDir::home();
|
||||
if ( isWritableDir( dir ) )
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
|
||||
cerr << "warning: Found no writable location for log dir, falling back to the temp dir\n";
|
||||
return QDir::temp();
|
||||
@ -191,4 +207,4 @@ setQmlModulesDir( const QDir& dir )
|
||||
s_qmlModulesDir = dir;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -31,43 +31,43 @@
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
DLLEXPORT QDir qmlModulesDir();
|
||||
DLLEXPORT QDir qmlModulesDir();
|
||||
|
||||
/**
|
||||
* @brief appDataDir returns the directory with common application data.
|
||||
* Defaults to CMAKE_INSTALL_FULL_DATADIR (usually /usr/share/calamares).
|
||||
*/
|
||||
DLLEXPORT QDir appDataDir();
|
||||
/**
|
||||
* @brief appDataDir returns the directory with common application data.
|
||||
* Defaults to CMAKE_INSTALL_FULL_DATADIR (usually /usr/share/calamares).
|
||||
*/
|
||||
DLLEXPORT QDir appDataDir();
|
||||
|
||||
/**
|
||||
* @brief appLogDir returns the directory for Calamares logs.
|
||||
* Defaults to QStandardPaths::CacheLocation (usually ~/.cache/Calamares).
|
||||
*/
|
||||
DLLEXPORT QDir appLogDir();
|
||||
/**
|
||||
* @brief appLogDir returns the directory for Calamares logs.
|
||||
* Defaults to QStandardPaths::CacheLocation (usually ~/.cache/Calamares).
|
||||
*/
|
||||
DLLEXPORT QDir appLogDir();
|
||||
|
||||
/**
|
||||
* @brief systemLibDir returns the system's lib directory.
|
||||
* Defaults to CMAKE_INSTALL_FULL_LIBDIR (usually /usr/lib64 or /usr/lib).
|
||||
*/
|
||||
DLLEXPORT QDir systemLibDir();
|
||||
/**
|
||||
* @brief systemLibDir returns the system's lib directory.
|
||||
* Defaults to CMAKE_INSTALL_FULL_LIBDIR (usually /usr/lib64 or /usr/lib).
|
||||
*/
|
||||
DLLEXPORT QDir systemLibDir();
|
||||
|
||||
/**
|
||||
* Override app data dir. Only for testing purposes.
|
||||
*/
|
||||
DLLEXPORT void setAppDataDir( const QDir& dir );
|
||||
DLLEXPORT bool isAppDataDirOverridden();
|
||||
/**
|
||||
* Override app data dir. Only for testing purposes.
|
||||
*/
|
||||
DLLEXPORT void setAppDataDir( const QDir& dir );
|
||||
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.
|
||||
*/
|
||||
DLLEXPORT void setXdgDirs();
|
||||
/** @brief Are any extra directories configured? */
|
||||
DLLEXPORT bool haveExtraDirs();
|
||||
/** @brief XDG_CONFIG_DIRS, each guaranteed to end with / */
|
||||
DLLEXPORT QStringList extraConfigDirs();
|
||||
/** @brief XDG_DATA_DIRS, each guaranteed to end with / */
|
||||
DLLEXPORT QStringList extraDataDirs();
|
||||
} // namespace
|
||||
/** @brief Setup extra config and data dirs from the XDG variables.
|
||||
*/
|
||||
DLLEXPORT void setXdgDirs();
|
||||
/** @brief Are any extra directories configured? */
|
||||
DLLEXPORT bool haveExtraDirs();
|
||||
/** @brief XDG_CONFIG_DIRS, each guaranteed to end with / */
|
||||
DLLEXPORT QStringList extraConfigDirs();
|
||||
/** @brief XDG_DATA_DIRS, each guaranteed to end with / */
|
||||
DLLEXPORT QStringList extraDataDirs();
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
@ -30,17 +30,17 @@
|
||||
#include <QTime>
|
||||
#include <QVariant>
|
||||
|
||||
#include "utils/Dirs.h"
|
||||
#include "CalamaresVersion.h"
|
||||
#include "utils/Dirs.h"
|
||||
|
||||
#define LOGFILE_SIZE 1024 * 256
|
||||
|
||||
static std::ofstream logfile;
|
||||
static unsigned int s_threshold =
|
||||
#ifdef QT_NO_DEBUG
|
||||
Logger::LOG_DISABLE;
|
||||
Logger::LOG_DISABLE;
|
||||
#else
|
||||
Logger::LOGEXTRA + 1; // Comparison is < in log() function
|
||||
Logger::LOGEXTRA + 1; // Comparison is < in log() function
|
||||
#endif
|
||||
static QMutex s_mutex;
|
||||
|
||||
@ -48,15 +48,17 @@ namespace Logger
|
||||
{
|
||||
|
||||
void
|
||||
setupLogLevel(unsigned int level)
|
||||
setupLogLevel( unsigned int level )
|
||||
{
|
||||
if ( level > LOGVERBOSE )
|
||||
{
|
||||
level = LOGVERBOSE;
|
||||
}
|
||||
s_threshold = level + 1; // Comparison is < in log() function
|
||||
}
|
||||
|
||||
bool
|
||||
logLevelEnabled(unsigned int level)
|
||||
logLevelEnabled( unsigned int level )
|
||||
{
|
||||
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
|
||||
// logging at exit as Qt tries to use QLocale to format, but QLocale is
|
||||
// on its way out.
|
||||
logfile << QDate::currentDate().toString( Qt::ISODate ).toUtf8().data()
|
||||
<< " - "
|
||||
<< QTime::currentTime().toString().toUtf8().data()
|
||||
<< " [" << QString::number( debugLevel ).toUtf8().data() << "]: "
|
||||
<< msg << std::endl;
|
||||
logfile << QDate::currentDate().toString( Qt::ISODate ).toUtf8().data() << " - "
|
||||
<< QTime::currentTime().toString().toUtf8().data() << " ["
|
||||
<< QString::number( debugLevel ).toUtf8().data() << "]: " << msg << std::endl;
|
||||
|
||||
logfile.flush();
|
||||
}
|
||||
@ -90,9 +90,8 @@ log( const char* msg, unsigned int debugLevel )
|
||||
{
|
||||
QMutexLocker lock( &s_mutex );
|
||||
|
||||
std::cout << QTime::currentTime().toString().toUtf8().data()
|
||||
<< " [" << QString::number( debugLevel ).toUtf8().data() << "]: "
|
||||
<< msg << std::endl;
|
||||
std::cout << QTime::currentTime().toString().toUtf8().data() << " ["
|
||||
<< QString::number( debugLevel ).toUtf8().data() << "]: " << msg << std::endl;
|
||||
std::cout.flush();
|
||||
}
|
||||
}
|
||||
@ -107,21 +106,21 @@ CalamaresLogHandler( QtMsgType type, const QMessageLogContext&, const QString& m
|
||||
const char* message = ba.constData();
|
||||
|
||||
QMutexLocker locker( &s_mutex );
|
||||
switch( type )
|
||||
switch ( type )
|
||||
{
|
||||
case QtDebugMsg:
|
||||
log( message, LOGVERBOSE );
|
||||
break;
|
||||
case QtDebugMsg:
|
||||
log( message, LOGVERBOSE );
|
||||
break;
|
||||
|
||||
case QtInfoMsg:
|
||||
log( message, 1 );
|
||||
break;
|
||||
case QtInfoMsg:
|
||||
log( message, 1 );
|
||||
break;
|
||||
|
||||
case QtCriticalMsg:
|
||||
case QtWarningMsg:
|
||||
case QtFatalMsg:
|
||||
log( message, 0 );
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
case QtWarningMsg:
|
||||
case QtFatalMsg:
|
||||
log( message, 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,11 +160,13 @@ setupLogfile()
|
||||
|
||||
// Lock while (re-)opening the logfile
|
||||
{
|
||||
QMutexLocker lock( &s_mutex );
|
||||
logfile.open( logFile().toLocal8Bit(), std::ios::app );
|
||||
if ( logfile.tellp() )
|
||||
logfile << "\n\n" << std::endl;
|
||||
logfile << "=== START CALAMARES " << CALAMARES_VERSION << std::endl;
|
||||
QMutexLocker lock( &s_mutex );
|
||||
logfile.open( logFile().toLocal8Bit(), std::ios::app );
|
||||
if ( logfile.tellp() )
|
||||
{
|
||||
logfile << "\n\n" << std::endl;
|
||||
}
|
||||
logfile << "=== START CALAMARES " << CALAMARES_VERSION << std::endl;
|
||||
}
|
||||
|
||||
qInstallMessageHandler( CalamaresLogHandler );
|
||||
@ -183,14 +184,13 @@ CLog::~CLog()
|
||||
log( m_msg.toUtf8().data(), m_debugLevel );
|
||||
}
|
||||
|
||||
CDebug::~CDebug()
|
||||
{
|
||||
}
|
||||
CDebug::~CDebug() {}
|
||||
|
||||
const char Continuation[] = "\n ";
|
||||
const char SubEntry[] = " .. ";
|
||||
|
||||
QString toString( const QVariant& v )
|
||||
QString
|
||||
toString( const QVariant& v )
|
||||
{
|
||||
auto t = v.type();
|
||||
|
||||
@ -199,11 +199,15 @@ QString toString( const QVariant& v )
|
||||
QStringList s;
|
||||
auto l = v.toList();
|
||||
for ( auto lit = l.constBegin(); lit != l.constEnd(); ++lit )
|
||||
{
|
||||
s << lit->toString();
|
||||
return s.join(", ");
|
||||
}
|
||||
return s.join( ", " );
|
||||
}
|
||||
else
|
||||
{
|
||||
return v.toString();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Logger
|
||||
|
@ -27,169 +27,181 @@
|
||||
|
||||
namespace Logger
|
||||
{
|
||||
DLLEXPORT extern const char Continuation[];
|
||||
DLLEXPORT extern const char SubEntry[];
|
||||
DLLEXPORT extern const char Continuation[];
|
||||
DLLEXPORT extern const char SubEntry[];
|
||||
|
||||
enum
|
||||
enum
|
||||
{
|
||||
LOG_DISABLE = 0,
|
||||
LOGERROR = 1,
|
||||
LOGWARNING = 2,
|
||||
LOGINFO = 3,
|
||||
LOGEXTRA = 5,
|
||||
LOGDEBUG = 6,
|
||||
LOGVERBOSE = 8
|
||||
};
|
||||
|
||||
class DLLEXPORT CLog : public QDebug
|
||||
{
|
||||
public:
|
||||
explicit CLog( unsigned int debugLevel );
|
||||
virtual ~CLog();
|
||||
|
||||
private:
|
||||
QString m_msg;
|
||||
unsigned int m_debugLevel;
|
||||
};
|
||||
|
||||
class DLLEXPORT CDebug : public CLog
|
||||
{
|
||||
public:
|
||||
CDebug( unsigned int debugLevel = LOGDEBUG )
|
||||
: CLog( debugLevel )
|
||||
{
|
||||
LOG_DISABLE = 0,
|
||||
LOGERROR = 1,
|
||||
LOGWARNING = 2,
|
||||
LOGINFO = 3,
|
||||
LOGEXTRA = 5,
|
||||
LOGDEBUG = 6,
|
||||
LOGVERBOSE = 8
|
||||
} ;
|
||||
|
||||
class DLLEXPORT CLog : public QDebug
|
||||
{
|
||||
public:
|
||||
explicit CLog( unsigned int debugLevel );
|
||||
virtual ~CLog();
|
||||
|
||||
private:
|
||||
QString m_msg;
|
||||
unsigned int m_debugLevel;
|
||||
};
|
||||
|
||||
class DLLEXPORT CDebug : public CLog
|
||||
{
|
||||
public:
|
||||
CDebug( unsigned int debugLevel = LOGDEBUG ) : CLog( debugLevel )
|
||||
if ( debugLevel <= LOGERROR )
|
||||
{
|
||||
if ( debugLevel <= LOGERROR )
|
||||
*this << "ERROR:";
|
||||
else if ( debugLevel <= LOGWARNING )
|
||||
*this << "WARNING:";
|
||||
*this << "ERROR:";
|
||||
}
|
||||
virtual ~CDebug();
|
||||
};
|
||||
else if ( debugLevel <= LOGWARNING )
|
||||
{
|
||||
*this << "WARNING:";
|
||||
}
|
||||
}
|
||||
virtual ~CDebug();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The full path of the log file.
|
||||
*/
|
||||
DLLEXPORT QString logFile();
|
||||
/**
|
||||
* @brief The full path of the log file.
|
||||
*/
|
||||
DLLEXPORT QString logFile();
|
||||
|
||||
/**
|
||||
* @brief Start logging to the log file.
|
||||
*
|
||||
* Call this (once) to start logging to the log file (usually
|
||||
* ~/.cache/calamares/session.log ). An existing log file is
|
||||
* rolled over if it is too large.
|
||||
*/
|
||||
DLLEXPORT void setupLogfile();
|
||||
/**
|
||||
* @brief Start logging to the log file.
|
||||
*
|
||||
* Call this (once) to start logging to the log file (usually
|
||||
* ~/.cache/calamares/session.log ). An existing log file is
|
||||
* rolled over if it is too large.
|
||||
*/
|
||||
DLLEXPORT void setupLogfile();
|
||||
|
||||
/**
|
||||
* @brief Set a log level for future logging.
|
||||
*
|
||||
* Pass in a value from the LOG* enum, above. Use 0 to
|
||||
* disable logging. Values greater than LOGVERBOSE are
|
||||
* limited to LOGVERBOSE, which will log everything.
|
||||
*
|
||||
* Practical values are 0, 1, 2, and 6.
|
||||
*/
|
||||
DLLEXPORT void setupLogLevel( unsigned int level );
|
||||
/**
|
||||
* @brief Set a log level for future logging.
|
||||
*
|
||||
* Pass in a value from the LOG* enum, above. Use 0 to
|
||||
* disable logging. Values greater than LOGVERBOSE are
|
||||
* limited to LOGVERBOSE, which will log everything.
|
||||
*
|
||||
* Practical values are 0, 1, 2, and 6.
|
||||
*/
|
||||
DLLEXPORT void setupLogLevel( unsigned int level );
|
||||
|
||||
/** @brief Return the configured log-level. */
|
||||
DLLEXPORT unsigned int logLevel();
|
||||
/** @brief Return the configured log-level. */
|
||||
DLLEXPORT unsigned int logLevel();
|
||||
|
||||
/** @brief Would the given @p level really be logged? */
|
||||
DLLEXPORT bool logLevelEnabled( unsigned int level );
|
||||
/** @brief Would the given @p level really be logged? */
|
||||
DLLEXPORT bool logLevelEnabled( unsigned int level );
|
||||
|
||||
/**
|
||||
* @brief Row-oriented formatted logging.
|
||||
*
|
||||
* Use DebugRow to produce multiple rows of 2-column output
|
||||
* in a debugging statement. For instance,
|
||||
* cDebug() << DebugRow<int,int>(1,12)
|
||||
* << DebugRow<int,int>(2,24)
|
||||
* will produce a single timestamped debug line with continuations.
|
||||
* Each DebugRow produces one line of output, with the two values.
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
struct DebugRow
|
||||
/**
|
||||
* @brief Row-oriented formatted logging.
|
||||
*
|
||||
* Use DebugRow to produce multiple rows of 2-column output
|
||||
* in a debugging statement. For instance,
|
||||
* cDebug() << DebugRow<int,int>(1,12)
|
||||
* << DebugRow<int,int>(2,24)
|
||||
* will produce a single timestamped debug line with continuations.
|
||||
* Each DebugRow produces one line of output, with the two values.
|
||||
*/
|
||||
template < typename T, typename U >
|
||||
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 U& second;
|
||||
} ;
|
||||
|
||||
/**
|
||||
* @brief List-oriented formatted logging.
|
||||
*
|
||||
* Use DebugList to produce multiple rows of output in a debugging
|
||||
* statement. For instance,
|
||||
* cDebug() << DebugList( QStringList() << "foo" << "bar" )
|
||||
* will produce a single timestamped debug line with continuations.
|
||||
* Each element of the list of strings will be logged on a separate line.
|
||||
*/
|
||||
struct DebugList
|
||||
{
|
||||
explicit DebugList( const QStringList& l )
|
||||
: list(l)
|
||||
{}
|
||||
|
||||
const QStringList& list;
|
||||
} ;
|
||||
|
||||
/**
|
||||
* @brief Map-oriented formatted logging.
|
||||
*
|
||||
* Use DebugMap to produce multiple rows of output in a debugging
|
||||
* statement from a map. The output is intentionally a bit-yaml-ish.
|
||||
* cDebug() << DebugMap( map )
|
||||
* will produce a single timestamped debug line with continuations.
|
||||
* The continued lines will have a key (from the map) and a value
|
||||
* on each line.
|
||||
*/
|
||||
struct DebugMap
|
||||
{
|
||||
public:
|
||||
explicit DebugMap(const QVariantMap& m)
|
||||
: map( m )
|
||||
{}
|
||||
|
||||
const QVariantMap& map;
|
||||
} ;
|
||||
|
||||
/** @brief output operator for DebugRow */
|
||||
template<typename T, typename U>
|
||||
inline QDebug&
|
||||
operator <<( QDebug& s, const DebugRow<T, U>& t )
|
||||
{
|
||||
s << Continuation << t.first << ':' << ' ' << t.second;
|
||||
return s;
|
||||
}
|
||||
|
||||
/** @brief output operator for DebugList */
|
||||
inline QDebug&
|
||||
operator <<( QDebug& s, const DebugList& c )
|
||||
const T& first;
|
||||
const U& second;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief List-oriented formatted logging.
|
||||
*
|
||||
* Use DebugList to produce multiple rows of output in a debugging
|
||||
* statement. For instance,
|
||||
* cDebug() << DebugList( QStringList() << "foo" << "bar" )
|
||||
* will produce a single timestamped debug line with continuations.
|
||||
* Each element of the list of strings will be logged on a separate line.
|
||||
*/
|
||||
struct DebugList
|
||||
{
|
||||
explicit DebugList( const QStringList& l )
|
||||
: list( l )
|
||||
{
|
||||
for( const auto& i : c.list )
|
||||
s << Continuation << i;
|
||||
return s;
|
||||
}
|
||||
|
||||
/** @brief supporting method for outputting a DebugMap */
|
||||
QString toString( const QVariant& v );
|
||||
const QStringList& list;
|
||||
};
|
||||
|
||||
/** @brief output operator for DebugMap */
|
||||
inline QDebug&
|
||||
operator <<( QDebug& s, const DebugMap& t )
|
||||
/**
|
||||
* @brief Map-oriented formatted logging.
|
||||
*
|
||||
* Use DebugMap to produce multiple rows of output in a debugging
|
||||
* statement from a map. The output is intentionally a bit-yaml-ish.
|
||||
* cDebug() << DebugMap( map )
|
||||
* will produce a single timestamped debug line with continuations.
|
||||
* The continued lines will have a key (from the map) and a value
|
||||
* on each line.
|
||||
*/
|
||||
struct DebugMap
|
||||
{
|
||||
public:
|
||||
explicit DebugMap( const QVariantMap& m )
|
||||
: map( m )
|
||||
{
|
||||
for ( auto it = t.map.constBegin(); it != t.map.constEnd(); ++it )
|
||||
s << Continuation << it.key().toUtf8().constData() << ':' << ' ' << toString( it.value() ).toUtf8().constData();
|
||||
return s;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const QVariantMap& map;
|
||||
};
|
||||
|
||||
/** @brief output operator for DebugRow */
|
||||
template < typename T, typename U >
|
||||
inline QDebug&
|
||||
operator<<( QDebug& s, const DebugRow< T, U >& t )
|
||||
{
|
||||
s << Continuation << t.first << ':' << ' ' << t.second;
|
||||
return s;
|
||||
}
|
||||
|
||||
/** @brief output operator for DebugList */
|
||||
inline QDebug&
|
||||
operator<<( QDebug& s, const DebugList& c )
|
||||
{
|
||||
for ( const auto& i : c.list )
|
||||
{
|
||||
s << Continuation << i;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/** @brief supporting method for outputting a DebugMap */
|
||||
QString toString( const QVariant& v );
|
||||
|
||||
/** @brief output operator for DebugMap */
|
||||
inline QDebug&
|
||||
operator<<( QDebug& s, const DebugMap& t )
|
||||
{
|
||||
for ( auto it = t.map.constBegin(); it != t.map.constEnd(); ++it )
|
||||
{
|
||||
s << Continuation << it.key().toUtf8().constData() << ':' << ' ' << toString( it.value() ).toUtf8().constData();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
} // namespace Logger
|
||||
|
||||
#define cDebug Logger::CDebug
|
||||
#define cWarning() Logger::CDebug(Logger::LOGWARNING)
|
||||
#define cError() Logger::CDebug(Logger::LOGERROR)
|
||||
#define cWarning() Logger::CDebug( Logger::LOGWARNING )
|
||||
#define cError() Logger::CDebug( Logger::LOGERROR )
|
||||
|
||||
#endif
|
||||
|
@ -31,12 +31,12 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
/** @brief Type for collecting parts of a named enum. */
|
||||
template<typename T>
|
||||
template < typename T >
|
||||
struct NamedEnumTable
|
||||
{
|
||||
using string_t = QString;
|
||||
@ -53,7 +53,11 @@ struct NamedEnumTable
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
@ -89,8 +93,8 @@ struct NamedEnumTable
|
||||
{
|
||||
ok = false;
|
||||
|
||||
for ( const auto &p : table )
|
||||
if ( s == p.second)
|
||||
for ( const auto& p : table )
|
||||
if ( s == p.second )
|
||||
{
|
||||
ok = true;
|
||||
return p.first;
|
||||
@ -99,13 +103,14 @@ struct NamedEnumTable
|
||||
// ok is still false
|
||||
return string_t();
|
||||
}
|
||||
} ;
|
||||
};
|
||||
|
||||
/** @brief Smashes an enum value to its underlying type. */
|
||||
template<typename E>
|
||||
constexpr typename std::underlying_type<E>::type smash( const E e )
|
||||
template < typename 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
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "NamedEnum.h"
|
||||
|
||||
/** @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
|
||||
{
|
||||
public:
|
||||
@ -52,7 +52,7 @@ public:
|
||||
|
||||
/** @brief Empty value. */
|
||||
NamedSuffix()
|
||||
: m_value(0)
|
||||
: m_value( 0 )
|
||||
, m_unit( none )
|
||||
{
|
||||
}
|
||||
@ -69,10 +69,10 @@ public:
|
||||
* This parses the given string @p s by comparing with the suffixes
|
||||
* 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()
|
||||
{
|
||||
for( const auto& suffix : table.table )
|
||||
for ( const auto& suffix : table.table )
|
||||
if ( s.endsWith( suffix.first ) )
|
||||
{
|
||||
m_value = s.left( s.length() - suffix.first.length() ).toInt();
|
||||
|
@ -24,8 +24,11 @@
|
||||
#include "PluginFactory.h"
|
||||
#include "PluginFactory_p.h"
|
||||
|
||||
#include <QObjectCleanupHandler>
|
||||
#include <QDebug>
|
||||
#include <QObjectCleanupHandler>
|
||||
|
||||
// *INDENT-OFF*
|
||||
// clang-format off
|
||||
|
||||
Q_GLOBAL_STATIC( QObjectCleanupHandler, factorycleanup )
|
||||
|
||||
|
@ -27,8 +27,11 @@
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
// *INDENT-OFF*
|
||||
// clang-format off
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
@ -32,23 +32,24 @@ namespace Calamares
|
||||
|
||||
class PluginFactoryPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(PluginFactory)
|
||||
Q_DECLARE_PUBLIC( PluginFactory )
|
||||
protected:
|
||||
typedef QPair<const QMetaObject *, PluginFactory::CreateInstanceFunction> Plugin;
|
||||
typedef QPair< const QMetaObject*, PluginFactory::CreateInstanceFunction > Plugin;
|
||||
|
||||
PluginFactoryPrivate()
|
||||
: catalogInitialized( false )
|
||||
, q_ptr( nullptr )
|
||||
{}
|
||||
{
|
||||
}
|
||||
~PluginFactoryPrivate() {}
|
||||
|
||||
QHash<QString, Plugin> createInstanceHash;
|
||||
QHash< QString, Plugin > createInstanceHash;
|
||||
QString catalogName;
|
||||
bool catalogInitialized;
|
||||
|
||||
PluginFactory *q_ptr;
|
||||
PluginFactory* q_ptr;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Calamares
|
||||
|
||||
#endif
|
||||
|
@ -26,27 +26,30 @@
|
||||
#include <QTranslator>
|
||||
|
||||
|
||||
namespace CalamaresUtils {
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
static QTranslator* s_brandingTranslator = nullptr;
|
||||
static QTranslator* s_translator = nullptr;
|
||||
static QString s_translatorLocaleName;
|
||||
|
||||
void
|
||||
installTranslator( const QLocale& locale,
|
||||
const QString& brandingTranslationsPrefix,
|
||||
QObject* parent )
|
||||
installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* parent )
|
||||
{
|
||||
QString localeName = locale.name();
|
||||
localeName.replace( "-", "_" );
|
||||
|
||||
if ( localeName == "C" )
|
||||
{
|
||||
localeName = "en";
|
||||
}
|
||||
|
||||
// Special case of sr@latin
|
||||
//
|
||||
// See top-level CMakeLists.txt about special cases for translation loading.
|
||||
if ( locale.language() == QLocale::Language::Serbian && locale.script() == QLocale::Script::LatinScript )
|
||||
{
|
||||
localeName = QStringLiteral( "sr@latin" );
|
||||
}
|
||||
|
||||
cDebug() << "Looking for translations for" << localeName;
|
||||
|
||||
@ -56,19 +59,14 @@ installTranslator( const QLocale& locale,
|
||||
if ( !brandingTranslationsPrefix.isEmpty() )
|
||||
{
|
||||
QString brandingTranslationsDirPath( brandingTranslationsPrefix );
|
||||
brandingTranslationsDirPath.truncate( brandingTranslationsPrefix.lastIndexOf(
|
||||
QDir::separator() ) );
|
||||
brandingTranslationsDirPath.truncate( brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) );
|
||||
QDir brandingTranslationsDir( brandingTranslationsDirPath );
|
||||
if ( brandingTranslationsDir.exists() )
|
||||
{
|
||||
QString filenameBase( brandingTranslationsPrefix );
|
||||
filenameBase.remove( 0, brandingTranslationsPrefix.lastIndexOf(
|
||||
QDir::separator() ) + 1 );
|
||||
filenameBase.remove( 0, brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) + 1 );
|
||||
translator = new QTranslator( parent );
|
||||
if ( translator->load( locale,
|
||||
filenameBase,
|
||||
"_",
|
||||
brandingTranslationsDir.absolutePath() ) )
|
||||
if ( translator->load( locale, filenameBase, "_", brandingTranslationsDir.absolutePath() ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Branding using locale:" << localeName;
|
||||
}
|
||||
@ -121,19 +119,22 @@ translatorLocaleName()
|
||||
}
|
||||
|
||||
void
|
||||
Retranslator::attachRetranslator( QObject* parent,
|
||||
std::function< void ( void ) > retranslateFunc )
|
||||
Retranslator::attachRetranslator( QObject* parent, std::function< void( void ) > retranslateFunc )
|
||||
{
|
||||
Retranslator* r = nullptr;
|
||||
for ( QObject* child : parent->children() )
|
||||
{
|
||||
r = qobject_cast< Retranslator* >( child );
|
||||
if ( r )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !r )
|
||||
{
|
||||
r = new Retranslator( parent );
|
||||
}
|
||||
|
||||
r->m_retranslateFuncList.append( retranslateFunc );
|
||||
retranslateFunc();
|
||||
@ -155,7 +156,9 @@ Retranslator::eventFilter( QObject* obj, QEvent* e )
|
||||
if ( e->type() == QEvent::LanguageChange )
|
||||
{
|
||||
foreach ( std::function< void() > func, m_retranslateFuncList )
|
||||
{
|
||||
func();
|
||||
}
|
||||
}
|
||||
}
|
||||
// pass the event on to the base
|
||||
@ -163,4 +166,4 @@ Retranslator::eventFilter( QObject* obj, QEvent* e )
|
||||
}
|
||||
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -32,24 +32,21 @@ class QLocale;
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
/**
|
||||
* @brief installTranslator changes the application language.
|
||||
* @param locale the new locale.
|
||||
* @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding.
|
||||
* @param parent the parent QObject.
|
||||
*/
|
||||
DLLEXPORT void installTranslator( const QLocale& locale,
|
||||
const QString& brandingTranslationsPrefix,
|
||||
QObject* parent );
|
||||
/**
|
||||
* @brief installTranslator changes the application language.
|
||||
* @param locale the new locale.
|
||||
* @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding.
|
||||
* @param parent the parent QObject.
|
||||
*/
|
||||
DLLEXPORT void installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* parent );
|
||||
|
||||
DLLEXPORT QString translatorLocaleName();
|
||||
DLLEXPORT QString translatorLocaleName();
|
||||
|
||||
class Retranslator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static void attachRetranslator( QObject* parent,
|
||||
std::function< void( void ) > retranslateFunc );
|
||||
static void attachRetranslator( QObject* parent, std::function< void( void ) > retranslateFunc );
|
||||
|
||||
void addRetranslateFunc( std::function< void( void ) > retranslateFunc );
|
||||
|
||||
@ -63,11 +60,10 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#define CALAMARES_RETRANSLATE(body) \
|
||||
CalamaresUtils::Retranslator::attachRetranslator( this, [=] { body } );
|
||||
#define CALAMARES_RETRANSLATE_WIDGET(widget,body) \
|
||||
#define CALAMARES_RETRANSLATE( body ) CalamaresUtils::Retranslator::attachRetranslator( this, [=] { body } );
|
||||
#define CALAMARES_RETRANSLATE_WIDGET( widget, body ) \
|
||||
CalamaresUtils::Retranslator::attachRetranslator( widget, [=] { body } );
|
||||
|
||||
#endif
|
||||
|
@ -31,6 +31,11 @@ namespace CalamaresUtils
|
||||
QString
|
||||
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(
|
||||
"ŠŒŽšœžŸ¥µÀ"
|
||||
"ÁÂÃÄÅÆÇÈÉÊ"
|
||||
@ -65,9 +70,11 @@ removeDiacritics( const QString& string )
|
||||
"r", "A", "a", "E", "e", "L", "l", "N", "n", "S",
|
||||
"s", "Z", "z", "Z", "z"
|
||||
};
|
||||
// clang-format on
|
||||
// *INDENT-ON*
|
||||
|
||||
QString output;
|
||||
for ( const QChar &c : string )
|
||||
for ( const QChar& c : string )
|
||||
{
|
||||
int i = diacriticLetters.indexOf( c );
|
||||
if ( i < 0 )
|
||||
@ -112,14 +119,14 @@ QString
|
||||
obscure( const QString& string )
|
||||
{
|
||||
QString result;
|
||||
const QChar *unicode = string.unicode();
|
||||
const QChar* unicode = string.unicode();
|
||||
for ( int i = 0; i < string.length(); ++i )
|
||||
// yes, no typo. can't encode ' ' or '!' because
|
||||
// they're the unicode BOM. stupid scrambling. stupid.
|
||||
result += ( unicode[ i ].unicode() <= 0x21 ) ?
|
||||
unicode[ i ] :
|
||||
QChar( 0x1001F - unicode[ i ].unicode() );
|
||||
// yes, no typo. can't encode ' ' or '!' because
|
||||
// they're the unicode BOM. stupid scrambling. stupid.
|
||||
{
|
||||
result += ( unicode[ i ].unicode() <= 0x21 ) ? unicode[ i ] : QChar( 0x1001F - unicode[ i ].unicode() );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -34,20 +34,20 @@
|
||||
*/
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
/**
|
||||
* @brief removeDiacritics replaces letters with diacritics and ligatures with
|
||||
* alternative forms and digraphs.
|
||||
* @param string the string to transform.
|
||||
* @return the output string with plain characters.
|
||||
*/
|
||||
DLLEXPORT QString removeDiacritics( const QString& string );
|
||||
/**
|
||||
* @brief removeDiacritics replaces letters with diacritics and ligatures with
|
||||
* alternative forms and digraphs.
|
||||
* @param string the string to transform.
|
||||
* @return the output string with plain characters.
|
||||
*/
|
||||
DLLEXPORT QString removeDiacritics( const QString& string );
|
||||
|
||||
/**
|
||||
* @brief obscure is a bidirectional obfuscation function, from KStringHandler.
|
||||
* @param string the input string.
|
||||
* @return the obfuscated string.
|
||||
*/
|
||||
DLLEXPORT QString obscure( const QString& string );
|
||||
} // namespace
|
||||
/**
|
||||
* @brief obscure is a bidirectional obfuscation function, from KStringHandler.
|
||||
* @param string the input string.
|
||||
* @return the obfuscated string.
|
||||
*/
|
||||
DLLEXPORT QString obscure( const QString& string );
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
||||
|
@ -26,76 +26,88 @@ namespace CalamaresUtils
|
||||
{
|
||||
|
||||
/** 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) */
|
||||
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) */
|
||||
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 );
|
||||
}
|
||||
|
||||
constexpr int BytesToGiB( qint64 b )
|
||||
constexpr int
|
||||
BytesToGiB( qint64 b )
|
||||
{
|
||||
return int( b / 1024 / 1024 / 1024 );
|
||||
}
|
||||
|
||||
constexpr qint64 alignBytesToBlockSize( qint64 bytes, qint64 blocksize )
|
||||
constexpr qint64
|
||||
alignBytesToBlockSize( qint64 bytes, qint64 blocksize )
|
||||
{
|
||||
qint64 blocks = bytes / blocksize;
|
||||
|
||||
if ( blocks * blocksize != bytes )
|
||||
{
|
||||
++blocks;
|
||||
}
|
||||
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
|
||||
|
@ -39,20 +39,24 @@ getBool( const QVariantMap& map, const QString& key, bool d )
|
||||
{
|
||||
auto v = map.value( key );
|
||||
if ( v.type() == QVariant::Bool )
|
||||
{
|
||||
result = v.toBool();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString
|
||||
getString(const QVariantMap& map, const QString& key)
|
||||
getString( const QVariantMap& map, const QString& key )
|
||||
{
|
||||
if ( map.contains( key ) )
|
||||
{
|
||||
auto v = map.value( key );
|
||||
if ( v.type() == QVariant::String )
|
||||
{
|
||||
return v.toString();
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
@ -65,7 +69,9 @@ getInteger( const QVariantMap& map, const QString& key, int d )
|
||||
{
|
||||
auto v = map.value( key );
|
||||
if ( v.type() == QVariant::Int )
|
||||
{
|
||||
result = v.toInt();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -79,9 +85,13 @@ getDouble( const QVariantMap& map, const QString& key, double d )
|
||||
{
|
||||
auto v = map.value( key );
|
||||
if ( v.type() == QVariant::Int )
|
||||
{
|
||||
result = v.toInt();
|
||||
}
|
||||
else if ( v.type() == QVariant::Double )
|
||||
{
|
||||
result = v.toDouble();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -104,4 +114,4 @@ getSubMap( const QVariantMap& map, const QString& key, bool& success )
|
||||
return QVariantMap();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -27,36 +27,36 @@
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
/**
|
||||
* Get a bool value from a mapping with a given key; returns the default
|
||||
* if no value is stored in the map.
|
||||
*/
|
||||
DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d );
|
||||
/**
|
||||
* Get a bool value from a mapping with a given key; returns the default
|
||||
* if no value is stored in the map.
|
||||
*/
|
||||
DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d );
|
||||
|
||||
/**
|
||||
* Get a string value from a mapping; returns empty QString if no value.
|
||||
*/
|
||||
DLLEXPORT QString getString( const QVariantMap& map, const QString& key );
|
||||
/**
|
||||
* Get a string value from a mapping; returns empty QString if no value.
|
||||
*/
|
||||
DLLEXPORT QString getString( const QVariantMap& map, const QString& key );
|
||||
|
||||
/**
|
||||
* Get an integer value from a mapping; returns @p d if no value.
|
||||
*/
|
||||
DLLEXPORT int getInteger( const QVariantMap& map, const QString& key, int d );
|
||||
/**
|
||||
* Get an integer value from a mapping; returns @p d if no value.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
DLLEXPORT double getDouble( const QVariantMap& map, const QString& key, double d );
|
||||
/**
|
||||
* 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 );
|
||||
|
||||
/**
|
||||
* 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
|
||||
* in @p map and converts to a map, false otherwise.
|
||||
*
|
||||
* Returns an empty map if there is no such key or it is not a map-value.
|
||||
* (e.g. if @p success is false).
|
||||
*/
|
||||
DLLEXPORT QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success );
|
||||
} // namespace
|
||||
/**
|
||||
* 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
|
||||
* in @p map and converts to a map, false otherwise.
|
||||
*
|
||||
* Returns an empty map if there is no such key or it is not a map-value.
|
||||
* (e.g. if @p success is false).
|
||||
*/
|
||||
DLLEXPORT QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success );
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
||||
|
@ -70,13 +70,21 @@ yamlScalarToVariant( const YAML::Node& scalarNode )
|
||||
std::string stdScalar = scalarNode.as< std::string >();
|
||||
QString scalarString = QString::fromStdString( stdScalar );
|
||||
if ( _yamlScalarTrueValues.exactMatch( scalarString ) )
|
||||
{
|
||||
return QVariant( true );
|
||||
}
|
||||
if ( _yamlScalarFalseValues.exactMatch( scalarString ) )
|
||||
{
|
||||
return QVariant( false );
|
||||
}
|
||||
if ( QRegExp( "[-+]?\\d+" ).exactMatch( scalarString ) )
|
||||
{
|
||||
return QVariant( scalarString.toInt() );
|
||||
}
|
||||
if ( QRegExp( "[-+]?\\d*\\.?\\d+" ).exactMatch( scalarString ) )
|
||||
{
|
||||
return QVariant( scalarString.toDouble() );
|
||||
}
|
||||
return QVariant( scalarString );
|
||||
}
|
||||
|
||||
@ -85,8 +93,7 @@ QVariant
|
||||
yamlSequenceToVariant( const YAML::Node& sequenceNode )
|
||||
{
|
||||
QVariantList vl;
|
||||
for ( YAML::const_iterator it = sequenceNode.begin();
|
||||
it != sequenceNode.end(); ++it )
|
||||
for ( YAML::const_iterator it = sequenceNode.begin(); it != sequenceNode.end(); ++it )
|
||||
{
|
||||
vl << yamlToVariant( *it );
|
||||
}
|
||||
@ -98,17 +105,15 @@ QVariant
|
||||
yamlMapToVariant( const YAML::Node& mapNode )
|
||||
{
|
||||
QVariantMap vm;
|
||||
for ( YAML::const_iterator it = mapNode.begin();
|
||||
it != mapNode.end(); ++it )
|
||||
for ( YAML::const_iterator it = mapNode.begin(); it != mapNode.end(); ++it )
|
||||
{
|
||||
vm.insert( QString::fromStdString( it->first.as< std::string >() ),
|
||||
yamlToVariant( it->second ) );
|
||||
vm.insert( QString::fromStdString( it->first.as< std::string >() ), yamlToVariant( it->second ) );
|
||||
}
|
||||
return vm;
|
||||
}
|
||||
|
||||
QStringList
|
||||
yamlToStringList(const YAML::Node& listNode)
|
||||
yamlToStringList( const YAML::Node& listNode )
|
||||
{
|
||||
QStringList l;
|
||||
listNode >> l;
|
||||
@ -117,7 +122,7 @@ yamlToStringList(const YAML::Node& listNode)
|
||||
|
||||
|
||||
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 << '.';
|
||||
explainYamlException( e, yamlData );
|
||||
@ -142,7 +147,9 @@ explainYamlException( const YAML::Exception& e, const QByteArray& yamlData )
|
||||
linestart = yamlData.indexOf( '\n', linestart );
|
||||
// No more \ns found, weird
|
||||
if ( linestart < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
linestart += 1; // Skip that \n
|
||||
}
|
||||
int lineend = linestart;
|
||||
@ -150,34 +157,43 @@ explainYamlException( const YAML::Exception& e, const QByteArray& yamlData )
|
||||
{
|
||||
lineend = yamlData.indexOf( '\n', linestart );
|
||||
if ( lineend < 0 )
|
||||
{
|
||||
lineend = yamlData.length();
|
||||
}
|
||||
}
|
||||
|
||||
int rangestart = linestart;
|
||||
int rangeend = lineend;
|
||||
// Adjust range (linestart..lineend) so it's not too long
|
||||
if ( ( linestart >= 0 ) && ( e.mark.column > 30 ) )
|
||||
{
|
||||
rangestart += ( e.mark.column - 30 );
|
||||
}
|
||||
if ( ( linestart >= 0 ) && ( rangeend - rangestart > 40 ) )
|
||||
{
|
||||
rangeend = rangestart + 40;
|
||||
}
|
||||
|
||||
if ( linestart >= 0 )
|
||||
cWarning() << "offending YAML data:" << yamlData.mid( rangestart, rangeend-rangestart ).constData();
|
||||
|
||||
{
|
||||
cWarning() << "offending YAML data:" << yamlData.mid( rangestart, rangeend - rangestart ).constData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap
|
||||
loadYaml(const QFileInfo& fi, bool* ok)
|
||||
loadYaml( const QFileInfo& fi, bool* ok )
|
||||
{
|
||||
return loadYaml( fi.absoluteFilePath(), ok );
|
||||
}
|
||||
|
||||
QVariantMap
|
||||
loadYaml(const QString& filename, bool* ok)
|
||||
loadYaml( const QString& filename, bool* ok )
|
||||
{
|
||||
if ( ok )
|
||||
{
|
||||
*ok = false;
|
||||
}
|
||||
|
||||
QFile yamlFile( filename );
|
||||
QVariant yamlContents;
|
||||
@ -197,12 +213,12 @@ loadYaml(const QString& filename, bool* ok)
|
||||
}
|
||||
|
||||
|
||||
if ( yamlContents.isValid() &&
|
||||
!yamlContents.isNull() &&
|
||||
yamlContents.type() == QVariant::Map )
|
||||
if ( yamlContents.isValid() && !yamlContents.isNull() && yamlContents.type() == QVariant::Map )
|
||||
{
|
||||
if ( ok )
|
||||
{
|
||||
*ok = true;
|
||||
}
|
||||
return yamlContents.toMap();
|
||||
}
|
||||
|
||||
@ -214,7 +230,9 @@ static void
|
||||
writeIndent( QFile& f, int indent )
|
||||
{
|
||||
while ( indent-- > 0 )
|
||||
{
|
||||
f.write( " " );
|
||||
}
|
||||
}
|
||||
|
||||
// forward declaration
|
||||
@ -229,7 +247,9 @@ static void
|
||||
dumpYamlElement( QFile& f, const QVariant& value, int indent )
|
||||
{
|
||||
if ( value.type() == QVariant::Type::Bool )
|
||||
{
|
||||
f.write( value.toBool() ? "true" : "false" );
|
||||
}
|
||||
else if ( value.type() == QVariant::Type::String )
|
||||
{
|
||||
f.write( quote );
|
||||
@ -251,17 +271,19 @@ dumpYamlElement( QFile& f, const QVariant& value, int indent )
|
||||
{
|
||||
++c;
|
||||
f.write( newline );
|
||||
writeIndent( f, indent+1 );
|
||||
writeIndent( f, indent + 1 );
|
||||
f.write( "- " );
|
||||
dumpYamlElement( f, it, indent+1 );
|
||||
dumpYamlElement( f, it, indent + 1 );
|
||||
}
|
||||
if ( !c ) // i.e. list was empty
|
||||
{
|
||||
f.write( "[]" );
|
||||
}
|
||||
}
|
||||
else if ( value.type() == QVariant::Type::Map )
|
||||
{
|
||||
f.write( newline );
|
||||
dumpYaml( f, value.toMap(), indent+1 );
|
||||
dumpYaml( f, value.toMap(), indent + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -293,12 +315,13 @@ saveYaml( const QString& filename, const QVariantMap& map )
|
||||
{
|
||||
QFile f( filename );
|
||||
if ( !f.open( QFile::WriteOnly ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
f.write( "# YAML dump\n---\n" );
|
||||
return dumpYaml( f, map, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -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.
|
||||
* 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 );
|
||||
|
||||
} // namespace
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user