don't use ALPM
This commit is contained in:
parent
69b0d7e258
commit
1d6761ddd8
|
@ -4,11 +4,9 @@ cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
|
||||||
set(HEADER_FILES
|
set(HEADER_FILES
|
||||||
alpm/manager.h
|
alpm/manager.h
|
||||||
alpm/package.h
|
alpm/package.h
|
||||||
alpm/list.h
|
|
||||||
alpm/utilities.h
|
alpm/utilities.h
|
||||||
network/server.h
|
network/server.h
|
||||||
network/connection.h
|
network/connection.h
|
||||||
alpm/group.h
|
|
||||||
alpm/config.h
|
alpm/config.h
|
||||||
alpm/resolvebuildorder.h
|
alpm/resolvebuildorder.h
|
||||||
alpm/mingwbundle.h
|
alpm/mingwbundle.h
|
||||||
|
@ -28,7 +26,6 @@ set(SRC_FILES
|
||||||
alpm/manager.cpp
|
alpm/manager.cpp
|
||||||
alpm/package.cpp
|
alpm/package.cpp
|
||||||
alpm/utilities.cpp
|
alpm/utilities.cpp
|
||||||
alpm/group.cpp
|
|
||||||
alpm/config.cpp
|
alpm/config.cpp
|
||||||
alpm/resolvebuildorder.cpp
|
alpm/resolvebuildorder.cpp
|
||||||
alpm/mingwbundle.cpp
|
alpm/mingwbundle.cpp
|
||||||
|
@ -85,8 +82,8 @@ set(META_APP_AUTHOR "Martchus")
|
||||||
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
|
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
|
||||||
set(META_APP_DESCRIPTION "Arch Linux repository browser")
|
set(META_APP_DESCRIPTION "Arch Linux repository browser")
|
||||||
set(META_VERSION_MAJOR 0)
|
set(META_VERSION_MAJOR 0)
|
||||||
set(META_VERSION_MINOR 0)
|
set(META_VERSION_MINOR 1)
|
||||||
set(META_VERSION_PATCH 2)
|
set(META_VERSION_PATCH 0)
|
||||||
|
|
||||||
# stringification of meta data
|
# stringification of meta data
|
||||||
set(META_PROJECT_NAME_STR "\"${META_PROJECT_NAME}\"")
|
set(META_PROJECT_NAME_STR "\"${META_PROJECT_NAME}\"")
|
||||||
|
@ -141,7 +138,7 @@ add_definitions(
|
||||||
|
|
||||||
# executable and linking
|
# executable and linking
|
||||||
add_executable(${META_PROJECT_NAME} ${HEADER_FILES} ${SRC_FILES} ${WEB_FILES} ${RES_FILES})
|
add_executable(${META_PROJECT_NAME} ${HEADER_FILES} ${SRC_FILES} ${WEB_FILES} ${RES_FILES})
|
||||||
target_link_libraries(${META_PROJECT_NAME} c++utilities alpm Qt5::Core Qt5::Concurrent Qt5::Network Qt5::WebSockets KF5::Archive)
|
target_link_libraries(${META_PROJECT_NAME} c++utilities Qt5::Core Qt5::Concurrent Qt5::Network Qt5::WebSockets KF5::Archive)
|
||||||
set_target_properties(${META_PROJECT_NAME} PROPERTIES
|
set_target_properties(${META_PROJECT_NAME} PROPERTIES
|
||||||
CXX_STANDARD 11
|
CXX_STANDARD 11
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
#include "./alpmdatabase.h"
|
#include "./alpmdatabase.h"
|
||||||
#include "./group.h"
|
|
||||||
#include "./upgradelookup.h"
|
#include "./upgradelookup.h"
|
||||||
#include "./alpmpackage.h"
|
#include "./alpmpackage.h"
|
||||||
#include "./utilities.h"
|
#include "./utilities.h"
|
||||||
|
|
||||||
#include <c++utilities/misc/memory.h>
|
#include <c++utilities/misc/memory.h>
|
||||||
|
|
||||||
#include <alpm.h>
|
#include <KTar>
|
||||||
|
#include <KArchiveDirectory>
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace RepoIndex {
|
namespace RepoIndex {
|
||||||
|
@ -28,68 +30,134 @@ using namespace Utilities;
|
||||||
class LoadPackage
|
class LoadPackage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LoadPackage(AlpmDatabase *db, QMutex *mutex) :
|
LoadPackage(AlpmDatabase *database, PackageOrigin origin) :
|
||||||
m_db(db),
|
m_db(database),
|
||||||
m_mutex(mutex)
|
m_origin(origin)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void operator()(alpm_pkg_t *pkg)
|
void operator()(const QPair<QString, QList<QByteArray> > &description)
|
||||||
{
|
{
|
||||||
auto res = make_unique<AlpmPackage>(pkg, m_db);
|
m_db->addPackageFromDescription(description.first, description.second, m_origin);
|
||||||
QMutexLocker locker(m_mutex);
|
|
||||||
for(const auto &grpName : res->groups()) {
|
|
||||||
m_db->groups()[grpName] << res.get();
|
|
||||||
}
|
|
||||||
m_db->packages().emplace(res->name(), move(res));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AlpmDatabase *m_db;
|
AlpmDatabase *const m_db;
|
||||||
QMutex *m_mutex;
|
const PackageOrigin m_origin;
|
||||||
};
|
};
|
||||||
|
|
||||||
AlpmPackageLoader::AlpmPackageLoader(AlpmDatabase *repository)
|
void AlpmDatabase::loadDescriptions(QList<QPair<QString, QList<QByteArray> > > &descriptions)
|
||||||
{
|
{
|
||||||
for(auto *pkg : PackageList(alpm_db_get_pkgcache(repository->ptr()))) {
|
QFileInfo pathInfo(databasePath());
|
||||||
m_packages << pkg;
|
if(pathInfo.isDir()) {
|
||||||
|
static const QStringList relevantFiles = QStringList() << QStringLiteral("desc") << QStringLiteral("files");
|
||||||
|
QDir dbDir(databasePath());
|
||||||
|
QStringList pkgDirNames = dbDir.entryList(QDir::Dirs | QDir::Readable | QDir::Executable | QDir::NoDotAndDotDot);
|
||||||
|
descriptions.reserve(pkgDirNames.size());
|
||||||
|
for(QString &pkgDirName : pkgDirNames) {
|
||||||
|
if(dbDir.cd(pkgDirName)) {
|
||||||
|
Utilities::stripVersion(pkgDirName);
|
||||||
|
const QStringList descFileNames = dbDir.entryList(relevantFiles, QDir::Files | QDir::Readable | QDir::NoDotAndDotDot);
|
||||||
|
QList<QByteArray> descData;
|
||||||
|
descData.reserve(descFileNames.size());
|
||||||
|
for(const QString &descFileName : descFileNames) {
|
||||||
|
QFile descFile(dbDir.absoluteFilePath(descFileName));
|
||||||
|
if(descFile.open(QFile::ReadOnly)) {
|
||||||
|
descData << descFile.readAll();
|
||||||
|
} else {
|
||||||
|
// TODO: error handling (can't open pkg file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!descData.isEmpty()) {
|
||||||
|
descriptions << qMakePair(pkgDirName, descData);
|
||||||
|
}
|
||||||
|
dbDir.cdUp();
|
||||||
|
} else {
|
||||||
|
// TODO: error handling (can't enter pkg dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(pathInfo.isFile()) {
|
||||||
|
KTar tar(databasePath());
|
||||||
|
const KArchiveDirectory *dbDir;
|
||||||
|
if(tar.open(QIODevice::ReadOnly) && (dbDir = tar.directory())) {
|
||||||
|
QStringList pkgDirNames = dbDir->entries();
|
||||||
|
descriptions.reserve(pkgDirNames.size());
|
||||||
|
for(QString &pkgDirName : pkgDirNames) {
|
||||||
|
if(const auto *pkgEntry = dbDir->entry(pkgDirName)) {
|
||||||
|
if(pkgEntry->isDirectory()) {
|
||||||
|
Utilities::stripVersion(pkgDirName);
|
||||||
|
const auto *pkgDir = static_cast<const KArchiveDirectory *>(pkgEntry);
|
||||||
|
const QStringList descFileNames = pkgDir->entries();
|
||||||
|
QList<QByteArray> descData;
|
||||||
|
descData.reserve(descFileNames.size());
|
||||||
|
for(const QString &descFileName : descFileNames) {
|
||||||
|
if(const auto *descEntry = pkgDir->entry(descFileName)) {
|
||||||
|
if(descEntry->isFile()) {
|
||||||
|
descData << static_cast<const KArchiveFile *>(descEntry)->data();
|
||||||
|
} else {
|
||||||
|
// there shouldn't be any subdirs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!descData.isEmpty()) {
|
||||||
|
descriptions << qMakePair(pkgDirName, descData);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// there shouldn't be any files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: error handling (can't open sync db file)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: error handling
|
||||||
}
|
}
|
||||||
m_future = QtConcurrent::map(m_packages, LoadPackage(repository, &m_mutex));
|
}
|
||||||
|
|
||||||
|
AlpmPackageLoader::AlpmPackageLoader(AlpmDatabase *repository, PackageOrigin origin)
|
||||||
|
{
|
||||||
|
repository->loadDescriptions(m_descriptions);
|
||||||
|
m_future = QtConcurrent::map(m_descriptions, LoadPackage(repository, origin));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Creates a new instance wrapping the specified database struct.
|
* \brief Creates a new instance wrapping the specified database struct.
|
||||||
*/
|
*/
|
||||||
AlpmDatabase::AlpmDatabase(alpm_db_t *dataBase, const QString &dbPath, uint32 index, QObject *parent) :
|
AlpmDatabase::AlpmDatabase(const QString &name, const QString &dbPath, RepositoryUsage usage, SignatureLevel sigLevel, uint32 index, QObject *parent) :
|
||||||
Repository(QString::fromLocal8Bit(alpm_db_get_name(dataBase)), index, parent),
|
Repository(name, index, parent),
|
||||||
m_ptr(dataBase),
|
m_dbPath(dbPath)
|
||||||
m_dbFile(QStringLiteral("%1/sync/%2").arg(dbPath, m_name))
|
{
|
||||||
{}
|
m_usage = usage;
|
||||||
|
m_sigLevel = sigLevel;
|
||||||
|
}
|
||||||
|
|
||||||
AlpmPackageLoader *AlpmDatabase::init()
|
AlpmPackageLoader *AlpmDatabase::init()
|
||||||
{
|
{
|
||||||
if(alpm_db_get_usage(m_ptr, &m_usage)) {
|
// set description, determine origin
|
||||||
m_usage = static_cast<decltype(m_usage)>(ALPM_DB_USAGE_ALL);
|
PackageOrigin origin;
|
||||||
}
|
|
||||||
if(m_name.compare(QLatin1String("local"), Qt::CaseInsensitive) == 0) {
|
if(m_name.compare(QLatin1String("local"), Qt::CaseInsensitive) == 0) {
|
||||||
m_description = QStringLiteral("The local database");
|
m_description = QStringLiteral("The local database");
|
||||||
|
origin = PackageOrigin::LocalDb;
|
||||||
} else {
|
} else {
|
||||||
if((m_usage & ALPM_DB_USAGE_SYNC) || (m_usage & ALPM_DB_USAGE_INSTALL) || (m_usage & ALPM_DB_USAGE_UPGRADE)) {
|
if((m_usage & RepositoryUsage::Sync) || (m_usage & RepositoryUsage::Install) || (m_usage & RepositoryUsage::Upgrade)) {
|
||||||
m_description = QStringLiteral("Sync database »%1«").arg(m_name);
|
m_description = QStringLiteral("Sync database »%1«").arg(m_name);
|
||||||
} else {
|
} else {
|
||||||
m_description = QStringLiteral("Database »%1«").arg(m_name);
|
m_description = QStringLiteral("Database »%1«").arg(m_name);
|
||||||
}
|
}
|
||||||
|
origin = PackageOrigin::SyncDb;
|
||||||
}
|
}
|
||||||
for(const char *str : servers()) {
|
|
||||||
m_serverUrls << qstr(str);
|
|
||||||
}
|
|
||||||
m_sigLevel = alpm_db_get_siglevel(m_ptr);
|
|
||||||
return new AlpmPackageLoader(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//AlpmDatabase::AlpmDatabase(const QString &dataBaseFile, QObject *parent) :
|
// initialization of packages is done concurrently via AlpmPackageLoader: ~ 4 sec
|
||||||
// PackageSource(parent),
|
return new AlpmPackageLoader(this, origin);
|
||||||
// m_ptr(nullptr)
|
|
||||||
//{}
|
// without concurrency: ~ 12 sec
|
||||||
|
//QList<QPair<QString, QList<QByteArray> > > descriptions;
|
||||||
|
//loadDescriptions(descriptions);
|
||||||
|
//for(const auto &description : descriptions) {
|
||||||
|
// addPackageFromDescription(description.first, description.second, origin);
|
||||||
|
//}
|
||||||
|
//return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
RepositoryType AlpmDatabase::type() const
|
RepositoryType AlpmDatabase::type() const
|
||||||
{
|
{
|
||||||
|
@ -109,22 +177,6 @@ PackageDetailAvailability AlpmDatabase::requestsRequired(PackageDetail packageDe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds the specified server URLs.
|
|
||||||
*/
|
|
||||||
bool AlpmDatabase::addServerUrls(const QStringList &urls)
|
|
||||||
{
|
|
||||||
bool res = true;
|
|
||||||
for(const auto &url : urls) {
|
|
||||||
if(alpm_db_add_server(m_ptr, url.toLocal8Bit().data()) != 0) {
|
|
||||||
res = false;
|
|
||||||
} else {
|
|
||||||
m_serverUrls << url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Package> AlpmDatabase::emptyPackage()
|
std::unique_ptr<Package> AlpmDatabase::emptyPackage()
|
||||||
{
|
{
|
||||||
return make_unique<AlpmPackage>(this);
|
return make_unique<AlpmPackage>(this);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define ALPM_DATABASE_H
|
#define ALPM_DATABASE_H
|
||||||
|
|
||||||
#include "./repository.h"
|
#include "./repository.h"
|
||||||
#include "./list.h"
|
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
@ -14,37 +13,30 @@ namespace RepoIndex {
|
||||||
|
|
||||||
class AlpmPackage;
|
class AlpmPackage;
|
||||||
class AlpmDatabase;
|
class AlpmDatabase;
|
||||||
|
class LoadPackage;
|
||||||
|
|
||||||
class AlpmPackageLoader : public PackageLoader
|
class AlpmPackageLoader : public PackageLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AlpmPackageLoader(AlpmDatabase *db);
|
AlpmPackageLoader(AlpmDatabase *db, PackageOrigin origin);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<alpm_pkg_t *> m_packages;
|
QList<QPair<QString, QList<QByteArray> > > m_descriptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AlpmDatabase : public Repository
|
class AlpmDatabase : public Repository
|
||||||
{
|
{
|
||||||
|
friend class AlpmPackageLoader;
|
||||||
public:
|
public:
|
||||||
explicit AlpmDatabase(alpm_db_t *dataBase, const QString &dbPath, uint32 index = invalidIndex, QObject *parent = nullptr);
|
explicit AlpmDatabase(const QString &name, const QString &dbPath, RepositoryUsage usage, SignatureLevel sigLevel, uint32 index = invalidIndex, QObject *parent = nullptr);
|
||||||
AlpmPackageLoader *init();
|
AlpmPackageLoader *init();
|
||||||
// explicit AlpmDatabase(const QString &dataBaseFile, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
RepositoryType type() const;
|
RepositoryType type() const;
|
||||||
PackageDetailAvailability requestsRequired(PackageDetail packageDetail) const;
|
PackageDetailAvailability requestsRequired(PackageDetail packageDetail) const;
|
||||||
|
|
||||||
// operators
|
|
||||||
bool operator ==(const AlpmDatabase &other) const;
|
|
||||||
bool operator !=(const AlpmDatabase &other) const;
|
|
||||||
|
|
||||||
// database meta data
|
// database meta data
|
||||||
alpm_db_t *ptr();
|
const QString &databasePath() const;
|
||||||
const QString &dataBaseFile() const;
|
void setDatabasePath(const QString &dbPath);
|
||||||
StringList servers() const;
|
|
||||||
bool setServers(StringList servers);
|
|
||||||
bool addServerUrls(const QStringList &urls);
|
|
||||||
PackageList search(StringList terms) const;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void initiated();
|
void initiated();
|
||||||
|
@ -53,64 +45,26 @@ protected:
|
||||||
std::unique_ptr<Package> emptyPackage();
|
std::unique_ptr<Package> emptyPackage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alpm_db_t *m_ptr;
|
void loadDescriptions(QList<QPair<QString, QList<QByteArray> > > &descriptions);
|
||||||
QString m_dbFile;
|
|
||||||
|
QString m_dbPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Checks whether the specified ALPM database is equal the current instance.
|
* \brief Returns the path of the database directory/file.
|
||||||
*/
|
*/
|
||||||
inline bool AlpmDatabase::operator ==(const AlpmDatabase &other) const
|
inline const QString &AlpmDatabase::databasePath() const
|
||||||
{
|
{
|
||||||
return m_ptr == other.m_ptr;
|
return m_dbPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Checks whether the specified ALPM database is not equal to the current instance.
|
* \brief Sets the path of the database directory/file.
|
||||||
|
* \remarks Does not invoke reinitialization using the new path.
|
||||||
*/
|
*/
|
||||||
inline bool AlpmDatabase::operator !=(const AlpmDatabase &other) const
|
inline void AlpmDatabase::setDatabasePath(const QString &dbPath)
|
||||||
{
|
{
|
||||||
return m_ptr != other.m_ptr;
|
m_dbPath = dbPath;
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Returns the pointer to the underlying database struct.
|
|
||||||
*/
|
|
||||||
inline alpm_db_t *AlpmDatabase::ptr()
|
|
||||||
{
|
|
||||||
return m_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Returns the path of the data base file.
|
|
||||||
*/
|
|
||||||
inline const QString &AlpmDatabase::dataBaseFile() const
|
|
||||||
{
|
|
||||||
return m_dbFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Returns the servers of the database.
|
|
||||||
*/
|
|
||||||
inline StringList AlpmDatabase::servers() const
|
|
||||||
{
|
|
||||||
return alpm_db_get_servers(m_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Sets the servers of the database.
|
|
||||||
*/
|
|
||||||
inline bool AlpmDatabase::setServers(StringList servers)
|
|
||||||
{
|
|
||||||
return alpm_db_set_servers(m_ptr, servers.begin().ptr()) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Performs a search using the build-in ALPM function.
|
|
||||||
*/
|
|
||||||
inline PackageList AlpmDatabase::search(StringList terms) const
|
|
||||||
{
|
|
||||||
return alpm_db_search(m_ptr, terms.begin().ptr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Alpm
|
} // namespace Alpm
|
||||||
|
|
|
@ -2,99 +2,50 @@
|
||||||
#include "./alpmdatabase.h"
|
#include "./alpmdatabase.h"
|
||||||
#include "./utilities.h"
|
#include "./utilities.h"
|
||||||
|
|
||||||
#include <QJsonObject>
|
#include <KTar>
|
||||||
|
#include <KArchiveDirectory>
|
||||||
|
#include <KArchiveFile>
|
||||||
|
|
||||||
#include <iostream>
|
#include <QFileInfo>
|
||||||
|
|
||||||
using namespace ChronoUtilities;
|
using namespace ChronoUtilities;
|
||||||
|
|
||||||
namespace RepoIndex {
|
namespace RepoIndex {
|
||||||
|
|
||||||
/*!
|
|
||||||
* \cond
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Utilities {
|
|
||||||
|
|
||||||
inline QList<Dependency> depinfos(DependencyList list)
|
|
||||||
{
|
|
||||||
QList<Dependency> infos;
|
|
||||||
for(const auto *dep : list) {
|
|
||||||
infos << Dependency(qstr(dep->name), qstr(dep->version), dep->mod);
|
|
||||||
}
|
|
||||||
return infos;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \endcond
|
|
||||||
*/
|
|
||||||
|
|
||||||
using namespace Utilities;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The AlpmPackage class wraps an ALPM package struct and holds additional meta information.
|
* \brief The AlpmPackage class wraps an ALPM package struct and holds additional meta information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs an empty ALPM package.
|
* \brief Constructs an empty ALPM package for the specified \a repository.
|
||||||
|
* \remarks This constructor is called by the AlpmDatabase class which puts the package name and
|
||||||
|
* available meta data via the Package::putDescription() method.
|
||||||
*/
|
*/
|
||||||
AlpmPackage::AlpmPackage(AlpmDatabase *repository) :
|
AlpmPackage::AlpmPackage(AlpmDatabase *repository) :
|
||||||
Package(QString(), repository),
|
Package(QString(), repository)
|
||||||
m_ptr(nullptr)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*!
|
AlpmPackage::AlpmPackage(const QString &packageFilePath) :
|
||||||
* \brief Constructs a new instance for the specified ALPM \a package.
|
Package(QString(), nullptr)
|
||||||
*/
|
|
||||||
AlpmPackage::AlpmPackage(alpm_pkg_t *package, AlpmDatabase *alpmDatabase) :
|
|
||||||
Package(QString::fromLocal8Bit(alpm_pkg_get_name(package)), alpmDatabase),
|
|
||||||
m_ptr(package)
|
|
||||||
{
|
{
|
||||||
m_origin = static_cast<PackageOrigin>(alpm_pkg_get_origin(package));
|
m_origin = PackageOrigin::File;
|
||||||
m_hasGeneralInfo = m_hasAllGeneralInfo = m_hasBuildRelatedMetaData = m_hasInstallRelatedMetaData = true;
|
m_name = m_fileName = QFileInfo(packageFilePath).fileName();
|
||||||
m_version = qstr(alpm_pkg_get_version(package));
|
Utilities::stripVersion(m_name);
|
||||||
m_description = qstr(alpm_pkg_get_desc(package));
|
KTar pkgTar(packageFilePath);
|
||||||
m_upstreamUrl = qstr(alpm_pkg_get_url(package));
|
const KArchiveDirectory *mainDir;
|
||||||
m_licenses = qstrlist(alpm_pkg_get_licenses(package));
|
if(pkgTar.open(QIODevice::ReadOnly) && (mainDir = pkgTar.directory())) {
|
||||||
m_groups = qstrlist(alpm_pkg_get_groups(package));
|
if(const KArchiveEntry *pkgInfoEntry = mainDir->entry(QStringLiteral(".PKGINFO"))) {
|
||||||
m_dependencies = depinfos(alpm_pkg_get_depends(package));
|
if(pkgInfoEntry->isFile()) {
|
||||||
m_optionalDependencies = depinfos(alpm_pkg_get_optdepends(package));
|
// parse fields
|
||||||
m_conflicts = depinfos(alpm_pkg_get_conflicts(package));
|
QList<QPair<QString, QString> > packageInfo;
|
||||||
m_provides = depinfos(alpm_pkg_get_provides(package));
|
AlpmDatabase::parsePkgInfo(static_cast<const KArchiveFile *>(pkgInfoEntry)->data(), m_name, packageInfo);
|
||||||
m_replaces = depinfos(alpm_pkg_get_replaces(package));
|
putInfo(QList<QPair<QString, QString> >(), packageInfo, true);
|
||||||
//alpm_list_t *tmp;
|
} else {
|
||||||
//m_requiredBy = qstrlist(tmp = alpm_pkg_compute_requiredby(package));
|
// TODO: handle error (.PKGINFO is not a file)
|
||||||
//FREELIST(tmp);
|
}
|
||||||
//m_optionalFor = qstrlist(tmp = alpm_pkg_compute_optionalfor(package));
|
|
||||||
//FREELIST(tmp);
|
|
||||||
m_hasInstallScript = alpm_pkg_has_scriptlet(package);
|
|
||||||
m_fileName = qstr(alpm_pkg_get_filename(package));
|
|
||||||
m_buildDate = DateTime::fromTimeStamp(alpm_pkg_get_builddate(package));
|
|
||||||
m_packager = qstr(alpm_pkg_get_packager(package));
|
|
||||||
m_md5 = qstr(alpm_pkg_get_md5sum(package));
|
|
||||||
m_sha256 = qstr(alpm_pkg_get_sha256sum(package));
|
|
||||||
m_buildArchitecture = qstr(alpm_pkg_get_arch(package));
|
|
||||||
m_packageSize = alpm_pkg_get_size(package);
|
|
||||||
m_installDate = DateTime::fromTimeStamp(alpm_pkg_get_installdate(package));
|
|
||||||
m_installedSize = alpm_pkg_get_isize(package);
|
|
||||||
for(const auto *backupEntry : BackupList(alpm_pkg_get_backup(package))) {
|
|
||||||
m_backupFiles << qstr(backupEntry->name);
|
|
||||||
}
|
|
||||||
m_validationMethods = alpm_pkg_get_validation(package);
|
|
||||||
m_installReason = alpm_pkg_get_reason(package);
|
|
||||||
alpm_filelist_t *fileList = alpm_pkg_get_files(package);
|
|
||||||
for(alpm_file_t *file = fileList->files, *end = fileList->files + fileList->count; file != end; ++file) {
|
|
||||||
QJsonObject fileInfo;
|
|
||||||
fileInfo.insert(QStringLiteral("name"), qstr(file->name));
|
|
||||||
if(file->mode) {
|
|
||||||
fileInfo.insert(QStringLiteral("mode"), static_cast<int>(file->mode));
|
|
||||||
}
|
}
|
||||||
if(file->size) {
|
} else {
|
||||||
fileInfo.insert(QStringLiteral("size"), static_cast<int>(file->size));
|
// TODO: handle error (can't open package file)
|
||||||
}
|
|
||||||
m_files << fileInfo;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,109 +11,10 @@ class AlpmPackage : public Package
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AlpmPackage(AlpmDatabase *repository);
|
AlpmPackage(AlpmDatabase *repository);
|
||||||
AlpmPackage(alpm_pkg_t *package, AlpmDatabase *alpmDatabase);
|
AlpmPackage(const QString &packageFile);
|
||||||
AlpmPackage(alpm_pkg_t *package);
|
|
||||||
|
|
||||||
// ALPM specific meta data
|
|
||||||
const alpm_pkg_t *ptr() const;
|
|
||||||
alpm_pkg_t *ptr();
|
|
||||||
const char *base64Signature() const;
|
|
||||||
void *openChangelog() const;
|
|
||||||
size_t readChangelog(void *changelog, void *buffer, size_t bufferSize);
|
|
||||||
bool closeChangelog(void *changelog);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
alpm_pkg_t *m_ptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Constructs a new instance for the specified ALPM \a package.
|
|
||||||
* \remarks This method is only meant to be used for packages which do
|
|
||||||
* not belong to a database.
|
|
||||||
*/
|
|
||||||
inline AlpmPackage::AlpmPackage(alpm_pkg_t *package) :
|
|
||||||
AlpmPackage(package, nullptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline uint qHash(const AlpmPackage &key)
|
|
||||||
{
|
|
||||||
return qHash(key.ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Returns a pointer to the underlying alpm_pkg_t.
|
|
||||||
*/
|
|
||||||
inline const alpm_pkg_t *AlpmPackage::ptr() const
|
|
||||||
{
|
|
||||||
return m_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Returns a pointer to the underlying alpm_pkg_t.
|
|
||||||
*/
|
|
||||||
inline alpm_pkg_t *AlpmPackage::ptr()
|
|
||||||
{
|
|
||||||
return m_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char *AlpmPackage::base64Signature() const
|
|
||||||
{
|
|
||||||
return alpm_pkg_get_base64_sig(m_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void *AlpmPackage::openChangelog() const
|
|
||||||
{
|
|
||||||
return alpm_pkg_changelog_open(m_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t AlpmPackage::readChangelog(void *changelog, void *buffer, size_t bufferSize)
|
|
||||||
{
|
|
||||||
return alpm_pkg_changelog_read(buffer, bufferSize, m_ptr, changelog);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool AlpmPackage::closeChangelog(void *changelog)
|
|
||||||
{
|
|
||||||
return alpm_pkg_changelog_close(m_ptr, changelog);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AlpmOwnershipPackage : public AlpmPackage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// constructor, destructor
|
|
||||||
AlpmOwnershipPackage(alpm_pkg_t *package);
|
|
||||||
AlpmOwnershipPackage(const AlpmOwnershipPackage &other) = delete;
|
|
||||||
AlpmOwnershipPackage(AlpmOwnershipPackage &&other);
|
|
||||||
~AlpmOwnershipPackage();
|
|
||||||
|
|
||||||
// assignment operator
|
|
||||||
AlpmOwnershipPackage &operator =(const AlpmOwnershipPackage &other) = delete;
|
|
||||||
AlpmOwnershipPackage &operator =(AlpmOwnershipPackage &&other);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline AlpmOwnershipPackage::AlpmOwnershipPackage(alpm_pkg_t *package) :
|
|
||||||
AlpmPackage(package)
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline AlpmOwnershipPackage::AlpmOwnershipPackage(AlpmOwnershipPackage &&other) :
|
|
||||||
AlpmPackage(other.m_ptr)
|
|
||||||
{
|
|
||||||
other.m_ptr = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AlpmOwnershipPackage &AlpmOwnershipPackage::operator =(AlpmOwnershipPackage &&other)
|
|
||||||
{
|
|
||||||
if(this != &other) {
|
|
||||||
m_ptr = other.m_ptr;
|
|
||||||
other.m_ptr = nullptr;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AlpmOwnershipPackage::~AlpmOwnershipPackage()
|
|
||||||
{
|
|
||||||
alpm_pkg_free(ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace PackageManagement
|
} // namespace PackageManagement
|
||||||
|
|
||||||
#endif // PACKAGEMANAGEMENT_ALPMPACKAGE_H
|
#endif // PACKAGEMANAGEMENT_ALPMPACKAGE_H
|
||||||
|
|
|
@ -316,6 +316,10 @@ void Config::loadFromArgs(const ConfigArgs &args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RepoEntry::RepoEntry() :
|
||||||
|
m_sigLevel(SignatureLevel::UseDefault)
|
||||||
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Loads the values from the specified JSON value.
|
* \brief Loads the values from the specified JSON value.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,6 +11,8 @@ QT_FORWARD_DECLARE_CLASS(QJsonValue)
|
||||||
|
|
||||||
namespace RepoIndex {
|
namespace RepoIndex {
|
||||||
|
|
||||||
|
enum class SignatureLevel;
|
||||||
|
|
||||||
// these are needed from the beginning and are initialized in the main()
|
// these are needed from the beginning and are initialized in the main()
|
||||||
extern bool useShSyntax;
|
extern bool useShSyntax;
|
||||||
extern const char *shchar;
|
extern const char *shchar;
|
||||||
|
@ -57,12 +59,12 @@ class RepoEntry
|
||||||
public:
|
public:
|
||||||
RepoEntry();
|
RepoEntry();
|
||||||
const QString &name() const;
|
const QString &name() const;
|
||||||
const QString &dataBasePath() const;
|
const QString &databasePath() const;
|
||||||
const QString &sourceDir() const;
|
const QString &sourceDir() const;
|
||||||
const QString &packageDir() const;
|
const QString &packageDir() const;
|
||||||
const QStringList &servers() const;
|
const QStringList &servers() const;
|
||||||
const QStringList &upgradeSources() const;
|
const QStringList &upgradeSources() const;
|
||||||
int sigLevel() const;
|
SignatureLevel sigLevel() const;
|
||||||
void load(const QJsonValue &jsonValue);
|
void load(const QJsonValue &jsonValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -72,19 +74,15 @@ private:
|
||||||
QString m_packageDir;
|
QString m_packageDir;
|
||||||
QStringList m_servers;
|
QStringList m_servers;
|
||||||
QStringList m_upgradeSources;
|
QStringList m_upgradeSources;
|
||||||
int m_sigLevel;
|
SignatureLevel m_sigLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline RepoEntry::RepoEntry() :
|
|
||||||
m_sigLevel(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline const QString &RepoEntry::name() const
|
inline const QString &RepoEntry::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const QString &RepoEntry::dataBasePath() const
|
inline const QString &RepoEntry::databasePath() const
|
||||||
{
|
{
|
||||||
return m_dataBaseFile;
|
return m_dataBaseFile;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +107,7 @@ inline const QStringList &RepoEntry::upgradeSources() const
|
||||||
return m_upgradeSources;
|
return m_upgradeSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int RepoEntry::sigLevel() const
|
inline SignatureLevel RepoEntry::sigLevel() const
|
||||||
{
|
{
|
||||||
return m_sigLevel;
|
return m_sigLevel;
|
||||||
}
|
}
|
||||||
|
|
324
alpm/manager.cpp
324
alpm/manager.cpp
|
@ -1,6 +1,5 @@
|
||||||
#include "./manager.h"
|
#include "./manager.h"
|
||||||
#include "./utilities.h"
|
#include "./utilities.h"
|
||||||
#include "./list.h"
|
|
||||||
#include "./config.h"
|
#include "./config.h"
|
||||||
#include "./alpmdatabase.h"
|
#include "./alpmdatabase.h"
|
||||||
|
|
||||||
|
@ -17,6 +16,8 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -33,8 +34,8 @@ namespace RepoIndex {
|
||||||
* \cond
|
* \cond
|
||||||
*/
|
*/
|
||||||
|
|
||||||
constexpr int defaultSigLevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
|
constexpr auto defaultSigLevel = SignatureLevel::Package | SignatureLevel::PackageOptional
|
||||||
ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
|
| SignatureLevel::Database | SignatureLevel::DatabaseOptional;
|
||||||
|
|
||||||
inline ostream &operator <<(ostream &stream, const QString &str)
|
inline ostream &operator <<(ostream &stream, const QString &str)
|
||||||
{
|
{
|
||||||
|
@ -62,9 +63,9 @@ Manager::Manager(const Config &config) :
|
||||||
m_config(config),
|
m_config(config),
|
||||||
m_writeCacheBeforeGone(true),
|
m_writeCacheBeforeGone(true),
|
||||||
m_sigLevel(defaultSigLevel),
|
m_sigLevel(defaultSigLevel),
|
||||||
m_localFileSigLevel(ALPM_SIG_USE_DEFAULT)
|
m_localFileSigLevel(SignatureLevel::UseDefault)
|
||||||
{
|
{
|
||||||
initAlpmHandle();
|
addLocalDatabase();
|
||||||
if(config.isAurEnabled()) {
|
if(config.isAurEnabled()) {
|
||||||
m_userRepo = make_unique<UserRepository>(m_networkAccessManager);
|
m_userRepo = make_unique<UserRepository>(m_networkAccessManager);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ Manager::~Manager()
|
||||||
if(m_writeCacheBeforeGone) {
|
if(m_writeCacheBeforeGone) {
|
||||||
writeCache();
|
writeCache();
|
||||||
}
|
}
|
||||||
cleanupAlpm();
|
removeAllDatabases();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -131,21 +132,6 @@ const AlpmPackage *Manager::packageFromSyncDatabases(const QString &pkgName) con
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Creates a new package instance for the specified package file.
|
|
||||||
*
|
|
||||||
* Verifies the integrity of the file if the option is set.
|
|
||||||
*/
|
|
||||||
unique_ptr<AlpmOwnershipPackage> Manager::packageFromFile(const char *fileName, bool verifyIntegrity)
|
|
||||||
{
|
|
||||||
alpm_pkg_t *pkg;
|
|
||||||
if(alpm_pkg_load(m_handle, fileName, verifyIntegrity, static_cast<alpm_siglevel_t>(m_localFileSigLevel), &pkg) != 0) {
|
|
||||||
throw runtime_error(string("Unable to load package file: ") + alpm_strerror(alpm_errno(m_handle)));
|
|
||||||
} else {
|
|
||||||
return make_unique<AlpmOwnershipPackage>(pkg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the first package satisfiing the specified dependency from one of the available package sources (excluding the local database
|
* \brief Returns the first package satisfiing the specified dependency from one of the available package sources (excluding the local database
|
||||||
* and sources requirering requests such as the AUR).
|
* and sources requirering requests such as the AUR).
|
||||||
|
@ -176,16 +162,6 @@ const Package *Manager::packageProviding(const Dependency &dependency) const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Sets the install reason for the specified \a package.
|
|
||||||
*/
|
|
||||||
void Manager::setInstallReason(AlpmPackage *package, alpm_pkgreason_t reason)
|
|
||||||
{
|
|
||||||
if(alpm_pkg_set_reason(package->ptr(), reason)) {
|
|
||||||
throw runtime_error(string("Unable to set install reason of the package ") + package->name().toLocal8Bit().data() + ": " + alpm_strerror(alpm_errno(m_handle)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the last value with the specified \a key in the specified multimap.
|
* \brief Returns the last value with the specified \a key in the specified multimap.
|
||||||
*/
|
*/
|
||||||
|
@ -201,9 +177,9 @@ const string &lastValue(const multimap<string, string> &mm, const string &key)
|
||||||
/*!
|
/*!
|
||||||
* \brief Parses a "SigLevel" denotation from pacman config file.
|
* \brief Parses a "SigLevel" denotation from pacman config file.
|
||||||
*/
|
*/
|
||||||
int Manager::parseSigLevel(const string &sigLevelStr)
|
SignatureLevel Manager::parseSigLevel(const string &sigLevelStr)
|
||||||
{
|
{
|
||||||
int sigLevel = defaultSigLevel;
|
SignatureLevel sigLevel = defaultSigLevel;
|
||||||
// split sig level denotation into parts
|
// split sig level denotation into parts
|
||||||
const auto parts = splitString<list<string> >(sigLevelStr, " ");
|
const auto parts = splitString<list<string> >(sigLevelStr, " ");
|
||||||
for(const auto &part : parts) {
|
for(const auto &part : parts) {
|
||||||
|
@ -220,40 +196,40 @@ int Manager::parseSigLevel(const string &sigLevelStr)
|
||||||
// set sig level according part
|
// set sig level according part
|
||||||
if(!strcmp(partStart, "Never")) {
|
if(!strcmp(partStart, "Never")) {
|
||||||
if(package) {
|
if(package) {
|
||||||
sigLevel &= ~ALPM_SIG_PACKAGE;
|
sigLevel &= ~SignatureLevel::Package;
|
||||||
}
|
}
|
||||||
if(db) {
|
if(db) {
|
||||||
sigLevel &= ~ALPM_SIG_DATABASE;
|
sigLevel &= ~SignatureLevel::Database;
|
||||||
}
|
}
|
||||||
} else if(!strcmp(partStart, "Optional")) {
|
} else if(!strcmp(partStart, "Optional")) {
|
||||||
if(package) {
|
if(package) {
|
||||||
sigLevel |= ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL;
|
sigLevel |= SignatureLevel::Package | SignatureLevel::PackageOptional;
|
||||||
}
|
}
|
||||||
if(db) {
|
if(db) {
|
||||||
sigLevel |= ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
|
sigLevel |= SignatureLevel::Database | SignatureLevel::DatabaseOptional;
|
||||||
}
|
}
|
||||||
} else if(!strcmp(partStart, "Required")) {
|
} else if(!strcmp(partStart, "Required")) {
|
||||||
if(package) {
|
if(package) {
|
||||||
sigLevel |= ALPM_SIG_PACKAGE;
|
sigLevel |= SignatureLevel::Package;
|
||||||
sigLevel &= ~ALPM_SIG_PACKAGE_OPTIONAL;
|
sigLevel &= ~SignatureLevel::PackageOptional;
|
||||||
}
|
}
|
||||||
if(db) {
|
if(db) {
|
||||||
sigLevel |= ALPM_SIG_DATABASE;
|
sigLevel |= SignatureLevel::Database;
|
||||||
sigLevel &= ~ALPM_SIG_DATABASE_OPTIONAL;
|
sigLevel &= ~SignatureLevel::DatabaseOptional;
|
||||||
}
|
}
|
||||||
} else if(!strcmp(partStart, "TrustedOnly")) {
|
} else if(!strcmp(partStart, "TrustedOnly")) {
|
||||||
if(package) {
|
if(package) {
|
||||||
sigLevel &= ~(ALPM_SIG_PACKAGE_MARGINAL_OK | ALPM_SIG_PACKAGE_UNKNOWN_OK);
|
sigLevel &= ~(SignatureLevel::PackageMarginalOk | SignatureLevel::PackageUnknownOk);
|
||||||
}
|
}
|
||||||
if(db) {
|
if(db) {
|
||||||
sigLevel &= ~(ALPM_SIG_DATABASE_MARGINAL_OK | ALPM_SIG_DATABASE_UNKNOWN_OK);
|
sigLevel &= ~(SignatureLevel::DatabaseMarginalOk | SignatureLevel::DatabaseUnknownOk);
|
||||||
}
|
}
|
||||||
} else if(!strcmp(partStart, "TrustAll")) {
|
} else if(!strcmp(partStart, "TrustAll")) {
|
||||||
if(package) {
|
if(package) {
|
||||||
sigLevel |= ALPM_SIG_PACKAGE_MARGINAL_OK | ALPM_SIG_PACKAGE_UNKNOWN_OK;
|
sigLevel |= SignatureLevel::PackageMarginalOk | SignatureLevel::PackageUnknownOk;
|
||||||
}
|
}
|
||||||
if(db) {
|
if(db) {
|
||||||
sigLevel |= ALPM_SIG_DATABASE_MARGINAL_OK | ALPM_SIG_DATABASE_UNKNOWN_OK;
|
sigLevel |= SignatureLevel::DatabaseMarginalOk | SignatureLevel::DatabaseUnknownOk;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cerr << shchar << "Warning: Invalid value \"" << part << "\" for \"SigLevel\" in pacman config file will be ignored." << endl;
|
cerr << shchar << "Warning: Invalid value \"" << part << "\" for \"SigLevel\" in pacman config file will be ignored." << endl;
|
||||||
|
@ -265,30 +241,30 @@ int Manager::parseSigLevel(const string &sigLevelStr)
|
||||||
/*!
|
/*!
|
||||||
* \brief Parses a "Usage" denotation from pacman config file.
|
* \brief Parses a "Usage" denotation from pacman config file.
|
||||||
*/
|
*/
|
||||||
int Manager::parseUsage(const string &usageStr)
|
RepositoryUsage Manager::parseUsage(const string &usageStr)
|
||||||
{
|
{
|
||||||
int usage = 0;
|
RepositoryUsage usage = RepositoryUsage::None;
|
||||||
const auto parts = splitString<list<string> >(usageStr, " ");
|
const auto parts = splitString<list<string> >(usageStr, " ", EmptyPartsTreat::Omit);
|
||||||
for(const auto &part : parts) {
|
for(const auto &part : parts) {
|
||||||
if(part == "Sync") {
|
if(part == "Sync") {
|
||||||
usage |= ALPM_DB_USAGE_SYNC;
|
usage |= RepositoryUsage::Sync;
|
||||||
} else if(part == "Search") {
|
} else if(part == "Search") {
|
||||||
usage |= ALPM_DB_USAGE_SEARCH;
|
usage |= RepositoryUsage::Search;
|
||||||
} else if(part == "Install") {
|
} else if(part == "Install") {
|
||||||
usage |= ALPM_DB_USAGE_INSTALL;
|
usage |= RepositoryUsage::Install;
|
||||||
} else if(part == "Upgrade") {
|
} else if(part == "Upgrade") {
|
||||||
usage |= ALPM_DB_USAGE_UPGRADE;
|
usage |= RepositoryUsage::Upgrade;
|
||||||
} else {
|
} else {
|
||||||
cerr << shchar << "Warning: Invalid value \"" << part << "\" for \"Usage\" in pacman config file will be ignored." << endl;
|
cerr << shchar << "Warning: Invalid value \"" << part << "\" for \"Usage\" in pacman config file will be ignored." << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return usage ? usage : ALPM_DB_USAGE_ALL;
|
return usage != RepositoryUsage::None ? usage : RepositoryUsage::All;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Registers sync databases listed in the Pacman config file. Also reads the cache dir.
|
* \brief Adds sync databases listed in the Pacman config file. Also reads the cache dir.
|
||||||
*/
|
*/
|
||||||
void Manager::registerDataBasesFromPacmanConfig()
|
void Manager::addDataBasesFromPacmanConfig()
|
||||||
{
|
{
|
||||||
// open config file and parse as ini
|
// open config file and parse as ini
|
||||||
try {
|
try {
|
||||||
|
@ -301,12 +277,12 @@ void Manager::registerDataBasesFromPacmanConfig()
|
||||||
}
|
}
|
||||||
// determine current cpu archtitecture (required for server URLs)
|
// determine current cpu archtitecture (required for server URLs)
|
||||||
static const string sysArch(QSysInfo::currentCpuArchitecture().toStdString());
|
static const string sysArch(QSysInfo::currentCpuArchitecture().toStdString());
|
||||||
string arch = sysArch;
|
string arch(sysArch);
|
||||||
const auto &config = configIni.data();
|
const auto &config = configIni.data();
|
||||||
// read relevant options
|
// read relevant options
|
||||||
static const string sigLevelKey("SigLevel");
|
static const string sigLevelKey("SigLevel");
|
||||||
static const string usageKey("Usage");
|
static const string usageKey("Usage");
|
||||||
int globalSigLevel = defaultSigLevel;
|
SignatureLevel globalSigLevel = defaultSigLevel;
|
||||||
for(auto &scope : config) {
|
for(auto &scope : config) {
|
||||||
if(scope.first == "options") {
|
if(scope.first == "options") {
|
||||||
// iterate through all "config" scopes (just to cover the case that there are multiple "options" scopes)
|
// iterate through all "config" scopes (just to cover the case that there are multiple "options" scopes)
|
||||||
|
@ -337,71 +313,73 @@ void Manager::registerDataBasesFromPacmanConfig()
|
||||||
} else {
|
} else {
|
||||||
// read sig level and usage
|
// read sig level and usage
|
||||||
const auto &sigLevelStr = lastValue(scope.second, sigLevelKey);
|
const auto &sigLevelStr = lastValue(scope.second, sigLevelKey);
|
||||||
int sigLevel = sigLevelStr.empty() ? globalSigLevel : parseSigLevel(sigLevelStr);
|
SignatureLevel sigLevel = sigLevelStr.empty() ? globalSigLevel : parseSigLevel(sigLevelStr);
|
||||||
int usage = parseUsage(lastValue(scope.second, usageKey));
|
RepositoryUsage usage = parseUsage(lastValue(scope.second, usageKey));
|
||||||
// try to register database in the ALPM system
|
|
||||||
if(alpm_db_t *db = alpm_register_syncdb(m_handle, scope.first.c_str(), static_cast<alpm_siglevel_t>(sigLevel))) {
|
// determine path of db file
|
||||||
// set usage
|
// -> currently just use the file from pacman dir, TODO: download syncdata base
|
||||||
if(alpm_db_set_usage(db, static_cast<alpm_db_usage_t>(usage)) == 0) {
|
QFileInfo dbPathRegular(m_config.alpmDbPath() % QStringLiteral("/sync/") % dbName % QStringLiteral(".db"));
|
||||||
if(m_config.isVerbose() || m_config.runServer()) {
|
QFileInfo dbPathWithFiles(m_config.alpmDbPath() % QStringLiteral("/sync/") % dbName % QStringLiteral(".files"));
|
||||||
cerr << shchar << "Added database [" << scope.first << ']' << endl;
|
QString dbPath;
|
||||||
}
|
if(dbPathWithFiles.isFile() && (!dbPathRegular.isFile() || dbPathWithFiles.lastModified() > dbPathRegular.lastModified())) {
|
||||||
} else {
|
dbPath = dbPathWithFiles.absoluteFilePath();
|
||||||
if(m_config.isVerbose() || m_config.runServer()) {
|
} else if(dbPathRegular.isFile()) {
|
||||||
cerr << shchar << "Warning: Added database [" << scope.first << "] but failed to set usage" << endl;
|
dbPath = dbPathRegular.absoluteFilePath();
|
||||||
}
|
} else {
|
||||||
|
cerr << shchar << "Error: Unable to locate database file for [" << scope.first << "]" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add sync db to internal map (use as index size + 1 because the local database has index 0)
|
||||||
|
m_syncDbs.emplace_back(make_unique<AlpmDatabase>(dbName, dbPath, usage, sigLevel, m_syncDbs.size() + 1));
|
||||||
|
AlpmDatabase *emplacedDb = m_syncDbs.back().get();
|
||||||
|
m_syncDbMap.emplace(dbName, emplacedDb);
|
||||||
|
if(usage & RepositoryUsage::Upgrade) {
|
||||||
|
// -> db is used to upgrade local database
|
||||||
|
localDataBase()->upgradeSources() << emplacedDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add servers
|
||||||
|
for(auto range = scope.second.equal_range("Server"); range.first != range.second; ++range.first) {
|
||||||
|
string url = range.first->second;
|
||||||
|
findAndReplace<string>(url, "$repo", scope.first);
|
||||||
|
findAndReplace<string>(url, "$arch", arch);
|
||||||
|
emplacedDb->serverUrls() << Utilities::qstr(url);
|
||||||
|
if(m_config.isVerbose() || m_config.runServer()) {
|
||||||
|
cerr << shchar << "Added server: " << url << endl;
|
||||||
}
|
}
|
||||||
// add servers
|
}
|
||||||
for(auto range = scope.second.equal_range("Server"); range.first != range.second; ++range.first) {
|
|
||||||
string url = range.first->second;
|
// add included servers / parse mirror list
|
||||||
findAndReplace<string>(url, "$repo", scope.first);
|
for(auto range = scope.second.equal_range("Include"); range.first != range.second; ++range.first) {
|
||||||
findAndReplace<string>(url, "$arch", arch);
|
const auto &path = range.first->second;
|
||||||
alpm_db_add_server(db, url.c_str());
|
auto &includedIni = includedInis[path];
|
||||||
if(m_config.isVerbose() || m_config.runServer()) {
|
if(includedIni.data().empty()) {
|
||||||
cerr << shchar << "Added server: " << url << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add included servers
|
|
||||||
for(auto range = scope.second.equal_range("Include"); range.first != range.second; ++range.first) {
|
|
||||||
const auto &path = range.first->second;
|
|
||||||
auto &includedIni = includedInis[path];
|
|
||||||
if(includedIni.data().empty()) {
|
|
||||||
try {
|
|
||||||
fstream includedFile;
|
|
||||||
includedFile.exceptions(ios_base::failbit | ios_base::badbit);
|
|
||||||
includedFile.open(path, ios_base::in);
|
|
||||||
includedIni.parse(includedFile);
|
|
||||||
} catch (const ios_base::failure &) {
|
|
||||||
cerr << shchar << "Error: An IO exception occured when parsing the included file \"" << path << "\"." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
for(auto &scope : includedIni.data()) {
|
fstream includedFile;
|
||||||
if(scope.first.empty()) {
|
includedFile.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
for(auto range = scope.second.equal_range("Server"); range.first != range.second; ++range.first) {
|
includedFile.open(path, ios_base::in);
|
||||||
string url = range.first->second;
|
includedIni.parse(includedFile);
|
||||||
findAndReplace<string>(url, "$repo", scope.first);
|
} catch (const ios_base::failure &) {
|
||||||
findAndReplace<string>(url, "$arch", arch);
|
cerr << shchar << "Error: An IO exception occured when parsing the included file \"" << path << "\"." << endl;
|
||||||
alpm_db_add_server(db, url.c_str());
|
}
|
||||||
if(m_config.isVerbose() || m_config.runServer()) {
|
}
|
||||||
cerr << shchar << "Added server: " << url << endl;
|
try {
|
||||||
}
|
for(auto &scope : includedIni.data()) {
|
||||||
|
if(scope.first.empty()) {
|
||||||
|
for(auto range = scope.second.equal_range("Server"); range.first != range.second; ++range.first) {
|
||||||
|
string url = range.first->second;
|
||||||
|
findAndReplace<string>(url, "$repo", scope.first);
|
||||||
|
findAndReplace<string>(url, "$arch", arch);
|
||||||
|
emplacedDb->serverUrls() << Utilities::qstr(url);
|
||||||
|
if(m_config.isVerbose() || m_config.runServer()) {
|
||||||
|
cerr << shchar << "Added server: " << url << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const out_of_range &) {
|
|
||||||
cerr << shchar << "Warning: Included file \"" << path << "\" has no values." << endl;
|
|
||||||
}
|
}
|
||||||
|
} catch (const out_of_range &) {
|
||||||
|
cerr << shchar << "Warning: Included file \"" << path << "\" has no values." << endl;
|
||||||
}
|
}
|
||||||
// add sync db to internal map (use as index size + 1 because the local database has index 0)
|
|
||||||
m_syncDbs.emplace_back(make_unique<AlpmDatabase>(db, m_config.alpmDbPath(), m_syncDbs.size() + 1));
|
|
||||||
auto emplaced = m_syncDbMap.emplace(dbName, m_syncDbs.back().get());
|
|
||||||
if(usage & ALPM_DB_USAGE_UPGRADE) {
|
|
||||||
// -> db is used to upgrade local database
|
|
||||||
localDataBase()->upgradeSources() << emplaced.first->second;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cerr << shchar << "Error: Unable to add sync database [" << scope.first << ']' << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,9 +390,9 @@ void Manager::registerDataBasesFromPacmanConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Registers sync databases listed in the repository index configuration.
|
* \brief Adds sync databases listed in the repository index configuration.
|
||||||
*/
|
*/
|
||||||
void Manager::registerDatabasesFromRepoIndexConfig()
|
void Manager::addDatabasesFromRepoIndexConfig()
|
||||||
{
|
{
|
||||||
// check whether an entry already exists, if not create a new one
|
// check whether an entry already exists, if not create a new one
|
||||||
for(const RepoEntry &repoEntry : m_config.repoEntries()) {
|
for(const RepoEntry &repoEntry : m_config.repoEntries()) {
|
||||||
|
@ -422,13 +400,11 @@ void Manager::registerDatabasesFromRepoIndexConfig()
|
||||||
try {
|
try {
|
||||||
syncDb = m_syncDbMap.at(repoEntry.name());
|
syncDb = m_syncDbMap.at(repoEntry.name());
|
||||||
cerr << shchar << "Applying config for database [" << syncDb->name() << ']' << endl;
|
cerr << shchar << "Applying config for database [" << syncDb->name() << ']' << endl;
|
||||||
if(!repoEntry.dataBasePath().isEmpty()) {
|
if(!repoEntry.databasePath().isEmpty()) {
|
||||||
cerr << shchar << "Warning: Can't use data base path specified in repo index config because the repo \""
|
syncDb->setDatabasePath(repoEntry.databasePath());
|
||||||
<< repoEntry.name() << "\" has already been added from the Pacman config." << endl;
|
|
||||||
}
|
}
|
||||||
if(repoEntry.sigLevel()) {
|
if(repoEntry.sigLevel() != SignatureLevel::UseDefault) {
|
||||||
cerr << shchar << "Warning: Can't use sig level specified in repo index config because the repo \""
|
syncDb->setSigLevel(repoEntry.sigLevel());
|
||||||
<< repoEntry.name() << "\" has already been added from the Pacman config." << endl;
|
|
||||||
}
|
}
|
||||||
syncDb->setPackagesDirectory(repoEntry.packageDir());
|
syncDb->setPackagesDirectory(repoEntry.packageDir());
|
||||||
syncDb->setSourcesDirectory(repoEntry.sourceDir());
|
syncDb->setSourcesDirectory(repoEntry.sourceDir());
|
||||||
|
@ -438,24 +414,40 @@ void Manager::registerDatabasesFromRepoIndexConfig()
|
||||||
} else if(repoEntry.name().startsWith(QLatin1String("aur"), Qt::CaseInsensitive)) {
|
} else if(repoEntry.name().startsWith(QLatin1String("aur"), Qt::CaseInsensitive)) {
|
||||||
cerr << shchar << "Error: Unable to add database from repo index config: The database name mustn't start with \"aur\" because this name is reserved for the Arch Linux User Repository." << endl;
|
cerr << shchar << "Error: Unable to add database from repo index config: The database name mustn't start with \"aur\" because this name is reserved for the Arch Linux User Repository." << endl;
|
||||||
} else {
|
} else {
|
||||||
// TODO: database path
|
// determine path of db file
|
||||||
auto *db = alpm_register_syncdb(m_handle, repoEntry.name().toLocal8Bit().data(), static_cast<alpm_siglevel_t>(repoEntry.sigLevel()));
|
// -> currently just use the file from pacman dir, TODO: download syncdata base
|
||||||
m_syncDbs.emplace_back(make_unique<AlpmDatabase>(db, m_config.alpmDbPath(), m_syncDbs.size() + 1));
|
QString dbPath;
|
||||||
auto emplaced = m_syncDbMap.emplace(repoEntry.name(), m_syncDbs.back().get());
|
if(repoEntry.databasePath().isEmpty()) {
|
||||||
if(emplaced.second) {
|
QFileInfo dbPathRegular(m_config.alpmDbPath() % QStringLiteral("/sync/") % repoEntry.name() % QStringLiteral(".db"));
|
||||||
syncDb = emplaced.first->second;
|
QFileInfo dbPathWithFiles(m_config.alpmDbPath() % QStringLiteral("/sync/") % repoEntry.name() % QStringLiteral(".files"));
|
||||||
syncDb->setSourcesDirectory(repoEntry.sourceDir());
|
if(dbPathWithFiles.isFile() && (!dbPathRegular.isFile() || dbPathWithFiles.lastModified() > dbPathRegular.lastModified())) {
|
||||||
syncDb->setPackagesDirectory(repoEntry.packageDir());
|
dbPath = dbPathWithFiles.absolutePath();
|
||||||
if(m_config.isVerbose() || m_config.runServer()) {
|
} else if(dbPathRegular.isFile()) {
|
||||||
cerr << shchar << "Added database [" << repoEntry.name() << ']' << endl;
|
dbPath = dbPathRegular.absolutePath();
|
||||||
|
} else {
|
||||||
|
cerr << shchar << "Error: Unable to locate database file for [" << repoEntry.name().toLocal8Bit().data() << "]" << endl;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dbPath = repoEntry.databasePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// add sync db to internal map (use as index size + 1 because the local database has index 0)
|
||||||
|
m_syncDbs.emplace_back(make_unique<AlpmDatabase>(repoEntry.name(), dbPath, RepositoryUsage::None, repoEntry.sigLevel(), m_syncDbs.size() + 1));
|
||||||
|
syncDb = m_syncDbs.back().get();
|
||||||
|
m_syncDbMap.emplace(repoEntry.name(), syncDb);
|
||||||
|
|
||||||
|
syncDb->setSourcesDirectory(repoEntry.sourceDir());
|
||||||
|
syncDb->setPackagesDirectory(repoEntry.packageDir());
|
||||||
|
if(m_config.isVerbose() || m_config.runServer()) {
|
||||||
|
cerr << shchar << "Added database [" << repoEntry.name() << ']' << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(syncDb) {
|
if(syncDb) {
|
||||||
syncDb->addServerUrls(repoEntry.servers());
|
syncDb->serverUrls() << repoEntry.servers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add upgrade sources
|
// add upgrade sources
|
||||||
for(const RepoEntry &repoEntry : m_config.repoEntries()) {
|
for(const RepoEntry &repoEntry : m_config.repoEntries()) {
|
||||||
try {
|
try {
|
||||||
|
@ -471,17 +463,20 @@ void Manager::registerDatabasesFromRepoIndexConfig()
|
||||||
// entry should have been added before
|
// entry should have been added before
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Initiates all ALPM data bases.
|
* \brief Initiates all ALPM data bases.
|
||||||
* \remarks Must be called, after all relevant sync data bases have been registered (eg. via applyPacmanConfig()).
|
* \remarks Must be called, after all relevant sync databases have been added (eg. via applyPacmanConfig()).
|
||||||
*/
|
*/
|
||||||
void Manager::initAlpmDataBases(bool computeRequiredBy)
|
void Manager::initAlpmDataBases(bool computeRequiredBy)
|
||||||
{
|
{
|
||||||
// call the init method
|
|
||||||
{
|
{
|
||||||
|
// call the init method
|
||||||
|
if(m_config.isVerbose() || m_config.runServer()) {
|
||||||
|
cerr << "Initializing ALPM databases ... ";
|
||||||
|
cerr.flush();
|
||||||
|
}
|
||||||
QList<PackageLoader *> loaders;
|
QList<PackageLoader *> loaders;
|
||||||
loaders.reserve(m_syncDbMap.size() + 1);
|
loaders.reserve(m_syncDbMap.size() + 1);
|
||||||
loaders << localDataBase()->init();
|
loaders << localDataBase()->init();
|
||||||
|
@ -489,12 +484,25 @@ void Manager::initAlpmDataBases(bool computeRequiredBy)
|
||||||
loaders << syncDbEntry.second->init();
|
loaders << syncDbEntry.second->init();
|
||||||
}
|
}
|
||||||
for(auto *loader : loaders) {
|
for(auto *loader : loaders) {
|
||||||
loader->future().waitForFinished();
|
if(loader) {
|
||||||
delete loader;
|
loader->future().waitForFinished();
|
||||||
|
delete loader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(auto &syncDbEntry : m_syncDbMap) {
|
||||||
|
syncDbEntry.second->updateGroups();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(m_config.isVerbose() || m_config.runServer()) {
|
||||||
|
cerr << "DONE" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// compute required-by and optional-for
|
// compute required-by and optional-for
|
||||||
if(computeRequiredBy) {
|
if(computeRequiredBy) {
|
||||||
|
if(m_config.isVerbose() || m_config.runServer()) {
|
||||||
|
cerr << "Calculating required-by/optional-for ... ";
|
||||||
|
cerr.flush();
|
||||||
|
}
|
||||||
QList<QFuture<void> > futures;
|
QList<QFuture<void> > futures;
|
||||||
futures.reserve(m_syncDbMap.size() + 1);
|
futures.reserve(m_syncDbMap.size() + 1);
|
||||||
futures << localDataBase()->computeRequiredBy(*this);
|
futures << localDataBase()->computeRequiredBy(*this);
|
||||||
|
@ -504,7 +512,12 @@ void Manager::initAlpmDataBases(bool computeRequiredBy)
|
||||||
for(auto &future : futures) {
|
for(auto &future : futures) {
|
||||||
future.waitForFinished();
|
future.waitForFinished();
|
||||||
}
|
}
|
||||||
|
if(m_config.isVerbose() || m_config.runServer()) {
|
||||||
|
cerr << "DONE" << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -598,12 +611,11 @@ void Manager::maintainCache()
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Unregisters all registred sync databases.
|
* \brief Unregisters all registred sync databases.
|
||||||
|
* \remarks TODO
|
||||||
*/
|
*/
|
||||||
void Manager::unregisterSyncDataBases()
|
void Manager::unregisterSyncDataBases()
|
||||||
{
|
{
|
||||||
if(alpm_unregister_all_syncdbs(m_handle)) {
|
|
||||||
throw runtime_error(string("Cannot unregister sync databases: ") + alpm_strerror(alpm_errno(m_handle)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -636,7 +648,7 @@ const QJsonObject &Manager::basicRepoInfo() const
|
||||||
// check if the "sync" database is actually used for syncing
|
// check if the "sync" database is actually used for syncing
|
||||||
QReadLocker locker(syncDb.second->lock());
|
QReadLocker locker(syncDb.second->lock());
|
||||||
auto usage = syncDb.second->usage();
|
auto usage = syncDb.second->usage();
|
||||||
if((usage & ALPM_DB_USAGE_SYNC) || (usage & ALPM_DB_USAGE_INSTALL) || (usage & ALPM_DB_USAGE_UPGRADE)) {
|
if((usage & RepositoryUsage::Sync) || (usage & RepositoryUsage::Install) || (usage & RepositoryUsage::Upgrade)) {
|
||||||
m_basicRepoInfo.insert(syncDb.first, syncDb.second->basicInfo());
|
m_basicRepoInfo.insert(syncDb.first, syncDb.second->basicInfo());
|
||||||
} else {
|
} else {
|
||||||
m_basicRepoInfo.insert(syncDb.first, syncDb.second->basicInfo());
|
m_basicRepoInfo.insert(syncDb.first, syncDb.second->basicInfo());
|
||||||
|
@ -716,31 +728,21 @@ const QJsonArray &Manager::groupInfo() const
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Initiates the ALPM library handle and databases.
|
* \brief Add local database.
|
||||||
* \remarks Do not call this function, if ALPM is already initiated.
|
|
||||||
*/
|
*/
|
||||||
void Manager::initAlpmHandle()
|
void Manager::addLocalDatabase()
|
||||||
{
|
{
|
||||||
alpm_errno_t err;
|
m_localDb = make_unique<AlpmDatabase>(QStringLiteral("local"), config().alpmDbPath() % QStringLiteral("/local"), RepositoryUsage::None, SignatureLevel::UseDefault, 0);
|
||||||
if(!(m_handle = alpm_initialize(config().alpmRootDir().toLocal8Bit().data(), config().alpmDbPath().toLocal8Bit().data(), &err))) {
|
|
||||||
throw runtime_error(string("Cannot initialize ALPM: ") + alpm_strerror(err));
|
|
||||||
}
|
|
||||||
m_localDb = make_unique<AlpmDatabase>(alpm_get_localdb(m_handle), config().alpmDbPath(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Frees the ALPM library handle and databases.
|
* \brief Removes all ALPM databases.
|
||||||
* \remarks Do not call any ALPM related methods except initAlpmHandle() to reinit ALPM.
|
|
||||||
*/
|
*/
|
||||||
void Manager::cleanupAlpm()
|
void Manager::removeAllDatabases()
|
||||||
{
|
{
|
||||||
if(m_handle) {
|
m_localDb.reset();
|
||||||
alpm_release(m_handle);
|
m_syncDbs.clear();
|
||||||
m_handle = nullptr;
|
m_syncDbMap.clear();
|
||||||
m_localDb.reset();
|
|
||||||
m_syncDbs.clear();
|
|
||||||
m_syncDbMap.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include "./upgradelookup.h"
|
#include "./upgradelookup.h"
|
||||||
#include "./alpmpackage.h"
|
#include "./alpmpackage.h"
|
||||||
|
|
||||||
#include <alpm.h>
|
|
||||||
|
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
@ -21,6 +19,7 @@ namespace RepoIndex {
|
||||||
class Config;
|
class Config;
|
||||||
class UserRepository;
|
class UserRepository;
|
||||||
class AlpmDatabase;
|
class AlpmDatabase;
|
||||||
|
enum class RepositoryUsage;
|
||||||
|
|
||||||
class Manager
|
class Manager
|
||||||
{
|
{
|
||||||
|
@ -40,17 +39,17 @@ public:
|
||||||
|
|
||||||
// configuration, signature level, etc
|
// configuration, signature level, etc
|
||||||
const Config &config() const;
|
const Config &config() const;
|
||||||
int sigLevel() const;
|
SignatureLevel sigLevel() const;
|
||||||
void setSigLevel(int sigLevel);
|
void setSigLevel(SignatureLevel sigLevel);
|
||||||
int localFileSigLevel() const;
|
SignatureLevel localFileSigLevel() const;
|
||||||
void setLocalFileSigLevel(int sigLevel);
|
void setLocalFileSigLevel(SignatureLevel sigLevel);
|
||||||
const QString &pacmanCacheDir() const;
|
const QString &pacmanCacheDir() const;
|
||||||
static int parseSigLevel(const std::string &sigLevelStr = std::string());
|
static SignatureLevel parseSigLevel(const std::string &sigLevelStr = std::string());
|
||||||
static int parseUsage(const std::string &usageStr);
|
static RepositoryUsage parseUsage(const std::string &usageStr);
|
||||||
void initAlpmHandle();
|
void addLocalDatabase();
|
||||||
void cleanupAlpm();
|
void removeAllDatabases();
|
||||||
void registerDataBasesFromPacmanConfig();
|
void addDataBasesFromPacmanConfig();
|
||||||
void registerDatabasesFromRepoIndexConfig();
|
void addDatabasesFromRepoIndexConfig();
|
||||||
void initAlpmDataBases(bool computeRequiredBy);
|
void initAlpmDataBases(bool computeRequiredBy);
|
||||||
|
|
||||||
// caching
|
// caching
|
||||||
|
@ -71,11 +70,8 @@ public:
|
||||||
const AlpmPackage *packageFromDatabase(const QString &dbName, const QString &pkgName) const;
|
const AlpmPackage *packageFromDatabase(const QString &dbName, const QString &pkgName) const;
|
||||||
AlpmPackage *packageFromSyncDatabases(const QString &pkgName);
|
AlpmPackage *packageFromSyncDatabases(const QString &pkgName);
|
||||||
const AlpmPackage *packageFromSyncDatabases(const QString &pkgName) const;
|
const AlpmPackage *packageFromSyncDatabases(const QString &pkgName) const;
|
||||||
std::unique_ptr<AlpmOwnershipPackage> packageFromFile(const char *fileName, bool verifyIntegrity = false);
|
|
||||||
Package *packageProviding(const Dependency &dependency);
|
Package *packageProviding(const Dependency &dependency);
|
||||||
const Package *packageProviding(const Dependency &dependency) const;
|
const Package *packageProviding(const Dependency &dependency) const;
|
||||||
bool isPackageIgnored(const AlpmPackage *package) const;
|
|
||||||
void setInstallReason(AlpmPackage *package, alpm_pkgreason_t reason);
|
|
||||||
|
|
||||||
// repository lookup
|
// repository lookup
|
||||||
const AlpmDatabase *localDataBase() const;
|
const AlpmDatabase *localDataBase() const;
|
||||||
|
@ -99,9 +95,8 @@ private:
|
||||||
const Config &m_config;
|
const Config &m_config;
|
||||||
bool m_writeCacheBeforeGone;
|
bool m_writeCacheBeforeGone;
|
||||||
std::unique_ptr<QTimer> m_cacheTimer;
|
std::unique_ptr<QTimer> m_cacheTimer;
|
||||||
alpm_handle_t *m_handle;
|
SignatureLevel m_sigLevel;
|
||||||
int m_sigLevel;
|
SignatureLevel m_localFileSigLevel;
|
||||||
int m_localFileSigLevel;
|
|
||||||
QString m_pacmanCacheDir;
|
QString m_pacmanCacheDir;
|
||||||
QNetworkAccessManager m_networkAccessManager;
|
QNetworkAccessManager m_networkAccessManager;
|
||||||
std::unique_ptr<UserRepository> m_userRepo;
|
std::unique_ptr<UserRepository> m_userRepo;
|
||||||
|
@ -152,7 +147,7 @@ inline void Manager::setWriteCacheBeforeGone(bool writeCacheBeforeGone)
|
||||||
* when parsePacmanConfig() is called or can be set
|
* when parsePacmanConfig() is called or can be set
|
||||||
* manually using setSigLevel().
|
* manually using setSigLevel().
|
||||||
*/
|
*/
|
||||||
inline int Manager::sigLevel() const
|
inline SignatureLevel Manager::sigLevel() const
|
||||||
{
|
{
|
||||||
return m_sigLevel;
|
return m_sigLevel;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +155,7 @@ inline int Manager::sigLevel() const
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the signature level.
|
* \brief Sets the signature level.
|
||||||
*/
|
*/
|
||||||
inline void Manager::setSigLevel(int sigLevel)
|
inline void Manager::setSigLevel(SignatureLevel sigLevel)
|
||||||
{
|
{
|
||||||
m_sigLevel = sigLevel;
|
m_sigLevel = sigLevel;
|
||||||
}
|
}
|
||||||
|
@ -172,7 +167,7 @@ inline void Manager::setSigLevel(int sigLevel)
|
||||||
* when parsePacmanConfig() is called or can be set
|
* when parsePacmanConfig() is called or can be set
|
||||||
* manually using setSigLevel().
|
* manually using setSigLevel().
|
||||||
*/
|
*/
|
||||||
inline int Manager::localFileSigLevel() const
|
inline SignatureLevel Manager::localFileSigLevel() const
|
||||||
{
|
{
|
||||||
return m_localFileSigLevel;
|
return m_localFileSigLevel;
|
||||||
}
|
}
|
||||||
|
@ -180,19 +175,11 @@ inline int Manager::localFileSigLevel() const
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the signature level used when opening local files.
|
* \brief Sets the signature level used when opening local files.
|
||||||
*/
|
*/
|
||||||
inline void Manager::setLocalFileSigLevel(int sigLevel)
|
inline void Manager::setLocalFileSigLevel(SignatureLevel sigLevel)
|
||||||
{
|
{
|
||||||
m_localFileSigLevel = sigLevel;
|
m_localFileSigLevel = sigLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Returns whether the specified \a package is ignored.
|
|
||||||
*/
|
|
||||||
inline bool Manager::isPackageIgnored(const AlpmPackage *package) const
|
|
||||||
{
|
|
||||||
return alpm_pkg_should_ignore(m_handle, const_cast<alpm_pkg_t *>(package->ptr()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the Pacman cache directory.
|
* \brief Returns the Pacman cache directory.
|
||||||
* \remarks This is read from the Pacman configuration.
|
* \remarks This is read from the Pacman configuration.
|
||||||
|
|
|
@ -516,7 +516,7 @@ void MingwBundle::createBundle(const string &targetDir, const string &targetName
|
||||||
for(const auto &pkgFileStdStr : m_extraPackages) {
|
for(const auto &pkgFileStdStr : m_extraPackages) {
|
||||||
QString pkgFile = QString::fromLocal8Bit(pkgFileStdStr.data());
|
QString pkgFile = QString::fromLocal8Bit(pkgFileStdStr.data());
|
||||||
if(QFile::exists(pkgFile)) {
|
if(QFile::exists(pkgFile)) {
|
||||||
const auto pkg = m_manager.packageFromFile(pkgFileStdStr.data()); // do not catch the exception here
|
const auto pkg = make_unique<AlpmPackage>(pkgFile); // do not catch the exception here
|
||||||
pkgFiles.emplace_back(pkg->name().startsWith(QLatin1String("mingw-w64-")) ? pkg->name().mid(10) : pkg->name(), pkgFile);
|
pkgFiles.emplace_back(pkg->name().startsWith(QLatin1String("mingw-w64-")) ? pkg->name().mid(10) : pkg->name(), pkgFile);
|
||||||
} else {
|
} else {
|
||||||
throw runtime_error("The specified extra package \"" + pkgFileStdStr + "\" can't be found.");
|
throw runtime_error("The specified extra package \"" + pkgFileStdStr + "\" can't be found.");
|
||||||
|
|
114
alpm/package.cpp
114
alpm/package.cpp
|
@ -41,8 +41,8 @@ Package::Package(const QString &name, Repository *repository) :
|
||||||
m_hasInstallScript(false),
|
m_hasInstallScript(false),
|
||||||
m_hasBuildRelatedMetaData(false),
|
m_hasBuildRelatedMetaData(false),
|
||||||
m_hasInstallRelatedMetaData(false),
|
m_hasInstallRelatedMetaData(false),
|
||||||
m_validationMethods(ALPM_PKG_VALIDATION_UNKNOWN),
|
m_validationMethods(PackageValidation::Unknown),
|
||||||
m_installReason(ALPM_PKG_REASON_EXPLICIT),
|
m_installReason(InstallStatus::None),
|
||||||
m_id(-1),
|
m_id(-1),
|
||||||
m_categoryId(-1),
|
m_categoryId(-1),
|
||||||
m_votes(-1)
|
m_votes(-1)
|
||||||
|
@ -131,17 +131,17 @@ bool Package::matches(const QString &name, const QString &version, const Depende
|
||||||
if(name == dependency.name) {
|
if(name == dependency.name) {
|
||||||
PackageVersionComparsion cmp;
|
PackageVersionComparsion cmp;
|
||||||
switch(dependency.mode) {
|
switch(dependency.mode) {
|
||||||
case ALPM_DEP_MOD_ANY:
|
case DependencyMode::Any:
|
||||||
return true;
|
return true;
|
||||||
case ALPM_DEP_MOD_EQ:
|
case DependencyMode::Equal:
|
||||||
return PackageVersion(version).compare(PackageVersion(dependency.version)) == PackageVersionComparsion::Equal;
|
return PackageVersion(version).compare(PackageVersion(dependency.version)) == PackageVersionComparsion::Equal;
|
||||||
case ALPM_DEP_MOD_GE:
|
case DependencyMode::GreatherEqual:
|
||||||
return (cmp = PackageVersion(version).compare(PackageVersion(dependency.version))) == PackageVersionComparsion::Equal || cmp == PackageVersionComparsion::NewerThenSyncVersion;
|
return (cmp = PackageVersion(version).compare(PackageVersion(dependency.version))) == PackageVersionComparsion::Equal || cmp == PackageVersionComparsion::NewerThenSyncVersion;
|
||||||
case ALPM_DEP_MOD_LE:
|
case DependencyMode::LessEqual:
|
||||||
return (cmp = PackageVersion(version).compare(PackageVersion(dependency.version))) == PackageVersionComparsion::Equal || cmp == PackageVersionComparsion::PackageUpgradeOnly || cmp == PackageVersionComparsion::SoftwareUpgrade;
|
return (cmp = PackageVersion(version).compare(PackageVersion(dependency.version))) == PackageVersionComparsion::Equal || cmp == PackageVersionComparsion::PackageUpgradeOnly || cmp == PackageVersionComparsion::SoftwareUpgrade;
|
||||||
case ALPM_DEP_MOD_GT:
|
case DependencyMode::GreatherThen:
|
||||||
return PackageVersion(version).compare(PackageVersion(dependency.version)) == PackageVersionComparsion::NewerThenSyncVersion;
|
return PackageVersion(version).compare(PackageVersion(dependency.version)) == PackageVersionComparsion::NewerThenSyncVersion;
|
||||||
case ALPM_DEP_MOD_LT:
|
case DependencyMode::LessThen:
|
||||||
return (cmp = PackageVersion(version).compare(PackageVersion(dependency.version))) == PackageVersionComparsion::PackageUpgradeOnly || cmp == PackageVersionComparsion::SoftwareUpgrade;
|
return (cmp = PackageVersion(version).compare(PackageVersion(dependency.version))) == PackageVersionComparsion::PackageUpgradeOnly || cmp == PackageVersionComparsion::SoftwareUpgrade;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
|
@ -221,7 +221,7 @@ QDataStream &operator >>(QDataStream &in, QList<Dependency> &dependencies)
|
||||||
in >> version;
|
in >> version;
|
||||||
quint32 mode;
|
quint32 mode;
|
||||||
in >> mode;
|
in >> mode;
|
||||||
dependencies << Dependency(name, version, static_cast<_alpm_depmod_t>(mode));
|
dependencies << Dependency(name, version, static_cast<DependencyMode>(mode));
|
||||||
}
|
}
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ QJsonObject Package::detailedInfo() const
|
||||||
put(info, QStringLiteral("conf"), conflicts());
|
put(info, QStringLiteral("conf"), conflicts());
|
||||||
put(info, QStringLiteral("repl"), replaces());
|
put(info, QStringLiteral("repl"), replaces());
|
||||||
put(info, QStringLiteral("pack"), packager());
|
put(info, QStringLiteral("pack"), packager());
|
||||||
put(info, QStringLiteral("expl"), QJsonValue(installReason() == ALPM_PKG_REASON_EXPLICIT));
|
put(info, QStringLiteral("expl"), QJsonValue(installReason() == InstallStatus::Explicit));
|
||||||
put(info, QStringLiteral("scri"), QJsonValue(hasInstallScript()));
|
put(info, QStringLiteral("scri"), QJsonValue(hasInstallScript()));
|
||||||
put(info, QStringLiteral("sig"), Utilities::validationMethodsStrings(validationMethods()));
|
put(info, QStringLiteral("sig"), Utilities::validationMethodsStrings(validationMethods()));
|
||||||
put(info, QStringLiteral("file"), fileName());
|
put(info, QStringLiteral("file"), fileName());
|
||||||
|
@ -401,9 +401,9 @@ void Package::restoreFromCacheStream(QDataStream &in)
|
||||||
// installation related meta data
|
// installation related meta data
|
||||||
in >> m_hasInstallRelatedMetaData >> m_installDate >> m_installedSize >> m_backupFiles;
|
in >> m_hasInstallRelatedMetaData >> m_installDate >> m_installedSize >> m_backupFiles;
|
||||||
in >> tmp;
|
in >> tmp;
|
||||||
m_validationMethods = static_cast<alpm_pkgvalidation_t>(m_validationMethods); // TODO: validate value
|
m_validationMethods = static_cast<PackageValidation>(tmp); // TODO: validate value
|
||||||
in >> tmp;
|
in >> tmp;
|
||||||
m_installReason = static_cast<alpm_pkgreason_t>(m_installReason); // TODO: validate value
|
m_installReason = static_cast<InstallStatus>(tmp); // TODO: validate value
|
||||||
// source related meta data
|
// source related meta data
|
||||||
in >> m_hasSourceRelatedMetaData >> m_baseName >> m_architectures >> m_id
|
in >> m_hasSourceRelatedMetaData >> m_baseName >> m_architectures >> m_id
|
||||||
>> m_categoryId >> m_votes >> m_outOfDate
|
>> m_categoryId >> m_votes >> m_outOfDate
|
||||||
|
@ -581,6 +581,10 @@ void Package::putInfo(const QList<QPair<QString, QString> > &baseInfo, const QLi
|
||||||
m_hasBuildRelatedMetaData = includesBuildRelatedMetaData;
|
m_hasBuildRelatedMetaData = includesBuildRelatedMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \cond
|
||||||
|
*/
|
||||||
|
|
||||||
inline void put(QString &lhs, const QStringList &rhs)
|
inline void put(QString &lhs, const QStringList &rhs)
|
||||||
{
|
{
|
||||||
if(!rhs.isEmpty()) {
|
if(!rhs.isEmpty()) {
|
||||||
|
@ -603,6 +607,19 @@ inline void put(QJsonArray &lhs, const QStringList &rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void putFiles(QJsonArray &lhs, const QStringList &rhs)
|
||||||
|
{
|
||||||
|
for(const QString &value : rhs) {
|
||||||
|
QJsonObject fileObj;
|
||||||
|
fileObj.insert(QStringLiteral("name"), value);
|
||||||
|
lhs << fileObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \endcond
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Puts the specified desc/depends/files key value(s) pairs; clears current values before inserting new values.
|
* \brief Puts the specified desc/depends/files key value(s) pairs; clears current values before inserting new values.
|
||||||
* \remarks
|
* \remarks
|
||||||
|
@ -611,10 +628,11 @@ inline void put(QJsonArray &lhs, const QStringList &rhs)
|
||||||
* - Actual parsing of desc/depends/files is done in Repository::addPackagesFromSrcInfo() because one info file
|
* - Actual parsing of desc/depends/files is done in Repository::addPackagesFromSrcInfo() because one info file
|
||||||
* applies to multiple packages in case of split packages.
|
* applies to multiple packages in case of split packages.
|
||||||
*/
|
*/
|
||||||
void Package::putDescription(QString name, const QList<QPair<QString, QStringList> > &description)
|
void Package::putDescription(QString name, const QList<QPair<QString, QStringList> > &description, PackageOrigin origin)
|
||||||
{
|
{
|
||||||
// clear current meta data
|
// clear current meta data
|
||||||
m_hasInstallRelatedMetaData = false;
|
m_origin = origin;
|
||||||
|
m_hasInstallRelatedMetaData = origin == PackageOrigin::LocalDb;
|
||||||
m_fileName.clear();
|
m_fileName.clear();
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
m_upstreamUrl.clear();
|
m_upstreamUrl.clear();
|
||||||
|
@ -632,8 +650,8 @@ void Package::putDescription(QString name, const QList<QPair<QString, QStringLis
|
||||||
m_files = QJsonArray();
|
m_files = QJsonArray();
|
||||||
m_md5.clear();
|
m_md5.clear();
|
||||||
m_sha256.clear();
|
m_sha256.clear();
|
||||||
m_installReason = ALPM_PKG_REASON_EXPLICIT;
|
m_installReason = InstallStatus::None;
|
||||||
m_validationMethods = ALPM_PKG_VALIDATION_UNKNOWN;
|
m_validationMethods = PackageValidation::Unknown;
|
||||||
|
|
||||||
// prevent overwriting these crucial fields with empty values
|
// prevent overwriting these crucial fields with empty values
|
||||||
PackageVersion version;
|
PackageVersion version;
|
||||||
|
@ -696,28 +714,28 @@ void Package::putDescription(QString name, const QList<QPair<QString, QStringLis
|
||||||
} else if(field == QLatin1String("SHA256SUM")) {
|
} else if(field == QLatin1String("SHA256SUM")) {
|
||||||
put(m_sha256, values);
|
put(m_sha256, values);
|
||||||
} else if(field == QLatin1String("FILES")) {
|
} else if(field == QLatin1String("FILES")) {
|
||||||
put(m_files, values);
|
putFiles(m_files, values);
|
||||||
} else if(field == QLatin1String("REASON")) {
|
} else if(field == QLatin1String("REASON")) {
|
||||||
if(!values.isEmpty()) {
|
if(!values.isEmpty()) {
|
||||||
m_installReason = values.back().toUInt() == 1 ? ALPM_PKG_REASON_DEPEND : ALPM_PKG_REASON_EXPLICIT;
|
m_installReason = values.back().toUInt() == 1 ? InstallStatus::AsDependency : InstallStatus::Explicit;
|
||||||
}
|
}
|
||||||
} else if(field == QLatin1String("VALIDATION")) {
|
} else if(field == QLatin1String("VALIDATION")) {
|
||||||
if(values.isEmpty()) {
|
if(!values.isEmpty()) {
|
||||||
m_validationMethods = ALPM_PKG_VALIDATION_NONE;
|
|
||||||
} else {
|
|
||||||
for(const QString &value : values) {
|
for(const QString &value : values) {
|
||||||
if(value == QLatin1String("md5")) {
|
if(value == QLatin1String("md5")) {
|
||||||
m_validationMethods = static_cast<alpm_pkgvalidation_t>(m_validationMethods | ALPM_PKG_VALIDATION_MD5SUM);
|
m_validationMethods = m_validationMethods | PackageValidation::Md5Sum;
|
||||||
} else if(value == QLatin1String("sha256")) {
|
} else if(value == QLatin1String("sha256")) {
|
||||||
m_validationMethods = static_cast<alpm_pkgvalidation_t>(m_validationMethods | ALPM_PKG_VALIDATION_SHA256SUM);
|
m_validationMethods = m_validationMethods | PackageValidation::Sha256Sum;
|
||||||
} else if(value == QLatin1String("pgp")) {
|
} else if(value == QLatin1String("pgp")) {
|
||||||
m_validationMethods = static_cast<alpm_pkgvalidation_t>(m_validationMethods | ALPM_PKG_VALIDATION_SIGNATURE);
|
m_validationMethods = m_validationMethods | PackageValidation::Signature;
|
||||||
} else {
|
} else {
|
||||||
// TODO: error handling (imporant?)
|
// TODO: error handling (imporant?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_hasInstallRelatedMetaData = true;
|
m_hasInstallRelatedMetaData = true;
|
||||||
|
} else if(field == QLatin1String("GROUPS")) {
|
||||||
|
m_groups = values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,7 +823,7 @@ PackageVersion::PackageVersion()
|
||||||
*/
|
*/
|
||||||
QString RepoIndex::PackageVersion::toString() const
|
QString RepoIndex::PackageVersion::toString() const
|
||||||
{
|
{
|
||||||
if(epoch.isEmpty()) {
|
if(epoch.isEmpty() || epoch == QLatin1String("0")) {
|
||||||
return version % QChar('-') % (release.isEmpty() ? QStringLiteral("1") : release);
|
return version % QChar('-') % (release.isEmpty() ? QStringLiteral("1") : release);
|
||||||
} else {
|
} else {
|
||||||
return epoch % QChar(':') % version % QChar('-') % (release.isEmpty() ? QStringLiteral("1") : release);
|
return epoch % QChar(':') % version % QChar('-') % (release.isEmpty() ? QStringLiteral("1") : release);
|
||||||
|
@ -912,30 +930,30 @@ Dependency::Dependency(const QString &dependency)
|
||||||
}
|
}
|
||||||
int suffixBeg;
|
int suffixBeg;
|
||||||
if((suffixBeg = actualDependency.lastIndexOf(QLatin1String(">="))) > 0) {
|
if((suffixBeg = actualDependency.lastIndexOf(QLatin1String(">="))) > 0) {
|
||||||
mode = ALPM_DEP_MOD_GE;
|
mode = DependencyMode::GreatherEqual;
|
||||||
} else if((suffixBeg = actualDependency.lastIndexOf(QLatin1String("<="))) > 0) {
|
} else if((suffixBeg = actualDependency.lastIndexOf(QLatin1String("<="))) > 0) {
|
||||||
mode = ALPM_DEP_MOD_LE;
|
mode = DependencyMode::LessEqual;
|
||||||
} else if((suffixBeg = actualDependency.lastIndexOf(QChar('='))) > 0) {
|
} else if((suffixBeg = actualDependency.lastIndexOf(QChar('='))) > 0) {
|
||||||
mode = ALPM_DEP_MOD_EQ;
|
mode = DependencyMode::Equal;
|
||||||
} else if((suffixBeg = actualDependency.lastIndexOf(QChar('<'))) > 0) {
|
} else if((suffixBeg = actualDependency.lastIndexOf(QChar('<'))) > 0) {
|
||||||
mode = ALPM_DEP_MOD_LT;
|
mode = DependencyMode::LessThen;
|
||||||
} else if((suffixBeg = actualDependency.lastIndexOf(QChar('>'))) > 0) {
|
} else if((suffixBeg = actualDependency.lastIndexOf(QChar('>'))) > 0) {
|
||||||
mode = ALPM_DEP_MOD_GT;
|
mode = DependencyMode::GreatherThen;
|
||||||
} else {
|
} else {
|
||||||
mode = ALPM_DEP_MOD_ANY;
|
mode = DependencyMode::Any;
|
||||||
}
|
}
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case ALPM_DEP_MOD_ANY:
|
case DependencyMode::Any:
|
||||||
name = actualDependency.toString();
|
name = actualDependency.toString();
|
||||||
break;
|
break;
|
||||||
case ALPM_DEP_MOD_GE:
|
case DependencyMode::GreatherEqual:
|
||||||
case ALPM_DEP_MOD_LE:
|
case DependencyMode::LessEqual:
|
||||||
name = actualDependency.mid(0, suffixBeg).toString();
|
name = actualDependency.mid(0, suffixBeg).toString();
|
||||||
version = actualDependency.mid(suffixBeg + 2).toString();
|
version = actualDependency.mid(suffixBeg + 2).toString();
|
||||||
break;
|
break;
|
||||||
case ALPM_DEP_MOD_EQ:
|
case DependencyMode::Equal:
|
||||||
case ALPM_DEP_MOD_LT:
|
case DependencyMode::LessThen:
|
||||||
case ALPM_DEP_MOD_GT:
|
case DependencyMode::GreatherThen:
|
||||||
name = actualDependency.mid(0, suffixBeg).toString();
|
name = actualDependency.mid(0, suffixBeg).toString();
|
||||||
version = actualDependency.mid(suffixBeg + 1).toString();
|
version = actualDependency.mid(suffixBeg + 1).toString();
|
||||||
break;
|
break;
|
||||||
|
@ -947,15 +965,15 @@ Dependency::Dependency(const QString &dependency)
|
||||||
QString Dependency::toString() const
|
QString Dependency::toString() const
|
||||||
{
|
{
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case ALPM_DEP_MOD_EQ:
|
case DependencyMode::Equal:
|
||||||
return name % QChar('=') % version;
|
return name % QChar('=') % version;
|
||||||
case ALPM_DEP_MOD_GE:
|
case DependencyMode::GreatherEqual:
|
||||||
return name % QChar('>') % QChar('=') % version;
|
return name % QChar('>') % QChar('=') % version;
|
||||||
case ALPM_DEP_MOD_LE:
|
case DependencyMode::LessEqual:
|
||||||
return name % QChar('<') % QChar('=') % version;
|
return name % QChar('<') % QChar('=') % version;
|
||||||
case ALPM_DEP_MOD_GT:
|
case DependencyMode::GreatherThen:
|
||||||
return name % QChar('>') % version;
|
return name % QChar('>') % version;
|
||||||
case ALPM_DEP_MOD_LT:
|
case DependencyMode::LessThen:
|
||||||
return name % QChar('<') % version;
|
return name % QChar('<') % version;
|
||||||
default:
|
default:
|
||||||
return name;
|
return name;
|
||||||
|
@ -971,22 +989,22 @@ QJsonObject Dependency::toJson() const
|
||||||
obj.insert(QStringLiteral("name"), name);
|
obj.insert(QStringLiteral("name"), name);
|
||||||
obj.insert(QStringLiteral("ver"), version);
|
obj.insert(QStringLiteral("ver"), version);
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case ALPM_DEP_MOD_ANY:
|
case DependencyMode::Any:
|
||||||
obj.insert(QStringLiteral("mod"), QStringLiteral("any"));
|
obj.insert(QStringLiteral("mod"), QStringLiteral("any"));
|
||||||
break;
|
break;
|
||||||
case ALPM_DEP_MOD_EQ:
|
case DependencyMode::Equal:
|
||||||
obj.insert(QStringLiteral("mod"), QStringLiteral("eq"));
|
obj.insert(QStringLiteral("mod"), QStringLiteral("eq"));
|
||||||
break;
|
break;
|
||||||
case ALPM_DEP_MOD_GE:
|
case DependencyMode::GreatherEqual:
|
||||||
obj.insert(QStringLiteral("mod"), QStringLiteral("ge"));
|
obj.insert(QStringLiteral("mod"), QStringLiteral("ge"));
|
||||||
break;
|
break;
|
||||||
case ALPM_DEP_MOD_LE:
|
case DependencyMode::LessEqual:
|
||||||
obj.insert(QStringLiteral("mod"), QStringLiteral("le"));
|
obj.insert(QStringLiteral("mod"), QStringLiteral("le"));
|
||||||
break;
|
break;
|
||||||
case ALPM_DEP_MOD_GT:
|
case DependencyMode::GreatherThen:
|
||||||
obj.insert(QStringLiteral("mod"), QStringLiteral("gt"));
|
obj.insert(QStringLiteral("mod"), QStringLiteral("gt"));
|
||||||
break;
|
break;
|
||||||
case ALPM_DEP_MOD_LT:
|
case DependencyMode::LessThen:
|
||||||
obj.insert(QStringLiteral("mod"), QStringLiteral("lt"));
|
obj.insert(QStringLiteral("mod"), QStringLiteral("lt"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
164
alpm/package.h
164
alpm/package.h
|
@ -1,12 +1,8 @@
|
||||||
#ifndef ALPM_PACKAGE_H
|
#ifndef ALPM_PACKAGE_H
|
||||||
#define ALPM_PACKAGE_H
|
#define ALPM_PACKAGE_H
|
||||||
|
|
||||||
#include "./list.h"
|
|
||||||
|
|
||||||
#include <c++utilities/chrono/datetime.h>
|
#include <c++utilities/chrono/datetime.h>
|
||||||
|
|
||||||
#include <alpm.h>
|
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
@ -43,23 +39,106 @@ enum class PackageVersionPartComparsion
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The PackageOrigin enum describes where a Package instance comes from.
|
* \brief The PackageOrigin enum describes where a Package instance comes from.
|
||||||
|
* \remarks ALPM type: alpm_pkgfrom_t
|
||||||
*/
|
*/
|
||||||
enum class PackageOrigin
|
enum class PackageOrigin
|
||||||
{
|
{
|
||||||
Unknown = 20, /*! The origin is unknown. */
|
Unknown = 20, /*! The origin is unknown. */
|
||||||
File = ALPM_PKG_FROM_FILE, /*!< The instance has been created from a package file; source() returns nullptr in this case. */
|
File = 1, /*!< The instance has been created from a package file; source() returns nullptr in this case. */
|
||||||
LocalDb = ALPM_PKG_FROM_LOCALDB, /*! The instance is from the local data base; source() is an AlpmDataBase instance. */
|
LocalDb = 2, /*! The instance is from the local data base; source() is an AlpmDataBase instance. */
|
||||||
SyncDb = ALPM_PKG_FROM_SYNCDB, /*! The instance is from a sync data base; source() is an AlpmDataBase instance. */
|
SyncDb = 3, /*! The instance is from a sync data base; source() is an AlpmDataBase instance. */
|
||||||
Aur = 21 /*! The instance is from the AUR; source() is a UserRepository instance. */
|
Aur = 21 /*! The instance is from the AUR; source() is a UserRepository instance. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The InstallStatus enum specifies whether a package has been installed explicitely
|
||||||
|
* or as dependency.
|
||||||
|
*/
|
||||||
enum class InstallStatus
|
enum class InstallStatus
|
||||||
{
|
{
|
||||||
Explicit = ALPM_PKG_REASON_EXPLICIT,
|
Explicit = 0,
|
||||||
AsDependency = ALPM_PKG_REASON_DEPEND,
|
AsDependency = 1,
|
||||||
None = 20
|
None = 20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The PackageValidation enum specifies methods used to validate a package.
|
||||||
|
* \remarks ALMP type: alpm_pkgvalidation_t
|
||||||
|
*/
|
||||||
|
enum class PackageValidation {
|
||||||
|
Unknown = 0,
|
||||||
|
None = (1 << 0),
|
||||||
|
Md5Sum = (1 << 1),
|
||||||
|
Sha256Sum = (1 << 2),
|
||||||
|
Signature = (1 << 3)
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr PackageValidation operator |(PackageValidation lhs, PackageValidation rhs)
|
||||||
|
{
|
||||||
|
return static_cast<PackageValidation>(static_cast<int>(lhs) & static_cast<int>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator &(PackageValidation lhs, PackageValidation rhs)
|
||||||
|
{
|
||||||
|
return (static_cast<int>(lhs) & static_cast<int>(rhs)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The SignatureLevel enum specifies PGP signature verification options.
|
||||||
|
*/
|
||||||
|
enum class SignatureLevel {
|
||||||
|
Package = (1 << 0),
|
||||||
|
PackageOptional = (1 << 1),
|
||||||
|
PackageMarginalOk = (1 << 2),
|
||||||
|
PackageUnknownOk = (1 << 3),
|
||||||
|
|
||||||
|
Database = (1 << 10),
|
||||||
|
DatabaseOptional = (1 << 11),
|
||||||
|
DatabaseMarginalOk = (1 << 12),
|
||||||
|
DatabaseUnknownOk = (1 << 13),
|
||||||
|
|
||||||
|
UseDefault = (1 << 31)
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr SignatureLevel operator |(SignatureLevel lhs, SignatureLevel rhs)
|
||||||
|
{
|
||||||
|
return static_cast<SignatureLevel>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator &(SignatureLevel lhs, SignatureLevel rhs)
|
||||||
|
{
|
||||||
|
return (static_cast<int>(lhs) & static_cast<int>(rhs)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int operator ~(SignatureLevel lhs)
|
||||||
|
{
|
||||||
|
return ~static_cast<int>(lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline SignatureLevel &operator &=(SignatureLevel &lhs, int rhs)
|
||||||
|
{
|
||||||
|
lhs = static_cast<SignatureLevel>(static_cast<int>(lhs) & rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline SignatureLevel &operator |=(SignatureLevel &lhs, SignatureLevel rhs)
|
||||||
|
{
|
||||||
|
lhs = static_cast<SignatureLevel>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The SigStatus enum specifies PGP signature verification status return codes.
|
||||||
|
*/
|
||||||
|
enum class SignatureStatus {
|
||||||
|
Valid,
|
||||||
|
KeyExpired,
|
||||||
|
SigExpired,
|
||||||
|
KeyUnknown,
|
||||||
|
KeyDisabled,
|
||||||
|
InvalidId
|
||||||
|
};
|
||||||
|
|
||||||
class PackageVersion
|
class PackageVersion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -75,10 +154,23 @@ public:
|
||||||
QString release;
|
QString release;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The DependencyMode enum specifies the version constraints in dependency specs.
|
||||||
|
* \remarks ALPM: alpm_depmod_t
|
||||||
|
*/
|
||||||
|
enum class DependencyMode {
|
||||||
|
Any = 1, /*! No version constraint */
|
||||||
|
Equal, /*! Test version equality (package=x.y.z) */
|
||||||
|
GreatherEqual, /*! Test for at least a version (package>=x.y.z) */
|
||||||
|
LessEqual, /*! Test for at most a version (package<=x.y.z) */
|
||||||
|
GreatherThen, /*! Test for greater than some version (package>x.y.z) */
|
||||||
|
LessThen /*! Test for less than some version (package<x.y.z) */
|
||||||
|
};
|
||||||
|
|
||||||
class Dependency
|
class Dependency
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Dependency(const QString &name, const QString &version, _alpm_depmod_t mode = ALPM_DEP_MOD_ANY, const QString &description = QString());
|
explicit Dependency(const QString &name, const QString &version, DependencyMode mode = DependencyMode::Any, const QString &description = QString());
|
||||||
explicit Dependency(const QString &dependency);
|
explicit Dependency(const QString &dependency);
|
||||||
|
|
||||||
bool operator ==(const Dependency &other) const;
|
bool operator ==(const Dependency &other) const;
|
||||||
|
@ -88,11 +180,11 @@ public:
|
||||||
|
|
||||||
QString name;
|
QString name;
|
||||||
QString version;
|
QString version;
|
||||||
_alpm_depmod_t mode;
|
DependencyMode mode;
|
||||||
QString description;
|
QString description;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Dependency::Dependency(const QString &name, const QString &version, _alpm_depmod_t mode, const QString &description) :
|
inline Dependency::Dependency(const QString &name, const QString &version, DependencyMode mode, const QString &description) :
|
||||||
name(name),
|
name(name),
|
||||||
version(version),
|
version(version),
|
||||||
mode(mode),
|
mode(mode),
|
||||||
|
@ -106,7 +198,7 @@ inline bool Dependency::operator ==(const Dependency &other) const
|
||||||
|
|
||||||
inline uint qHash(const Dependency &dependency, uint seed)
|
inline uint qHash(const Dependency &dependency, uint seed)
|
||||||
{
|
{
|
||||||
return qHash(dependency.name, seed) ^ qHash(dependency.version, seed) ^ qHash(dependency.mode, seed) ^ qHash(dependency.description, seed);
|
return qHash(dependency.name, seed) ^ qHash(dependency.version, seed) ^ static_cast<uint>(dependency.mode) ^ seed ^ qHash(dependency.description, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Manager;
|
class Manager;
|
||||||
|
@ -136,8 +228,11 @@ public:
|
||||||
bool isRequiredByComputed() const;
|
bool isRequiredByComputed() const;
|
||||||
void computeRequiredBy(Manager &manager);
|
void computeRequiredBy(Manager &manager);
|
||||||
const QStringList &requiredBy() const;
|
const QStringList &requiredBy() const;
|
||||||
|
QStringList &requiredBy();
|
||||||
const QStringList &optionalFor() const;
|
const QStringList &optionalFor() const;
|
||||||
|
QStringList &optionalFor();
|
||||||
bool hasInstallScript() const;
|
bool hasInstallScript() const;
|
||||||
|
void setHasInstallScript(bool hasInstallScript);
|
||||||
|
|
||||||
// build related meta data
|
// build related meta data
|
||||||
bool hasBuildRelatedMetaData() const;
|
bool hasBuildRelatedMetaData() const;
|
||||||
|
@ -157,8 +252,8 @@ public:
|
||||||
ChronoUtilities::DateTime installDate() const;
|
ChronoUtilities::DateTime installDate() const;
|
||||||
uint32 installedSize() const;
|
uint32 installedSize() const;
|
||||||
const QStringList &backupFiles() const;
|
const QStringList &backupFiles() const;
|
||||||
alpm_pkgvalidation_t validationMethods() const;
|
PackageValidation validationMethods() const;
|
||||||
alpm_pkgreason_t installReason() const;
|
InstallStatus installReason() const;
|
||||||
|
|
||||||
// source related meta data
|
// source related meta data
|
||||||
bool hasSourceRelatedMetaData() const;
|
bool hasSourceRelatedMetaData() const;
|
||||||
|
@ -193,7 +288,7 @@ public:
|
||||||
|
|
||||||
// parsing .SRCINFO/.PKGINFO/desc/depends/files info
|
// parsing .SRCINFO/.PKGINFO/desc/depends/files info
|
||||||
void putInfo(const QList<QPair<QString, QString> > &baseInfo, const QList<QPair<QString, QString> > &pkgInfo, bool includesSourceRelatedMetaData = false, bool includesBuildRelatedMetaData = false);
|
void putInfo(const QList<QPair<QString, QString> > &baseInfo, const QList<QPair<QString, QString> > &pkgInfo, bool includesSourceRelatedMetaData = false, bool includesBuildRelatedMetaData = false);
|
||||||
void putDescription(QString name, const QList<QPair<QString, QStringList> > &description);
|
void putDescription(QString name, const QList<QPair<QString, QStringList> > &description, PackageOrigin origin);
|
||||||
void putSourceFile(const QString &path, const QByteArray &data);
|
void putSourceFile(const QString &path, const QByteArray &data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -242,8 +337,8 @@ protected:
|
||||||
ChronoUtilities::DateTime m_installDate;
|
ChronoUtilities::DateTime m_installDate;
|
||||||
uint32 m_installedSize;
|
uint32 m_installedSize;
|
||||||
QStringList m_backupFiles;
|
QStringList m_backupFiles;
|
||||||
alpm_pkgvalidation_t m_validationMethods;
|
PackageValidation m_validationMethods;
|
||||||
alpm_pkgreason_t m_installReason;
|
InstallStatus m_installReason;
|
||||||
|
|
||||||
// source related meta data
|
// source related meta data
|
||||||
bool m_hasSourceRelatedMetaData;
|
bool m_hasSourceRelatedMetaData;
|
||||||
|
@ -405,6 +500,14 @@ inline const QStringList &Package::requiredBy() const
|
||||||
return m_requiredBy;
|
return m_requiredBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns packages requiring this packages.
|
||||||
|
*/
|
||||||
|
inline QStringList &Package::requiredBy()
|
||||||
|
{
|
||||||
|
return m_requiredBy;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns packages having this package as optional dependency.
|
* \brief Returns packages having this package as optional dependency.
|
||||||
*/
|
*/
|
||||||
|
@ -413,6 +516,14 @@ inline const QStringList &Package::optionalFor() const
|
||||||
return m_optionalFor;
|
return m_optionalFor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns packages having this package as optional dependency.
|
||||||
|
*/
|
||||||
|
inline QStringList &Package::optionalFor()
|
||||||
|
{
|
||||||
|
return m_optionalFor;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns whether the package has an install script.
|
* \brief Returns whether the package has an install script.
|
||||||
*/
|
*/
|
||||||
|
@ -421,6 +532,14 @@ inline bool Package::hasInstallScript() const
|
||||||
return m_hasInstallScript;
|
return m_hasInstallScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets whether the package has an install script.
|
||||||
|
*/
|
||||||
|
inline void Package::setHasInstallScript(bool hasInstallScript)
|
||||||
|
{
|
||||||
|
m_hasInstallScript = hasInstallScript;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns whether the package has build-related meta data.
|
* \brief Returns whether the package has build-related meta data.
|
||||||
*
|
*
|
||||||
|
@ -554,7 +673,7 @@ inline const QStringList &Package::backupFiles() const
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the validation methods used during installation.
|
* \brief Returns the validation methods used during installation.
|
||||||
*/
|
*/
|
||||||
inline alpm_pkgvalidation_t Package::validationMethods() const
|
inline PackageValidation Package::validationMethods() const
|
||||||
{
|
{
|
||||||
return m_validationMethods;
|
return m_validationMethods;
|
||||||
}
|
}
|
||||||
|
@ -562,7 +681,7 @@ inline alpm_pkgvalidation_t Package::validationMethods() const
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns whether the package has been installed explicitely or as a dependency.
|
* \brief Returns whether the package has been installed explicitely or as a dependency.
|
||||||
*/
|
*/
|
||||||
inline alpm_pkgreason_t Package::installReason() const
|
inline InstallStatus Package::installReason() const
|
||||||
{
|
{
|
||||||
return m_installReason;
|
return m_installReason;
|
||||||
}
|
}
|
||||||
|
@ -694,6 +813,11 @@ inline PackageVersionComparsion Package::compareVersion(const Dependency &depend
|
||||||
return PackageVersion(version()).compare(PackageVersion(dependency.version));
|
return PackageVersion(version()).compare(PackageVersion(dependency.version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint qHash(const Package &package, uint seed)
|
||||||
|
{
|
||||||
|
return static_cast<uint>(((reinterpret_cast<quint64>(package.repository()) >> (8 * sizeof(uint) - 1)) ^ reinterpret_cast<quint64>(package.repository())) & (~0U)) ^ seed ^ qHash(package.name(), seed);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ALPM_PACKAGE_H
|
#endif // ALPM_PACKAGE_H
|
||||||
|
|
|
@ -61,7 +61,7 @@ void Reply::replyFinished()
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns a list of all package names.
|
* \brief Returns a list of all package names.
|
||||||
*/
|
*/
|
||||||
const QStringList RepoIndex::Repository::packageNames() const
|
const QStringList Repository::packageNames() const
|
||||||
{
|
{
|
||||||
QStringList names;
|
QStringList names;
|
||||||
names.reserve(m_packages.size());
|
names.reserve(m_packages.size());
|
||||||
|
@ -71,6 +71,16 @@ const QStringList RepoIndex::Repository::packageNames() const
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Repository::updateGroups()
|
||||||
|
{
|
||||||
|
m_groups.clear();
|
||||||
|
for(auto &entry : m_packages) {
|
||||||
|
for(const QString &group : entry.second->groups()) {
|
||||||
|
m_groups[group] << entry.second.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Initializes the repository.
|
* \brief Initializes the repository.
|
||||||
* \remarks
|
* \remarks
|
||||||
|
@ -107,8 +117,8 @@ Repository::Repository(const QString &name, uint32 index, QObject *parent) :
|
||||||
m_index(index),
|
m_index(index),
|
||||||
m_name(name),
|
m_name(name),
|
||||||
m_maxPackageAge(TimeSpan::infinity()),
|
m_maxPackageAge(TimeSpan::infinity()),
|
||||||
m_usage(static_cast<alpm_db_usage_t>(0)),
|
m_usage(RepositoryUsage::None),
|
||||||
m_sigLevel(static_cast<alpm_siglevel_t>(ALPM_SIGSTATUS_INVALID)),
|
m_sigLevel(SignatureLevel::UseDefault),
|
||||||
m_lock(QReadWriteLock::Recursive)
|
m_lock(QReadWriteLock::Recursive)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -266,14 +276,14 @@ QFuture<void> Repository::computeRequiredBy(Manager &manager, bool forceUpdate)
|
||||||
QJsonObject Repository::suggestions(const QString &term) const
|
QJsonObject Repository::suggestions(const QString &term) const
|
||||||
{
|
{
|
||||||
QJsonArray suggestions;
|
QJsonArray suggestions;
|
||||||
// size_t remainingSuggestions = 20;
|
// size_t remainingSuggestions = 20;
|
||||||
// for(auto i = packages().lower_bound(term), end = packages().cend(); i != end && remainingSuggestions; ++i, --remainingSuggestions) {
|
// for(auto i = packages().lower_bound(term), end = packages().cend(); i != end && remainingSuggestions; ++i, --remainingSuggestions) {
|
||||||
// if(i->first.startsWith(term, Qt::CaseInsensitive)) {
|
// if(i->first.startsWith(term, Qt::CaseInsensitive)) {
|
||||||
// suggestions << i->first;
|
// suggestions << i->first;
|
||||||
// } else {
|
// } else {
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
for(const auto &pkgEntry : packages()) {
|
for(const auto &pkgEntry : packages()) {
|
||||||
if(pkgEntry.first.contains(term, Qt::CaseInsensitive)) {
|
if(pkgEntry.first.contains(term, Qt::CaseInsensitive)) {
|
||||||
suggestions << pkgEntry.first;
|
suggestions << pkgEntry.first;
|
||||||
|
@ -543,15 +553,207 @@ void Repository::cleanOutdatedPackages()
|
||||||
for(auto i = m_packages.begin(); i != m_packages.end(); ) {
|
for(auto i = m_packages.begin(); i != m_packages.end(); ) {
|
||||||
const Package &pkg = *i->second;
|
const Package &pkg = *i->second;
|
||||||
if((now - pkg.timeStamp()) > maxPackageAge()) {
|
if((now - pkg.timeStamp()) > maxPackageAge()) {
|
||||||
i = m_packages.erase(i);
|
i = m_packages.erase(i);
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Repository::parsePkgInfo(const QByteArray &pkgInfo, QString &name, QList<QPair<QString, QString> > packageInfo)
|
||||||
|
{
|
||||||
|
// define states
|
||||||
|
enum {
|
||||||
|
FieldName, // reading field name (initial state)
|
||||||
|
EquationSign, // expecting equation sign
|
||||||
|
Pad, // expecting padding
|
||||||
|
FieldValue, // reading field value
|
||||||
|
Comment // reading comment
|
||||||
|
} state = FieldName;
|
||||||
|
|
||||||
|
// define variables to store parsing results
|
||||||
|
QByteArray currentFieldName;
|
||||||
|
currentFieldName.reserve(16);
|
||||||
|
QByteArray currentFieldValue;
|
||||||
|
currentFieldValue.reserve(32);
|
||||||
|
packageInfo.reserve(16);
|
||||||
|
|
||||||
|
// state machine: consumes each char of .SRCINFO
|
||||||
|
for(const char c : pkgInfo) {
|
||||||
|
switch(state) {
|
||||||
|
case FieldName:
|
||||||
|
switch(c) {
|
||||||
|
case '#':
|
||||||
|
// discard truncated line
|
||||||
|
currentFieldName.clear();
|
||||||
|
state = Comment;
|
||||||
|
case ' ':
|
||||||
|
// field name complete, expect equation sign
|
||||||
|
if(!currentFieldName.isEmpty()) {
|
||||||
|
state = EquationSign;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\n': case '\r': case '\t':
|
||||||
|
// discard truncated line
|
||||||
|
currentFieldName.clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
currentFieldName.append(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EquationSign:
|
||||||
|
switch(c) {
|
||||||
|
case '=':
|
||||||
|
state = Pad;
|
||||||
|
break;
|
||||||
|
case '\n': case '\r': case '\t':
|
||||||
|
// unexpected new line -> discard truncated line
|
||||||
|
currentFieldName.clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
; // ignore unexpected characters
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Pad:
|
||||||
|
switch(c) {
|
||||||
|
case ' ':
|
||||||
|
state = FieldValue;
|
||||||
|
break;
|
||||||
|
case '\n': case '\r': case '\t':
|
||||||
|
// unexpected new line -> discard truncated line
|
||||||
|
currentFieldName.clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
; // ignore unexpected characters
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FieldValue:
|
||||||
|
switch(c) {
|
||||||
|
case '\n': case '\r':
|
||||||
|
state = FieldName;
|
||||||
|
if(!currentFieldValue.isEmpty() && "pkgname" == currentFieldName) {
|
||||||
|
// put current info to current package
|
||||||
|
name = currentFieldValue;
|
||||||
|
}
|
||||||
|
packageInfo << QPair<QString, QString>(currentFieldName, currentFieldValue);
|
||||||
|
currentFieldName.clear();
|
||||||
|
currentFieldValue.clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
currentFieldValue.append(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Comment:
|
||||||
|
switch(c) {
|
||||||
|
case '\n': case '\r': case '\t':
|
||||||
|
state = FieldName;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
; // ignore outcommented characters
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Adds packages parsed from the specified .SRCINFO/.PKGINFO file.
|
* \brief Parses the specified package \a descriptions (desc/depends/files file).
|
||||||
|
*
|
||||||
|
* Stores the results in \a fields. The package name is also stored in \a name.
|
||||||
|
*/
|
||||||
|
void Repository::parseDescriptions(const QList<QByteArray> &descriptions, QString &name, QList<QPair<QString, QStringList> > &fields)
|
||||||
|
{
|
||||||
|
// define variables to store parsing results
|
||||||
|
QByteArray currentFieldName;
|
||||||
|
currentFieldName.reserve(16);
|
||||||
|
QByteArray currentFieldValue;
|
||||||
|
currentFieldValue.reserve(16);
|
||||||
|
QStringList currentFieldValues;
|
||||||
|
|
||||||
|
for(const QByteArray &description : descriptions) {
|
||||||
|
// define states
|
||||||
|
enum {
|
||||||
|
FieldName, // reading field name
|
||||||
|
NewLine, // expecting new line (after field name)
|
||||||
|
Next, // start reading next field value / next field name (initial state)
|
||||||
|
FieldValue, // reading field value
|
||||||
|
} state = Next;
|
||||||
|
|
||||||
|
// state machine: consumes each char of desc
|
||||||
|
for(const char c : description) {
|
||||||
|
switch(state) {
|
||||||
|
case FieldName:
|
||||||
|
switch(c) {
|
||||||
|
case '%':
|
||||||
|
state = NewLine;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
currentFieldName.append(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NewLine:
|
||||||
|
switch(c) {
|
||||||
|
case '\n': case '\r':
|
||||||
|
state = Next;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
; // ignore unexpected characters
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Next:
|
||||||
|
switch(c) {
|
||||||
|
case '\n': case '\r': case '\t': case ' ':
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
state = FieldName;
|
||||||
|
// next field -> put current field
|
||||||
|
if(!currentFieldName.isEmpty()) {
|
||||||
|
fields << QPair<QString, QStringList>(currentFieldName, currentFieldValues);
|
||||||
|
currentFieldName.clear();
|
||||||
|
currentFieldValues.clear();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = FieldValue;
|
||||||
|
currentFieldValue.append(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FieldValue:
|
||||||
|
switch(c) {
|
||||||
|
case '\n': case '\r':
|
||||||
|
state = Next;
|
||||||
|
currentFieldValues << currentFieldValue;
|
||||||
|
if(!currentFieldValue.isEmpty() && "NAME" == currentFieldName) {
|
||||||
|
name = currentFieldValues.back();
|
||||||
|
}
|
||||||
|
currentFieldValue.clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
currentFieldValue.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// all characters read
|
||||||
|
switch(state) {
|
||||||
|
case FieldValue:
|
||||||
|
currentFieldValues << currentFieldValue;
|
||||||
|
if(!currentFieldValue.isEmpty() && "NAME" == currentFieldName) {
|
||||||
|
name = currentFieldValues.back();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
// put last field
|
||||||
|
if(!currentFieldName.isEmpty()) {
|
||||||
|
fields << QPair<QString, QStringList>(currentFieldName, currentFieldValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds packages parsed from the specified .SRCINFO file.
|
||||||
* \remarks Updates existing packages.
|
* \remarks Updates existing packages.
|
||||||
* \returns Returns the added/updated packages. In the case of a split package more then
|
* \returns Returns the added/updated packages. In the case of a split package more then
|
||||||
* one package is returned.
|
* one package is returned.
|
||||||
|
@ -568,9 +770,9 @@ QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
|
||||||
} state = FieldName;
|
} state = FieldName;
|
||||||
|
|
||||||
// define variables to store parsing results
|
// define variables to store parsing results
|
||||||
QString currentFieldName;
|
QByteArray currentFieldName;
|
||||||
currentFieldName.reserve(16);
|
currentFieldName.reserve(16);
|
||||||
QString currentFieldValue;
|
QByteArray currentFieldValue;
|
||||||
currentFieldValue.reserve(32);
|
currentFieldValue.reserve(32);
|
||||||
QString packageBase;
|
QString packageBase;
|
||||||
packageBase.reserve(32);
|
packageBase.reserve(32);
|
||||||
|
@ -634,10 +836,10 @@ QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case '\n': case '\r':
|
case '\n': case '\r':
|
||||||
state = FieldName;
|
state = FieldName;
|
||||||
if(currentFieldName == QLatin1String("pkgbase")) {
|
if("pkgbase" == currentFieldName) {
|
||||||
// pkgbase
|
// pkgbase
|
||||||
packageBase = currentFieldValue;
|
packageBase = currentFieldValue;
|
||||||
} else if(currentFieldName == QLatin1String("pkgname")) {
|
} else if("pkgname" == currentFieldName) {
|
||||||
// next package
|
// next package
|
||||||
if(packageBase.isEmpty()) {
|
if(packageBase.isEmpty()) {
|
||||||
// no pkgbase specified -> use the first pkgname as pkgbase
|
// no pkgbase specified -> use the first pkgname as pkgbase
|
||||||
|
@ -646,6 +848,7 @@ QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
|
||||||
// put current info to current package
|
// put current info to current package
|
||||||
if(currentPackage) {
|
if(currentPackage) {
|
||||||
currentPackage->putInfo(baseInfo, packageInfo, true);
|
currentPackage->putInfo(baseInfo, packageInfo, true);
|
||||||
|
// TODO: add groups
|
||||||
packages << currentPackage;
|
packages << currentPackage;
|
||||||
}
|
}
|
||||||
// find next package
|
// find next package
|
||||||
|
@ -691,95 +894,37 @@ QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Adds packages parsed from the specified desc/depends/files file.
|
* \brief Adds packages parsed from the specified desc/depends/files file.
|
||||||
* \remarks Updates the package if it already exists.
|
* \remarks
|
||||||
* \returns Returns the added/updated package.
|
* - Updates the package if it already exists.
|
||||||
|
* - If \a name is empty and the description doesn't provide a name either, the package can not be added.
|
||||||
|
* \returns Returns the added/updated package or nullptr if no package could be added.
|
||||||
*/
|
*/
|
||||||
Package *Repository::addPackageFromDescription(QString name, const QList<QByteArray> &descriptions)
|
Package *Repository::addPackageFromDescription(QString name, const QList<QByteArray> &descriptions, PackageOrigin origin)
|
||||||
{
|
{
|
||||||
// define variables to store parsing results
|
// parse fields
|
||||||
QString currentFieldName;
|
|
||||||
currentFieldName.reserve(16);
|
|
||||||
QStringList currentFieldValues;
|
|
||||||
QList<QPair<QString, QStringList> > fields;
|
QList<QPair<QString, QStringList> > fields;
|
||||||
|
parseDescriptions(descriptions, name, fields);
|
||||||
|
|
||||||
for(const QByteArray &description : descriptions) {
|
// check whether name is empty
|
||||||
// define states
|
if(name.isEmpty()) {
|
||||||
enum {
|
return nullptr;
|
||||||
FieldName, // reading field name
|
|
||||||
NewLine, // expecting new line (after field name)
|
|
||||||
Next, // start reading next field value / next field name (initial state)
|
|
||||||
FieldValue, // reading field value
|
|
||||||
} state = Next;
|
|
||||||
|
|
||||||
// state machine: consumes each char of desc
|
|
||||||
for(const char c : description) {
|
|
||||||
switch(state) {
|
|
||||||
case FieldName:
|
|
||||||
switch(c) {
|
|
||||||
case '%':
|
|
||||||
state = NewLine;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
currentFieldName.append(c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NewLine:
|
|
||||||
switch(c) {
|
|
||||||
case '\n': case '\r':
|
|
||||||
state = Next;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
; // ignore unexpected characters
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Next:
|
|
||||||
switch(c) {
|
|
||||||
case '\n': case '\r': case '\t': case ' ':
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
state = FieldName;
|
|
||||||
// next field -> put current field
|
|
||||||
if(!currentFieldName.isEmpty()) {
|
|
||||||
if(!currentFieldValues.isEmpty() && currentFieldName == QLatin1String("NAME")) {
|
|
||||||
name = currentFieldValues.back();
|
|
||||||
}
|
|
||||||
fields << QPair<QString, QStringList>(currentFieldName, currentFieldValues);
|
|
||||||
currentFieldName.clear();
|
|
||||||
currentFieldValues.clear();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
state = FieldValue;
|
|
||||||
currentFieldValues << QString(QChar(c));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FieldValue:
|
|
||||||
switch(c) {
|
|
||||||
case '\n': case '\r':
|
|
||||||
state = Next;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
currentFieldValues.back().append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// put last field
|
|
||||||
if(!currentFieldName.isEmpty()) {
|
|
||||||
if(!currentFieldValues.isEmpty() && currentFieldName == QLatin1String("NAME")) {
|
|
||||||
name = currentFieldValues.back();
|
|
||||||
}
|
|
||||||
fields << QPair<QString, QStringList>(currentFieldName, currentFieldValues);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// find/create package for description
|
// find/create package for description
|
||||||
auto &pkg = m_packages[name];
|
Package *pkgRawPtr;
|
||||||
if(!pkg) {
|
{
|
||||||
pkg = emptyPackage();
|
QWriteLocker locker(&m_lock);
|
||||||
|
auto &pkgPtrRef = m_packages[name];
|
||||||
|
if(!pkgPtrRef) {
|
||||||
|
pkgPtrRef = emptyPackage();
|
||||||
|
}
|
||||||
|
pkgRawPtr = pkgPtrRef.get();
|
||||||
}
|
}
|
||||||
pkg->putDescription(name, fields);
|
|
||||||
return pkg.get();
|
// add groups
|
||||||
|
pkgRawPtr->putDescription(name, fields, origin);
|
||||||
|
|
||||||
|
return pkgRawPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace PackageManagement
|
} // namespace PackageManagement
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define PACKAGEMANAGEMENT_PACKAGESOURCE_H
|
#define PACKAGEMANAGEMENT_PACKAGESOURCE_H
|
||||||
|
|
||||||
#include "./package.h"
|
#include "./package.h"
|
||||||
#include "./group.h"
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
@ -169,6 +168,29 @@ enum class PackageDetailAvailability
|
||||||
FullRequest /*! The information is available after the requestFullPackageInfo() method has been called for the package. */
|
FullRequest /*! The information is available after the requestFullPackageInfo() method has been called for the package. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The RepositoryUsage enum specifies the usage of a repository.
|
||||||
|
*/
|
||||||
|
enum class RepositoryUsage {
|
||||||
|
None = 0,
|
||||||
|
Sync = 1, /*! The repository is used when synchronizing. */
|
||||||
|
Search = (1 << 1), /*! The repository is used when searching. */
|
||||||
|
Install = (1 << 2), /*! The repository is used to install packages. */
|
||||||
|
Upgrade = (1 << 3), /*! The repository is used to upgrade packages. */
|
||||||
|
All = (1 << 4) - 1, /*! The reposiotry is used for everything. */
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr bool operator &(RepositoryUsage lhs, RepositoryUsage rhs)
|
||||||
|
{
|
||||||
|
return (static_cast<int>(lhs) & static_cast<int>(rhs)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline RepositoryUsage &operator |=(RepositoryUsage &lhs, RepositoryUsage rhs)
|
||||||
|
{
|
||||||
|
lhs = static_cast<RepositoryUsage>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
class Repository : public QObject
|
class Repository : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -184,13 +206,16 @@ public:
|
||||||
const std::map<QString, std::unique_ptr<Package> > &packages() const;
|
const std::map<QString, std::unique_ptr<Package> > &packages() const;
|
||||||
std::map<QString, std::unique_ptr<Package> > &packages();
|
std::map<QString, std::unique_ptr<Package> > &packages();
|
||||||
const QStringList packageNames() const;
|
const QStringList packageNames() const;
|
||||||
alpm_db_usage_t usage() const;
|
RepositoryUsage usage() const;
|
||||||
bool isSourceOnly() const;
|
bool isSourceOnly() const;
|
||||||
bool isPackageOnly() const;
|
bool isPackageOnly() const;
|
||||||
std::map<QString, QList<Package *> > &groups();
|
std::map<QString, QList<Package *> > &groups();
|
||||||
const std::map<QString, QList<Package *> > &groups() const;
|
const std::map<QString, QList<Package *> > &groups() const;
|
||||||
|
void updateGroups();
|
||||||
const QStringList &serverUrls() const;
|
const QStringList &serverUrls() const;
|
||||||
alpm_siglevel_t sigLevel() const;
|
QStringList &serverUrls();
|
||||||
|
SignatureLevel sigLevel() const;
|
||||||
|
void setSigLevel(SignatureLevel sigLevel);
|
||||||
|
|
||||||
// gathering data
|
// gathering data
|
||||||
virtual PackageLoader *init();
|
virtual PackageLoader *init();
|
||||||
|
@ -241,8 +266,10 @@ public:
|
||||||
void wipePackages();
|
void wipePackages();
|
||||||
|
|
||||||
// parsing src/pkg info
|
// parsing src/pkg info
|
||||||
|
static void parsePkgInfo(const QByteArray &pkgInfo, QString &name, QList<QPair<QString, QString> > packageInfo);
|
||||||
|
static void parseDescriptions(const QList<QByteArray> &descriptions, QString &name, QList<QPair<QString, QStringList> > &fields);
|
||||||
QList<Package *> addPackagesFromSrcInfo(const QByteArray &srcInfo);
|
QList<Package *> addPackagesFromSrcInfo(const QByteArray &srcInfo);
|
||||||
Package *addPackageFromDescription(QString name, const QList<QByteArray> &descriptions);
|
Package *addPackageFromDescription(QString name, const QList<QByteArray> &descriptions, PackageOrigin origin);
|
||||||
|
|
||||||
// thread synchronization
|
// thread synchronization
|
||||||
QReadWriteLock *lock() const;
|
QReadWriteLock *lock() const;
|
||||||
|
@ -258,10 +285,10 @@ protected:
|
||||||
QString m_description;
|
QString m_description;
|
||||||
std::map<QString, std::unique_ptr<Package> > m_packages;
|
std::map<QString, std::unique_ptr<Package> > m_packages;
|
||||||
ChronoUtilities::TimeSpan m_maxPackageAge;
|
ChronoUtilities::TimeSpan m_maxPackageAge;
|
||||||
alpm_db_usage_t m_usage;
|
RepositoryUsage m_usage;
|
||||||
std::map<QString, QList<Package *> > m_groups;
|
std::map<QString, QList<Package *> > m_groups;
|
||||||
QStringList m_serverUrls;
|
QStringList m_serverUrls;
|
||||||
alpm_siglevel_t m_sigLevel;
|
SignatureLevel m_sigLevel;
|
||||||
QList<Repository *> m_upgradeSources;
|
QList<Repository *> m_upgradeSources;
|
||||||
QString m_srcDir;
|
QString m_srcDir;
|
||||||
QString m_pkgDir;
|
QString m_pkgDir;
|
||||||
|
@ -362,16 +389,26 @@ inline Package *Repository::packageByName(const QString &name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline alpm_db_usage_t Repository::usage() const
|
/*!
|
||||||
|
* \brief Returns the operations the repository is used for.
|
||||||
|
*/
|
||||||
|
inline RepositoryUsage Repository::usage() const
|
||||||
{
|
{
|
||||||
return m_usage;
|
return m_usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the groups the packages of the repository belong to.
|
||||||
|
*/
|
||||||
inline std::map<QString, QList<Package *> > &Repository::groups()
|
inline std::map<QString, QList<Package *> > &Repository::groups()
|
||||||
{
|
{
|
||||||
return m_groups;
|
return m_groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the groups the packages of the repository belong to.
|
||||||
|
*/
|
||||||
inline const std::map<QString, QList<Package *> > &Repository::groups() const
|
inline const std::map<QString, QList<Package *> > &Repository::groups() const
|
||||||
{
|
{
|
||||||
return m_groups;
|
return m_groups;
|
||||||
|
@ -385,14 +422,31 @@ inline const QStringList &Repository::serverUrls() const
|
||||||
return m_serverUrls;
|
return m_serverUrls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the server URLs.
|
||||||
|
* \remarks This non-const version is used by the manager to add the servers.
|
||||||
|
*/
|
||||||
|
inline QStringList &Repository::serverUrls()
|
||||||
|
{
|
||||||
|
return m_serverUrls;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the signature level of the database.
|
* \brief Returns the signature level of the database.
|
||||||
*/
|
*/
|
||||||
inline alpm_siglevel_t Repository::sigLevel() const
|
inline SignatureLevel Repository::sigLevel() const
|
||||||
{
|
{
|
||||||
return m_sigLevel;
|
return m_sigLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the signature level.
|
||||||
|
*/
|
||||||
|
inline void Repository::setSigLevel(SignatureLevel sigLevel)
|
||||||
|
{
|
||||||
|
m_sigLevel = sigLevel;
|
||||||
|
}
|
||||||
|
|
||||||
inline const QList<Repository *> &Repository::upgradeSources() const
|
inline const QList<Repository *> &Repository::upgradeSources() const
|
||||||
{
|
{
|
||||||
return m_upgradeSources;
|
return m_upgradeSources;
|
||||||
|
|
|
@ -16,50 +16,38 @@ namespace RepoIndex {
|
||||||
|
|
||||||
namespace Utilities {
|
namespace Utilities {
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Returns the package names of the specified \a dependencyList.
|
|
||||||
*/
|
|
||||||
list<string> getNames(DependencyList dependencyList)
|
|
||||||
{
|
|
||||||
list<string> res;
|
|
||||||
for(auto dependency : dependencyList) {
|
|
||||||
res.push_back(dependency->name);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns string representations for the specified \a sigLevel.
|
* \brief Returns string representations for the specified \a sigLevel.
|
||||||
*/
|
*/
|
||||||
QJsonArray sigLevelStrings(alpm_siglevel_t sigLevel)
|
QJsonArray sigLevelStrings(SignatureLevel sigLevel)
|
||||||
{
|
{
|
||||||
QJsonArray options;
|
QJsonArray options;
|
||||||
if(sigLevel & ALPM_SIG_PACKAGE) {
|
if(sigLevel & SignatureLevel::Package) {
|
||||||
options << QStringLiteral("package");
|
options << QStringLiteral("package");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_PACKAGE_OPTIONAL) {
|
if(sigLevel & SignatureLevel::PackageOptional) {
|
||||||
options << QStringLiteral("package optional");
|
options << QStringLiteral("package optional");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_PACKAGE_MARGINAL_OK) {
|
if(sigLevel & SignatureLevel::PackageMarginalOk) {
|
||||||
options << QStringLiteral("package marginal ok");
|
options << QStringLiteral("package marginal ok");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_PACKAGE_UNKNOWN_OK) {
|
if(sigLevel & SignatureLevel::PackageUnknownOk) {
|
||||||
options << QStringLiteral("package unknown ok");
|
options << QStringLiteral("package unknown ok");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_DATABASE) {
|
if(sigLevel & SignatureLevel::Database) {
|
||||||
options << QStringLiteral("database");
|
options << QStringLiteral("database");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_DATABASE_OPTIONAL) {
|
if(sigLevel & SignatureLevel::DatabaseOptional) {
|
||||||
options << QStringLiteral("database optional");
|
options << QStringLiteral("database optional");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_DATABASE_MARGINAL_OK) {
|
if(sigLevel & SignatureLevel::DatabaseMarginalOk) {
|
||||||
options << QStringLiteral("database marginal ok");
|
options << QStringLiteral("database marginal ok");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_DATABASE_UNKNOWN_OK) {
|
if(sigLevel & SignatureLevel::DatabaseUnknownOk) {
|
||||||
options << QStringLiteral("database unknown ok");
|
options << QStringLiteral("database unknown ok");
|
||||||
}
|
}
|
||||||
if(sigLevel & ALPM_SIG_USE_DEFAULT) {
|
if(sigLevel & SignatureLevel::UseDefault) {
|
||||||
options << QStringLiteral("use default");
|
options << QStringLiteral("default");
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
@ -67,39 +55,42 @@ QJsonArray sigLevelStrings(alpm_siglevel_t sigLevel)
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns string representations for the specified database \a usage.
|
* \brief Returns string representations for the specified database \a usage.
|
||||||
*/
|
*/
|
||||||
QJsonArray usageStrings(alpm_db_usage_t usage)
|
QJsonArray usageStrings(RepositoryUsage usage)
|
||||||
{
|
{
|
||||||
QJsonArray strings;
|
QJsonArray strings;
|
||||||
if(usage & ALPM_DB_USAGE_SYNC) {
|
if(usage & RepositoryUsage::Sync) {
|
||||||
strings << QStringLiteral("refreshing");
|
strings << QStringLiteral("refreshing");
|
||||||
}
|
}
|
||||||
if(usage & ALPM_DB_USAGE_SEARCH) {
|
if(usage & RepositoryUsage::Search) {
|
||||||
strings << QStringLiteral("searching");
|
strings << QStringLiteral("searching");
|
||||||
}
|
}
|
||||||
if(usage & ALPM_DB_USAGE_INSTALL) {
|
if(usage & RepositoryUsage::Install) {
|
||||||
strings << QStringLiteral("installing");
|
strings << QStringLiteral("installing");
|
||||||
}
|
}
|
||||||
if(usage & ALPM_DB_USAGE_UPGRADE) {
|
if(usage & RepositoryUsage::Upgrade) {
|
||||||
strings << QStringLiteral("upgrading");
|
strings << QStringLiteral("upgrading");
|
||||||
}
|
}
|
||||||
|
if(strings.empty()) {
|
||||||
|
strings << QStringLiteral("none");
|
||||||
|
}
|
||||||
return strings;
|
return strings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the string representation for the specified \a sigStatus.
|
* \brief Returns the string representation for the specified \a sigStatus.
|
||||||
*/
|
*/
|
||||||
QString sigStatusString(alpm_sigstatus_t sigStatus)
|
QString sigStatusString(SignatureStatus sigStatus)
|
||||||
{
|
{
|
||||||
switch(sigStatus) {
|
switch(sigStatus) {
|
||||||
case ALPM_SIGSTATUS_VALID:
|
case SignatureStatus::Valid:
|
||||||
return QStringLiteral("valid");
|
return QStringLiteral("valid");
|
||||||
case ALPM_SIGSTATUS_KEY_EXPIRED:
|
case SignatureStatus::KeyExpired:
|
||||||
return QStringLiteral("key expired");
|
return QStringLiteral("key expired");
|
||||||
case ALPM_SIGSTATUS_SIG_EXPIRED:
|
case SignatureStatus::SigExpired:
|
||||||
return QStringLiteral("sig expired");
|
return QStringLiteral("sig expired");
|
||||||
case ALPM_SIGSTATUS_KEY_UNKNOWN:
|
case SignatureStatus::KeyUnknown:
|
||||||
return QStringLiteral("key unknown");
|
return QStringLiteral("key unknown");
|
||||||
case ALPM_SIGSTATUS_KEY_DISABLED:
|
case SignatureStatus::KeyDisabled:
|
||||||
return QStringLiteral("key disabled");
|
return QStringLiteral("key disabled");
|
||||||
default:
|
default:
|
||||||
return QStringLiteral("invalid");
|
return QStringLiteral("invalid");
|
||||||
|
@ -109,19 +100,19 @@ QString sigStatusString(alpm_sigstatus_t sigStatus)
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the string representation for the specified \a validationMethods.
|
* \brief Returns the string representation for the specified \a validationMethods.
|
||||||
*/
|
*/
|
||||||
QJsonArray validationMethodsStrings(alpm_pkgvalidation_t validationMethods)
|
QJsonArray validationMethodsStrings(PackageValidation validationMethods)
|
||||||
{
|
{
|
||||||
QJsonArray jsonArray;
|
QJsonArray jsonArray;
|
||||||
if(validationMethods & 0x1) {
|
if(validationMethods & PackageValidation::None) {
|
||||||
jsonArray << QStringLiteral("none");
|
jsonArray << QStringLiteral("none");
|
||||||
}
|
}
|
||||||
if(validationMethods & 0x2) {
|
if(validationMethods & PackageValidation::Md5Sum) {
|
||||||
jsonArray << QStringLiteral("MD5");
|
jsonArray << QStringLiteral("MD5");
|
||||||
}
|
}
|
||||||
if(validationMethods & 0x4) {
|
if(validationMethods & PackageValidation::Sha256Sum) {
|
||||||
jsonArray << QStringLiteral("SHA256");
|
jsonArray << QStringLiteral("SHA256");
|
||||||
}
|
}
|
||||||
if(validationMethods & 0x8) {
|
if(validationMethods & PackageValidation::Signature) {
|
||||||
jsonArray << QStringLiteral("signature");
|
jsonArray << QStringLiteral("signature");
|
||||||
}
|
}
|
||||||
if(jsonArray.empty()) {
|
if(jsonArray.empty()) {
|
||||||
|
@ -130,78 +121,6 @@ QJsonArray validationMethodsStrings(alpm_pkgvalidation_t validationMethods)
|
||||||
return jsonArray;
|
return jsonArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonArray qjarry(StringList list)
|
|
||||||
{
|
|
||||||
QJsonArray jsonArray;
|
|
||||||
for(const char *str : list) {
|
|
||||||
jsonArray << qstr(str);
|
|
||||||
}
|
|
||||||
return jsonArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonArray qjarry(DependencyList list)
|
|
||||||
{
|
|
||||||
QJsonArray jsonArray;
|
|
||||||
for(alpm_depend_t *dep : list) {
|
|
||||||
QJsonObject depObj;
|
|
||||||
depObj.insert(QStringLiteral("name"), dep->name);
|
|
||||||
depObj.insert(QStringLiteral("desc"), dep->desc);
|
|
||||||
depObj.insert(QStringLiteral("ver"), dep->version);
|
|
||||||
switch(dep->mod) {
|
|
||||||
case ALPM_DEP_MOD_ANY:
|
|
||||||
depObj.insert(QStringLiteral("mod"), QStringLiteral("any"));
|
|
||||||
break;
|
|
||||||
case ALPM_DEP_MOD_EQ:
|
|
||||||
depObj.insert(QStringLiteral("mod"), QStringLiteral("eq"));
|
|
||||||
break;
|
|
||||||
case ALPM_DEP_MOD_GE:
|
|
||||||
depObj.insert(QStringLiteral("mod"), QStringLiteral("ge"));
|
|
||||||
break;
|
|
||||||
case ALPM_DEP_MOD_LE:
|
|
||||||
depObj.insert(QStringLiteral("mod"), QStringLiteral("le"));
|
|
||||||
break;
|
|
||||||
case ALPM_DEP_MOD_GT:
|
|
||||||
depObj.insert(QStringLiteral("mod"), QStringLiteral("gt"));
|
|
||||||
break;
|
|
||||||
case ALPM_DEP_MOD_LT:
|
|
||||||
depObj.insert(QStringLiteral("mod"), QStringLiteral("lt"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
jsonArray << depObj;
|
|
||||||
}
|
|
||||||
return jsonArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonArray qjarry(_alpm_pkgvalidation_t validation)
|
|
||||||
{
|
|
||||||
QJsonArray jsonArray;
|
|
||||||
if(validation & 0x1) {
|
|
||||||
jsonArray << QStringLiteral("none");
|
|
||||||
}
|
|
||||||
if(validation & 0x2) {
|
|
||||||
jsonArray << QStringLiteral("MD5");
|
|
||||||
}
|
|
||||||
if(validation & 0x4) {
|
|
||||||
jsonArray << QStringLiteral("SHA256");
|
|
||||||
}
|
|
||||||
if(validation & 0x8) {
|
|
||||||
jsonArray << QStringLiteral("signature");
|
|
||||||
}
|
|
||||||
if(jsonArray.empty()) {
|
|
||||||
jsonArray << QStringLiteral("unknown");
|
|
||||||
}
|
|
||||||
return jsonArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList qstrlist(StringList list)
|
|
||||||
{
|
|
||||||
QStringList strings;
|
|
||||||
for(const auto *str : list) {
|
|
||||||
strings << qstr(str);
|
|
||||||
}
|
|
||||||
return strings;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printValues(ostream &output, const char *label, const QStringList &values)
|
void printValues(ostream &output, const char *label, const QStringList &values)
|
||||||
{
|
{
|
||||||
output << label << ':';
|
output << label << ':';
|
||||||
|
@ -242,6 +161,18 @@ void printError(string &message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stripVersion(QString &packageName)
|
||||||
|
{
|
||||||
|
int lastHyphen = packageName.lastIndexOf(QChar('-'));
|
||||||
|
if(lastHyphen > 0) {
|
||||||
|
packageName.remove(lastHyphen, packageName.size() - lastHyphen);
|
||||||
|
int lastHyphen = packageName.lastIndexOf(QChar('-'));
|
||||||
|
if(lastHyphen > 0) {
|
||||||
|
packageName.remove(lastHyphen, packageName.size() - lastHyphen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Alpm
|
} // namespace Alpm
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#ifndef ALPM_UTILITIES_H
|
#ifndef ALPM_UTILITIES_H
|
||||||
#define ALPM_UTILITIES_H
|
#define ALPM_UTILITIES_H
|
||||||
|
|
||||||
#include "./list.h"
|
#include "repository.h"
|
||||||
|
#include "package.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QJsonArray)
|
QT_FORWARD_DECLARE_CLASS(QJsonArray)
|
||||||
|
|
||||||
|
@ -14,16 +14,11 @@ namespace RepoIndex {
|
||||||
|
|
||||||
namespace Utilities {
|
namespace Utilities {
|
||||||
|
|
||||||
std::list<std::string> getNames(DependencyList dependencyList);
|
QJsonArray sigLevelStrings(SignatureLevel sigLevel);
|
||||||
QJsonArray sigLevelStrings(alpm_siglevel_t sigLevel);
|
QJsonArray usageStrings(RepositoryUsage usage);
|
||||||
QJsonArray usageStrings(alpm_db_usage_t usage);
|
QString sigStatusString(SignatureStatus sigStatus);
|
||||||
QString sigStatusString(alpm_sigstatus_t sigStatus);
|
QJsonArray validationMethodsStrings(PackageValidation validationMethods);
|
||||||
QJsonArray validationMethodsStrings(alpm_pkgvalidation_t validationMethods);
|
void stripVersion(QString &packageName);
|
||||||
|
|
||||||
QJsonArray qjarry(StringList list);
|
|
||||||
QJsonArray qjarry(DependencyList list);
|
|
||||||
QJsonArray qjarry(_alpm_pkgvalidation_t validation);
|
|
||||||
QStringList qstrlist(StringList list);
|
|
||||||
|
|
||||||
inline QString qstr(const char *str)
|
inline QString qstr(const char *str)
|
||||||
{
|
{
|
||||||
|
|
4
main.cpp
4
main.cpp
|
@ -53,8 +53,8 @@ int main(int argc, char *argv[])
|
||||||
// setup manager
|
// setup manager
|
||||||
Manager manager(config);
|
Manager manager(config);
|
||||||
cerr << shchar << "Loading databases ..." << endl;
|
cerr << shchar << "Loading databases ..." << endl;
|
||||||
manager.registerDataBasesFromPacmanConfig();
|
manager.addDataBasesFromPacmanConfig();
|
||||||
manager.registerDatabasesFromRepoIndexConfig();
|
manager.addDatabasesFromRepoIndexConfig();
|
||||||
manager.initAlpmDataBases(configArgs.serverArg.isPresent());
|
manager.initAlpmDataBases(configArgs.serverArg.isPresent());
|
||||||
cerr << shchar << "Restoring cache ..." << endl;
|
cerr << shchar << "Restoring cache ..." << endl;
|
||||||
manager.restoreCache();
|
manager.restoreCache();
|
||||||
|
|
|
@ -130,10 +130,10 @@ void Connection::handleCmd(const QJsonObject &obj)
|
||||||
} else if(what == QLatin1String("reinitalpm")) {
|
} else if(what == QLatin1String("reinitalpm")) {
|
||||||
if(m_socket->peerAddress().isLoopback()) {
|
if(m_socket->peerAddress().isLoopback()) {
|
||||||
cerr << shchar << "Info: Reinit of ALPM databases triggered via web interface." << endl;
|
cerr << shchar << "Info: Reinit of ALPM databases triggered via web interface." << endl;
|
||||||
m_manager.cleanupAlpm();
|
m_manager.removeAllDatabases();
|
||||||
m_manager.initAlpmHandle();
|
m_manager.addLocalDatabase();
|
||||||
m_manager.registerDataBasesFromPacmanConfig();
|
m_manager.addDataBasesFromPacmanConfig();
|
||||||
m_manager.registerDatabasesFromRepoIndexConfig();
|
m_manager.addDatabasesFromRepoIndexConfig();
|
||||||
m_manager.initAlpmDataBases(true);
|
m_manager.initAlpmDataBases(true);
|
||||||
} else {
|
} else {
|
||||||
sendError(QStringLiteral("rejected"), id);
|
sendError(QStringLiteral("rejected"), id);
|
||||||
|
|
|
@ -27,11 +27,9 @@ CONFIG(release, debug|release) {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
alpm/manager.h \
|
alpm/manager.h \
|
||||||
alpm/package.h \
|
alpm/package.h \
|
||||||
alpm/list.h \
|
|
||||||
alpm/utilities.h \
|
alpm/utilities.h \
|
||||||
network/server.h \
|
network/server.h \
|
||||||
network/connection.h \
|
network/connection.h \
|
||||||
alpm/group.h \
|
|
||||||
alpm/config.h \
|
alpm/config.h \
|
||||||
alpm/resolvebuildorder.h \
|
alpm/resolvebuildorder.h \
|
||||||
alpm/mingwbundle.h \
|
alpm/mingwbundle.h \
|
||||||
|
@ -53,7 +51,6 @@ SOURCES += \
|
||||||
alpm/utilities.cpp \
|
alpm/utilities.cpp \
|
||||||
network/server.cpp \
|
network/server.cpp \
|
||||||
network/connection.cpp \
|
network/connection.cpp \
|
||||||
alpm/group.cpp \
|
|
||||||
alpm/config.cpp \
|
alpm/config.cpp \
|
||||||
alpm/resolvebuildorder.cpp \
|
alpm/resolvebuildorder.cpp \
|
||||||
alpm/mingwbundle.cpp \
|
alpm/mingwbundle.cpp \
|
||||||
|
@ -102,7 +99,6 @@ CONFIG(debug, debug|release) {
|
||||||
} else {
|
} else {
|
||||||
LIBS += -lc++utilities
|
LIBS += -lc++utilities
|
||||||
}
|
}
|
||||||
LIBS += -lalpm
|
|
||||||
|
|
||||||
# installs
|
# installs
|
||||||
target.path = $$(INSTALL_ROOT)/bin
|
target.path = $$(INSTALL_ROOT)/bin
|
||||||
|
|
Loading…
Reference in New Issue