added desc parser, minor adjustments
This commit is contained in:
parent
82d4ae2eb7
commit
69b0d7e258
|
@ -125,5 +125,10 @@ bool AlpmDatabase::addServerUrls(const QStringList &urls)
|
|||
return res;
|
||||
}
|
||||
|
||||
std::unique_ptr<Package> AlpmDatabase::emptyPackage()
|
||||
{
|
||||
return make_unique<AlpmPackage>(this);
|
||||
}
|
||||
|
||||
} // namespace Alpm
|
||||
|
||||
|
|
|
@ -49,6 +49,9 @@ public:
|
|||
signals:
|
||||
void initiated();
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Package> emptyPackage();
|
||||
|
||||
private:
|
||||
alpm_db_t *m_ptr;
|
||||
QString m_dbFile;
|
||||
|
|
|
@ -37,6 +37,14 @@ using namespace Utilities;
|
|||
* \brief The AlpmPackage class wraps an ALPM package struct and holds additional meta information.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs an empty ALPM package.
|
||||
*/
|
||||
AlpmPackage::AlpmPackage(AlpmDatabase *repository) :
|
||||
Package(QString(), repository),
|
||||
m_ptr(nullptr)
|
||||
{}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a new instance for the specified ALPM \a package.
|
||||
*/
|
||||
|
@ -64,7 +72,7 @@ AlpmPackage::AlpmPackage(alpm_pkg_t *package, AlpmDatabase *alpmDatabase) :
|
|||
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_packer = qstr(alpm_pkg_get_packager(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));
|
||||
|
|
|
@ -10,6 +10,7 @@ class AlpmDatabase;
|
|||
class AlpmPackage : public Package
|
||||
{
|
||||
public:
|
||||
AlpmPackage(AlpmDatabase *repository);
|
||||
AlpmPackage(alpm_pkg_t *package, AlpmDatabase *alpmDatabase);
|
||||
AlpmPackage(alpm_pkg_t *package);
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ ConfigArgs::ConfigArgs(ArgumentParser &parser) :
|
|||
defaultIconThemeArg("default-icon-theme", string(), "specifies the name of the default icon theme (should be included in --icon-packages)"),
|
||||
extraPackagesArg("extra-packages", string(), "specifies extra packages to be included"),
|
||||
cacheDirArg("cache-dir", string(), "specifies the cache directory (default is /var/cache/repoindex)"),
|
||||
storageDirArg("storage-dir", string(), "specifies the storage directory (default is /var/lib/repoindex)"),
|
||||
shSyntaxArg("sh-syntax", string(), "prints the output using shell syntax: export REPOINDEX_RESULTS=('res1' 'res2' 'res3') or export REPOINDEX_ERROR='some error message'"),
|
||||
repoArg("repo", string(), "specifies the repository")
|
||||
{
|
||||
|
@ -130,6 +131,9 @@ ConfigArgs::ConfigArgs(ArgumentParser &parser) :
|
|||
cacheDirArg.setCombinable(true);
|
||||
cacheDirArg.setRequiredValueCount(1);
|
||||
cacheDirArg.setValueNames(pathValueName);
|
||||
storageDirArg.setCombinable(true);
|
||||
storageDirArg.setRequiredValueCount(1);
|
||||
storageDirArg.setValueNames(pathValueName);
|
||||
parser.setMainArguments({&buildOrderArg, &upgradeLookupArg, &serverArg, &mingwBundleArg, &repoindexConfArg, &repoindexConfArg, &cacheDirArg, &helpArg});
|
||||
}
|
||||
|
||||
|
@ -146,6 +150,7 @@ Config::Config() :
|
|||
m_alpmDbPath(QStringLiteral("/var/lib/pacman")),
|
||||
m_pacmanConfFile(QStringLiteral("/etc/pacman.conf")),
|
||||
m_cacheDir(QStringLiteral("/var/cache/repoindex")),
|
||||
m_storageDir(QStringLiteral("/var/lib/repoindex")),
|
||||
m_websocketServerListeningAddr(QHostAddress::LocalHost),
|
||||
m_websocketServerListeningPort(1234),
|
||||
m_serverInsecure(false),
|
||||
|
@ -234,6 +239,7 @@ void Config::loadFromConfigFile(const QString &configFilePath)
|
|||
m_alpmDbPath = alpmObj.value(QStringLiteral("dbPath")).toString(m_alpmDbPath);
|
||||
m_pacmanConfFile = alpmObj.value(QStringLiteral("pacmanConfigFile")).toString(m_pacmanConfFile);
|
||||
m_cacheDir = mainObj.value(QStringLiteral("cacheDir")).toString(m_cacheDir);
|
||||
m_storageDir = mainObj.value(QStringLiteral("storageDir")).toString(m_storageDir);
|
||||
auto aurObj = mainObj.value(QStringLiteral("aur")).toObject();
|
||||
m_aurEnabled = aurObj.value(QStringLiteral("enabled")).toBool(m_aurEnabled);
|
||||
auto serverObj = mainObj.value(QStringLiteral("server")).toObject();
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
ApplicationUtilities::Argument defaultIconThemeArg;
|
||||
ApplicationUtilities::Argument extraPackagesArg;
|
||||
ApplicationUtilities::Argument cacheDirArg;
|
||||
ApplicationUtilities::Argument storageDirArg;
|
||||
ApplicationUtilities::Argument shSyntaxArg;
|
||||
ApplicationUtilities::Argument repoArg;
|
||||
};
|
||||
|
@ -143,6 +144,7 @@ private:
|
|||
QString m_alpmDbPath;
|
||||
QString m_pacmanConfFile;
|
||||
QString m_cacheDir;
|
||||
QString m_storageDir;
|
||||
|
||||
QHostAddress m_websocketServerListeningAddr;
|
||||
quint16 m_websocketServerListeningPort;
|
||||
|
|
274
alpm/package.cpp
274
alpm/package.cpp
|
@ -328,7 +328,7 @@ QJsonObject Package::detailedInfo() const
|
|||
put(info, QStringLiteral("optf"), optionalFor());
|
||||
put(info, QStringLiteral("conf"), conflicts());
|
||||
put(info, QStringLiteral("repl"), replaces());
|
||||
put(info, QStringLiteral("pack"), packer());
|
||||
put(info, QStringLiteral("pack"), packager());
|
||||
put(info, QStringLiteral("expl"), QJsonValue(installReason() == ALPM_PKG_REASON_EXPLICIT));
|
||||
put(info, QStringLiteral("scri"), QJsonValue(hasInstallScript()));
|
||||
put(info, QStringLiteral("sig"), Utilities::validationMethodsStrings(validationMethods()));
|
||||
|
@ -348,7 +348,7 @@ QJsonObject Package::simpleInfo() const
|
|||
put(info, QStringLiteral("bdate"), buildDate());
|
||||
put(info, QStringLiteral("url"), upstreamUrl());
|
||||
put(info, QStringLiteral("lic"), licenses());
|
||||
put(info, QStringLiteral("packer"), packer());
|
||||
put(info, QStringLiteral("packer"), packager());
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ void Package::writeToCacheStream(QDataStream &out)
|
|||
<< m_groups << m_dependencies << m_optionalDependencies << m_conflicts << m_provides
|
||||
<< m_replaces << m_requiredByComputed << m_requiredBy << m_optionalFor << m_hasInstallScript;
|
||||
// build related meta data
|
||||
out << m_hasBuildRelatedMetaData << m_fileName << m_files << m_buildDate << m_packer
|
||||
out << m_hasBuildRelatedMetaData << m_fileName << m_files << m_buildDate << m_packager
|
||||
<< m_md5 << m_sha256 << m_buildArchitecture << m_packageSize << m_makeDependencies;
|
||||
// installation related meta data
|
||||
out << m_hasInstallRelatedMetaData << m_installDate << m_installedSize << m_backupFiles
|
||||
|
@ -396,7 +396,7 @@ void Package::restoreFromCacheStream(QDataStream &in)
|
|||
>> m_groups >> m_dependencies >> m_optionalDependencies >> m_conflicts >> m_provides
|
||||
>> m_replaces >> m_requiredByComputed >> m_requiredBy >> m_optionalFor >> m_hasInstallScript;
|
||||
// build related meta data
|
||||
in >> m_hasBuildRelatedMetaData >> m_fileName >> m_files >> m_buildDate >> m_packer
|
||||
in >> m_hasBuildRelatedMetaData >> m_fileName >> m_files >> m_buildDate >> m_packager
|
||||
>> m_md5 >> m_sha256 >> m_buildArchitecture >> m_packageSize >> m_makeDependencies;
|
||||
// installation related meta data
|
||||
in >> m_hasInstallRelatedMetaData >> m_installDate >> m_installedSize >> m_backupFiles;
|
||||
|
@ -423,32 +423,101 @@ void Package::restoreFromCacheStream(QDataStream &in)
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Puts the specified src/pkg info key value pairs; clears current dependencies, provides, ... before inserting new values.
|
||||
* \remarks This method should only be called by the associated repository because it must handle a possible name change.
|
||||
* \brief Puts the specified .SRCINFO/.PKGINFO key value pairs; clears current values before inserting new values.
|
||||
* \remarks
|
||||
* - This method should only be called by the associated repository because the associated repository might
|
||||
* has to handle a possible name change.
|
||||
* - Actual parsing of .SRCINFO/.PKGINFO is done in Repository::addPackagesFromSrcInfo() because one info file
|
||||
* applies to multiple packages in case of split packages.
|
||||
*/
|
||||
void Package::putInfo(const QList<QPair<QString, QString> > &baseInfo, const QList<QPair<QString, QString> > &pkgInfo, bool includesSourceRelatedMetaData)
|
||||
void Package::putInfo(const QList<QPair<QString, QString> > &baseInfo, const QList<QPair<QString, QString> > &pkgInfo, bool includesSourceRelatedMetaData, bool includesBuildRelatedMetaData)
|
||||
{
|
||||
// clear current values
|
||||
m_baseName.clear();
|
||||
m_description.clear();
|
||||
m_upstreamUrl.clear();
|
||||
m_packager.clear();
|
||||
m_licenses.clear();
|
||||
m_dependencies.clear();
|
||||
m_makeDependencies.clear();
|
||||
m_checkDependencies.clear();
|
||||
m_optionalDependencies.clear();
|
||||
m_conflicts.clear();
|
||||
m_provides.clear();
|
||||
m_replaces.clear();
|
||||
// read specified key value pairs
|
||||
if(includesBuildRelatedMetaData) {
|
||||
m_buildArchitecture.clear();
|
||||
}
|
||||
if(includesSourceRelatedMetaData) {
|
||||
m_architectures.clear();
|
||||
m_makeDependencies.clear();
|
||||
m_checkDependencies.clear();
|
||||
m_installedSize = 0;
|
||||
m_buildDate = DateTime();
|
||||
m_packager.clear();
|
||||
}
|
||||
|
||||
// prevent overwriting these crucial fields with empty values
|
||||
QString name;
|
||||
PackageVersion version;
|
||||
QStringList archs;
|
||||
|
||||
// read specified key value pairs
|
||||
const auto infos = {baseInfo, pkgInfo};
|
||||
for(const auto &info : infos) {
|
||||
for(const auto &pair : info) {
|
||||
const auto &field = pair.first;
|
||||
if(field == QLatin1String("pkgbase")) {
|
||||
m_baseName.clear();
|
||||
} else if(field == QLatin1String("pkgname")) {
|
||||
name.clear();
|
||||
} else if(field == QLatin1String("epoch")) {
|
||||
version.epoch.clear();
|
||||
} else if(field == QLatin1String("pkgver")) {
|
||||
version.version.clear();
|
||||
} else if(field == QLatin1String("pkgrel")) {
|
||||
version.release.clear();
|
||||
} else if(field == QLatin1String("pkgdesc")) {
|
||||
m_description.clear();
|
||||
} else if(field == QLatin1String("url")) {
|
||||
m_upstreamUrl.clear();
|
||||
} else if(field == QLatin1String("arch")) {
|
||||
if(includesSourceRelatedMetaData) {
|
||||
m_architectures.clear();
|
||||
}
|
||||
if(includesBuildRelatedMetaData) {
|
||||
m_buildArchitecture.clear();
|
||||
}
|
||||
} else if(field == QLatin1String("license")) {
|
||||
m_licenses.clear();
|
||||
} else if(field == QLatin1String("depends")) {
|
||||
m_dependencies.clear();
|
||||
} else if(field == QLatin1String("makedepends")) {
|
||||
m_makeDependencies.clear();
|
||||
} else if(field == QLatin1String("checkdepends")) {
|
||||
m_checkDependencies.clear();
|
||||
} else if(field == QLatin1String("optdepends")) {
|
||||
m_optionalDependencies.clear();
|
||||
} else if(field == QLatin1String("conflicts")) {
|
||||
m_conflicts.clear();
|
||||
} else if(field == QLatin1String("provides")) {
|
||||
m_provides.clear();
|
||||
} else if(field == QLatin1String("replaces")) {
|
||||
m_replaces.clear();
|
||||
} else if(field == QLatin1String("source")) {
|
||||
// currently not used
|
||||
} else if(field == QLatin1String("size")) {
|
||||
m_installedSize = 0;
|
||||
} else if(field == QLatin1String("builddate")) {
|
||||
m_buildDate = DateTime();
|
||||
} else if(field == QLatin1String("packager")) {
|
||||
m_packager.clear();
|
||||
}
|
||||
}
|
||||
for(const auto &pair : info) {
|
||||
const auto &field = pair.first;
|
||||
const auto &value = pair.second;
|
||||
if(field == QLatin1String("pkgbase")) {
|
||||
m_baseName = value;
|
||||
} else if(field == QLatin1String("pkgname")) {
|
||||
m_name = value;
|
||||
name = value;
|
||||
} else if(field == QLatin1String("epoch")) {
|
||||
version.epoch = value;
|
||||
} else if(field == QLatin1String("pkgver")) {
|
||||
|
@ -460,7 +529,12 @@ void Package::putInfo(const QList<QPair<QString, QString> > &baseInfo, const QLi
|
|||
} else if(field == QLatin1String("url")) {
|
||||
m_upstreamUrl = value;
|
||||
} else if(field == QLatin1String("arch")) {
|
||||
archs << value;
|
||||
if(includesSourceRelatedMetaData) {
|
||||
m_architectures << value;
|
||||
}
|
||||
if(includesBuildRelatedMetaData) {
|
||||
m_buildArchitecture = value;
|
||||
}
|
||||
} else if(field == QLatin1String("license")) {
|
||||
m_licenses << value;
|
||||
} else if(field == QLatin1String("depends")) {
|
||||
|
@ -479,26 +553,196 @@ void Package::putInfo(const QList<QPair<QString, QString> > &baseInfo, const QLi
|
|||
m_replaces << Dependency(value);
|
||||
} else if(field == QLatin1String("source")) {
|
||||
// currently not used
|
||||
} else if(field == QLatin1String("size")) {
|
||||
m_installedSize = value.toUInt();
|
||||
} else if(field == QLatin1String("builddate")) {
|
||||
m_buildDate = DateTime::fromTimeStampGmt(value.toUInt());
|
||||
} else if(field == QLatin1String("packager")) {
|
||||
m_packager = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure crucial information is still present (use old values rather than no values)
|
||||
if(!name.isEmpty()) {
|
||||
m_name = name;
|
||||
}
|
||||
if(!version.version.isEmpty()) {
|
||||
m_version = version.toString();
|
||||
}
|
||||
if(!archs.isEmpty()) {
|
||||
m_architectures.swap(archs);
|
||||
// use the name as base name if the base name hasn't been specified explicitely
|
||||
if(includesSourceRelatedMetaData && m_baseName.isEmpty()) {
|
||||
m_baseName = m_name;
|
||||
}
|
||||
|
||||
// consider general information as complete
|
||||
m_hasGeneralInfo = m_hasAllGeneralInfo = true;
|
||||
m_hasSourceRelatedMetaData = includesSourceRelatedMetaData;
|
||||
m_hasBuildRelatedMetaData = includesBuildRelatedMetaData;
|
||||
}
|
||||
|
||||
inline void put(QString &lhs, const QStringList &rhs)
|
||||
{
|
||||
if(!rhs.isEmpty()) {
|
||||
lhs = rhs.back();
|
||||
}
|
||||
}
|
||||
|
||||
inline void put(QList<Dependency> &lhs, const QStringList &rhs)
|
||||
{
|
||||
lhs.reserve(rhs.size());
|
||||
for(const QString &dep : rhs) {
|
||||
lhs << Dependency(dep);
|
||||
}
|
||||
}
|
||||
|
||||
inline void put(QJsonArray &lhs, const QStringList &rhs)
|
||||
{
|
||||
for(const QString &value : rhs) {
|
||||
lhs << value;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Puts the specified desc/depends/files key value(s) pairs; clears current values before inserting new values.
|
||||
* \remarks
|
||||
* - This method should only be called by the associated repository because the associated repository might
|
||||
* has to handle a possible name change.
|
||||
* - Actual parsing of desc/depends/files is done in Repository::addPackagesFromSrcInfo() because one info file
|
||||
* applies to multiple packages in case of split packages.
|
||||
*/
|
||||
void Package::putDescription(QString name, const QList<QPair<QString, QStringList> > &description)
|
||||
{
|
||||
// clear current meta data
|
||||
m_hasInstallRelatedMetaData = false;
|
||||
m_fileName.clear();
|
||||
m_description.clear();
|
||||
m_upstreamUrl.clear();
|
||||
m_buildArchitecture.clear();
|
||||
m_licenses.clear();
|
||||
m_dependencies.clear();
|
||||
m_makeDependencies.clear();
|
||||
m_checkDependencies.clear();
|
||||
m_optionalDependencies.clear();
|
||||
m_conflicts.clear();
|
||||
m_provides.clear();
|
||||
m_replaces.clear();
|
||||
m_buildDate = m_installDate = DateTime();
|
||||
m_packageSize = m_installedSize = 0;
|
||||
m_files = QJsonArray();
|
||||
m_md5.clear();
|
||||
m_sha256.clear();
|
||||
m_installReason = ALPM_PKG_REASON_EXPLICIT;
|
||||
m_validationMethods = ALPM_PKG_VALIDATION_UNKNOWN;
|
||||
|
||||
// prevent overwriting these crucial fields with empty values
|
||||
PackageVersion version;
|
||||
|
||||
for(const auto &pair : description) {
|
||||
const auto &field = pair.first;
|
||||
const auto &values = pair.second;
|
||||
if(field == QLatin1String("FILENAME")) {
|
||||
put(m_fileName, values);
|
||||
} else if(field == QLatin1String("NAME")) {
|
||||
put(name, values);
|
||||
} else if(field == QLatin1String("VERSION")) {
|
||||
if(!values.isEmpty()) {
|
||||
version = PackageVersion(values.back());
|
||||
}
|
||||
} else if(field == QLatin1String("DESC")) {
|
||||
put(m_description, values);
|
||||
} else if(field == QLatin1String("URL")) {
|
||||
put(m_upstreamUrl, values);
|
||||
} else if(field == QLatin1String("ARCH")) {
|
||||
put(m_buildArchitecture, values);
|
||||
} else if(field == QLatin1String("LICENSE")) {
|
||||
m_licenses = values;
|
||||
} else if(field == QLatin1String("DEPENDS")) {
|
||||
put(m_dependencies, values);
|
||||
} else if(field == QLatin1String("MAKEDEPENDS")) {
|
||||
put(m_makeDependencies, values);
|
||||
} else if(field == QLatin1String("CHECKDEPENDS")) {
|
||||
put(m_checkDependencies, values);
|
||||
} else if(field == QLatin1String("OPTDEPENDS")) {
|
||||
put(m_optionalDependencies, values);
|
||||
} else if(field == QLatin1String("CONFLICTS")) {
|
||||
put(m_conflicts, values);
|
||||
} else if(field == QLatin1String("PROVIDES")) {
|
||||
put(m_provides, values);
|
||||
} else if(field == QLatin1String("REPLACES")) {
|
||||
put(m_replaces, values);
|
||||
} else if(field == QLatin1String("BUILDDATE")) {
|
||||
if(!values.isEmpty()) {
|
||||
m_buildDate = DateTime::fromTimeStampGmt(values.back().toUInt());
|
||||
}
|
||||
} else if(field == QLatin1String("INSTALLDATE")) {
|
||||
if(!values.isEmpty()) {
|
||||
m_installDate = DateTime::fromTimeStampGmt(values.back().toUInt());
|
||||
m_hasInstallRelatedMetaData = true;
|
||||
}
|
||||
} else if(field == QLatin1String("ISIZE") || field == QLatin1String("SIZE")) {
|
||||
if(!values.empty()) {
|
||||
m_installedSize = values.back().toUInt();
|
||||
m_hasInstallRelatedMetaData = true;
|
||||
}
|
||||
} else if(field == QLatin1String("CSIZE")) {
|
||||
if(!values.empty()) {
|
||||
m_packageSize = values.back().toUInt();
|
||||
}
|
||||
} else if(field == QLatin1String("PACKAGER")) {
|
||||
put(m_packager, values);
|
||||
} else if(field == QLatin1String("MD5SUM")) {
|
||||
put(m_md5, values);
|
||||
} else if(field == QLatin1String("SHA256SUM")) {
|
||||
put(m_sha256, values);
|
||||
} else if(field == QLatin1String("FILES")) {
|
||||
put(m_files, values);
|
||||
} else if(field == QLatin1String("REASON")) {
|
||||
if(!values.isEmpty()) {
|
||||
m_installReason = values.back().toUInt() == 1 ? ALPM_PKG_REASON_DEPEND : ALPM_PKG_REASON_EXPLICIT;
|
||||
}
|
||||
} else if(field == QLatin1String("VALIDATION")) {
|
||||
if(values.isEmpty()) {
|
||||
m_validationMethods = ALPM_PKG_VALIDATION_NONE;
|
||||
} else {
|
||||
for(const QString &value : values) {
|
||||
if(value == QLatin1String("md5")) {
|
||||
m_validationMethods = static_cast<alpm_pkgvalidation_t>(m_validationMethods | ALPM_PKG_VALIDATION_MD5SUM);
|
||||
} else if(value == QLatin1String("sha256")) {
|
||||
m_validationMethods = static_cast<alpm_pkgvalidation_t>(m_validationMethods | ALPM_PKG_VALIDATION_SHA256SUM);
|
||||
} else if(value == QLatin1String("pgp")) {
|
||||
m_validationMethods = static_cast<alpm_pkgvalidation_t>(m_validationMethods | ALPM_PKG_VALIDATION_SIGNATURE);
|
||||
} else {
|
||||
// TODO: error handling (imporant?)
|
||||
}
|
||||
}
|
||||
}
|
||||
m_hasInstallRelatedMetaData = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure crucial information is still present (use old values rather than no values)
|
||||
if(!name.isEmpty()) {
|
||||
m_name = name;
|
||||
}
|
||||
if(!version.version.isEmpty()) {
|
||||
m_version = version.toString();
|
||||
}
|
||||
|
||||
// description provides source related meta data, too (except pkgbase, TODO: special flag required?)
|
||||
m_hasBuildRelatedMetaData = m_hasSourceRelatedMetaData = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds a source file with the specified \a path and \a data.
|
||||
*/
|
||||
void Package::putSourceFile(const QString &path, const QByteArray &data)
|
||||
{
|
||||
m_sourceFiles.insert(make_pair(path, data));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \class PackageVersion
|
||||
* \brief The PackageVersion class helps parsing package versions.
|
||||
*/
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ public:
|
|||
const QString &fileName() const;
|
||||
const QJsonArray &files() const;
|
||||
ChronoUtilities::DateTime buildDate() const;
|
||||
const QString &packer() const;
|
||||
const QString &packager() const;
|
||||
const QString &md5() const;
|
||||
const QString &sha256() const;
|
||||
const QString &buildArchitecture() const;
|
||||
|
@ -191,8 +191,9 @@ public:
|
|||
void restoreFromCacheStream(QDataStream &in);
|
||||
void reinitEntries();
|
||||
|
||||
// parsing src/pkg info
|
||||
void putInfo(const QList<QPair<QString, QString> > &baseInfo, const QList<QPair<QString, QString> > &pkgInfo, bool includesSourceRelatedMetaData = false);
|
||||
// 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 putDescription(QString name, const QList<QPair<QString, QStringList> > &description);
|
||||
void putSourceFile(const QString &path, const QByteArray &data);
|
||||
|
||||
protected:
|
||||
|
@ -228,7 +229,7 @@ protected:
|
|||
QString m_fileName;
|
||||
QJsonArray m_files;
|
||||
ChronoUtilities::DateTime m_buildDate;
|
||||
QString m_packer;
|
||||
QString m_packager;
|
||||
QString m_md5;
|
||||
QString m_sha256;
|
||||
QString m_buildArchitecture;
|
||||
|
@ -457,11 +458,11 @@ inline ChronoUtilities::DateTime Package::buildDate() const
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the packer of the package file.
|
||||
* \brief Returns the packager of the package file.
|
||||
*/
|
||||
inline const QString &Package::packer() const
|
||||
inline const QString &Package::packager() const
|
||||
{
|
||||
return m_packer;
|
||||
return m_packager;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -660,7 +661,9 @@ inline const QString &Package::tarUrl() const
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the source files of the package.
|
||||
* \brief Returns the available source files.
|
||||
*
|
||||
* Contains usually the PKGBUILD/.SRCINFO file and patches.
|
||||
*/
|
||||
inline const std::map<QString, QByteArray> &Package::sourceFiles() const
|
||||
{
|
||||
|
|
|
@ -551,25 +551,37 @@ void Repository::cleanOutdatedPackages()
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds packages parsed from the specified \a srcInfo.
|
||||
* \returns Returns the added packages.
|
||||
* \brief Adds packages parsed from the specified .SRCINFO/.PKGINFO file.
|
||||
* \remarks Updates existing packages.
|
||||
* \returns Returns the added/updated packages. In the case of a split package more then
|
||||
* one package is returned.
|
||||
*/
|
||||
QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
|
||||
{
|
||||
// define states
|
||||
enum {
|
||||
FieldName,
|
||||
EquationSign,
|
||||
Pad,
|
||||
FieldValue,
|
||||
Comment
|
||||
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
|
||||
QString currentFieldName;
|
||||
currentFieldName.reserve(16);
|
||||
QString currentFieldValue;
|
||||
currentFieldValue.reserve(32);
|
||||
QString packageBase;
|
||||
packageBase.reserve(32);
|
||||
QList<QPair<QString, QString> > baseInfo;
|
||||
baseInfo.reserve(16);
|
||||
QList<QPair<QString, QString> > packageInfo;
|
||||
packageInfo.reserve(16);
|
||||
QList<Package *> packages;
|
||||
Package *currentPackage = nullptr;
|
||||
|
||||
// state machine: consumes each char of .SRCINFO
|
||||
for(const char c : srcInfo) {
|
||||
switch(state) {
|
||||
case FieldName:
|
||||
|
@ -628,23 +640,28 @@ QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
|
|||
} else if(currentFieldName == QLatin1String("pkgname")) {
|
||||
// next package
|
||||
if(packageBase.isEmpty()) {
|
||||
// TODO: handle error - pkgbase must be present
|
||||
} else {
|
||||
if(currentPackage) {
|
||||
currentPackage->putInfo(baseInfo, packageInfo, true);
|
||||
packages << currentPackage;
|
||||
}
|
||||
auto &pkg = m_packages[currentFieldValue];
|
||||
if(!pkg) {
|
||||
pkg = emptyPackage();
|
||||
}
|
||||
currentPackage = pkg.get();
|
||||
packageInfo.clear();
|
||||
// no pkgbase specified -> use the first pkgname as pkgbase
|
||||
packageBase = currentFieldName;
|
||||
}
|
||||
// put current info to current package
|
||||
if(currentPackage) {
|
||||
currentPackage->putInfo(baseInfo, packageInfo, true);
|
||||
packages << currentPackage;
|
||||
}
|
||||
// find next package
|
||||
auto &pkg = m_packages[currentFieldValue];
|
||||
if(!pkg) {
|
||||
pkg = emptyPackage();
|
||||
}
|
||||
currentPackage = pkg.get();
|
||||
packageInfo.clear();
|
||||
}
|
||||
// add field to ...
|
||||
if(currentPackage) {
|
||||
// ... concrete package info if there's already a concrete package
|
||||
packageInfo << QPair<QString, QString>(currentFieldName, currentFieldValue);
|
||||
} else {
|
||||
// ... base info if still parsing general info
|
||||
baseInfo << QPair<QString, QString>(currentFieldName, currentFieldValue);
|
||||
}
|
||||
currentFieldName.clear();
|
||||
|
@ -672,4 +689,97 @@ QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
|
|||
return packages;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds packages parsed from the specified desc/depends/files file.
|
||||
* \remarks Updates the package if it already exists.
|
||||
* \returns Returns the added/updated package.
|
||||
*/
|
||||
Package *Repository::addPackageFromDescription(QString name, const QList<QByteArray> &descriptions)
|
||||
{
|
||||
// define variables to store parsing results
|
||||
QString currentFieldName;
|
||||
currentFieldName.reserve(16);
|
||||
QStringList currentFieldValues;
|
||||
QList<QPair<QString, QStringList> > fields;
|
||||
|
||||
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()) {
|
||||
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
|
||||
auto &pkg = m_packages[name];
|
||||
if(!pkg) {
|
||||
pkg = emptyPackage();
|
||||
}
|
||||
pkg->putDescription(name, fields);
|
||||
return pkg.get();
|
||||
}
|
||||
|
||||
} // namespace PackageManagement
|
||||
|
|
|
@ -242,6 +242,7 @@ public:
|
|||
|
||||
// parsing src/pkg info
|
||||
QList<Package *> addPackagesFromSrcInfo(const QByteArray &srcInfo);
|
||||
Package *addPackageFromDescription(QString name, const QList<QByteArray> &descriptions);
|
||||
|
||||
// thread synchronization
|
||||
QReadWriteLock *lock() const;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "userrepository.h"
|
||||
|
||||
#include "../alpm/aurpackage.h"
|
||||
#include "../alpm/config.h"
|
||||
|
||||
#include <c++utilities/misc/memory.h>
|
||||
|
||||
|
@ -20,6 +21,8 @@
|
|||
#include <QTemporaryFile>
|
||||
#include <QStringBuilder>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace ChronoUtilities;
|
||||
|
||||
|
@ -118,10 +121,9 @@ void AurFullPackageReply::processData(QNetworkReply *reply)
|
|||
const auto data = static_cast<const KArchiveFile *>(entry)->data();
|
||||
for(Package *package : packages) {
|
||||
package->putSourceFile(entry->name(), data);
|
||||
// TODO: add source files
|
||||
}
|
||||
} else {
|
||||
// don't think it is required to read sub directories recursively
|
||||
// don't think it is required to read sub directories recursively (TODO?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +137,7 @@ void AurFullPackageReply::processData(QNetworkReply *reply)
|
|||
m_error = QStringLiteral("Unable to request tarball from AUR: ") + reply->errorString();
|
||||
}
|
||||
if(!m_error.isEmpty()) {
|
||||
qDebug() << m_error;
|
||||
cerr << shchar << m_error.toLocal8Bit().data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
"enabled": true
|
||||
},
|
||||
|
||||
"cacheDir": "/var/cache/repoindex"
|
||||
"cacheDir": "/var/cache/repoindex",
|
||||
"storageDir": "/var/lib/repoindex",
|
||||
|
||||
"server": {
|
||||
"websocketListeningAddr": "any-IPv4",
|
||||
|
|
|
@ -54,6 +54,7 @@ span.glyphicon {
|
|||
border: none!important;
|
||||
font-size: 90%;
|
||||
padding: 5px;
|
||||
vertical-align: top!important;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue