diff options
Diffstat (limited to 'src/libs/installer/packagemanagercore_p.cpp')
-rw-r--r-- | src/libs/installer/packagemanagercore_p.cpp | 316 |
1 files changed, 166 insertions, 150 deletions
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 18f72e03d..642d7f5ae 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -54,13 +54,13 @@ #include "componentchecker.h" #include "globals.h" -#include "kdselfrestarter.h" -#include "kdupdaterfiledownloaderfactory.h" -#include "kdupdaterupdatesourcesinfo.h" -#include "kdupdaterupdateoperationfactory.h" +#include "selfrestarter.h" +#include "filedownloaderfactory.h" +#include "updateoperationfactory.h" #include <productkeycheck.h> +#include <QSettings> #include <QtConcurrentRun> #include <QtCore/QCoreApplication> #include <QtCore/QDir> @@ -97,9 +97,9 @@ public: { if (!m_operation) return; - qDebug() << QString::fromLatin1("%1 %2 operation: %3").arg(state, m_operation->value( + qDebug().noquote() << QString::fromLatin1("%1 %2 operation: %3").arg(state, m_operation->value( QLatin1String("component")).toString(), m_operation->name()); - qDebug() << QString::fromLatin1("\t- arguments: %1").arg(m_operation->arguments() + qDebug().noquote() << QString::fromLatin1("\t- arguments: %1").arg(m_operation->arguments() .join(QLatin1String(", "))); } ~OperationTracer() { @@ -176,7 +176,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool #else QFile::remove(newName); QFile::rename(oldName, newName); - KDSelfRestarter::setRestartOnQuit(restart); + SelfRestarter::setRestartOnQuit(restart); #endif } @@ -185,7 +185,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core) : m_updateFinder(0) - , m_updaterApplication(new DummyConfigurationInterface) + , m_localPackageHub(std::make_shared<LocalPackageHub>()) , m_core(core) , m_updates(false) , m_repoFetched(false) @@ -206,7 +206,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core) PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, qint64 magicInstallerMaker, const QList<OperationBlob> &performedOperations) : m_updateFinder(0) - , m_updaterApplication(new DummyConfigurationInterface) + , m_localPackageHub(std::make_shared<LocalPackageHub>()) , m_status(PackageManagerCore::Unfinished) , m_needsHardRestart(false) , m_testChecksum(false) @@ -232,24 +232,27 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q { foreach (const OperationBlob &operation, performedOperations) { QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance() - .create(operation.name)); + .create(operation.name, core)); if (op.isNull()) { - qWarning() << QString::fromLatin1("Failed to load unknown operation %1") - .arg(operation.name); + qWarning() << "Failed to load unknown operation" << operation.name; continue; } if (!op->fromXml(operation.xml)) { - qWarning() << "Failed to load XML for operation:" << operation.name; + qWarning() << "Failed to load XML for operation" << operation.name; continue; } m_performedOperationsOld.append(op.take()); } - connect(this, SIGNAL(installationStarted()), m_core, SIGNAL(installationStarted())); - connect(this, SIGNAL(installationFinished()), m_core, SIGNAL(installationFinished())); - connect(this, SIGNAL(uninstallationStarted()), m_core, SIGNAL(uninstallationStarted())); - connect(this, SIGNAL(uninstallationFinished()), m_core, SIGNAL(uninstallationFinished())); + connect(this, &PackageManagerCorePrivate::installationStarted, + m_core, &PackageManagerCore::installationStarted); + connect(this, &PackageManagerCorePrivate::installationFinished, + m_core, &PackageManagerCore::installationFinished); + connect(this, &PackageManagerCorePrivate::uninstallationStarted, + m_core, &PackageManagerCore::uninstallationStarted); + connect(this, &PackageManagerCorePrivate::uninstallationFinished, + m_core, &PackageManagerCore::uninstallationFinished); } PackageManagerCorePrivate::~PackageManagerCorePrivate() @@ -311,7 +314,8 @@ bool PackageManagerCorePrivate::performOperationThreaded(Operation *operation, O const QFuture<bool> future = QtConcurrent::run(runOperation, operation, type); QEventLoop loop; - loop.connect(&futureWatcher, SIGNAL(finished()), SLOT(quit()), Qt::QueuedConnection); + QObject::connect(&futureWatcher, &decltype(futureWatcher)::finished, &loop, &QEventLoop::quit, + Qt::QueuedConnection); futureWatcher.setFuture(future); if (!future.isFinished()) @@ -343,7 +347,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c return false; // append all components to their respective parents QHash<QString, Component*>::const_iterator it; - for (it = components.begin(); it != components.end(); ++it) { + for (it = components.constBegin(); it != components.constEnd(); ++it) { QString id = it.key(); QInstaller::Component *component = it.value(); while (!id.isEmpty() && component->parentComponent() == 0) { @@ -395,7 +399,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c foreach (QInstaller::Component *component, components) { const QStringList warnings = ComponentChecker::checkComponent(component); foreach (const QString &warning, warnings) - qCWarning(lcComponentChecker) << warning; + qCWarning(lcComponentChecker).noquote() << warning; } } catch (const Error &error) { clearAllComponentLists(); @@ -413,7 +417,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c void PackageManagerCorePrivate::cleanUpComponentEnvironment() { // clean up registered (downloaded) data - if (m_core->isUpdater() || m_core->isPackageManager()) + if (m_core->isMaintainer()) BinaryFormatEngineHandler::instance()->clear(); // there could be still some references to already deleted components, @@ -548,45 +552,37 @@ void PackageManagerCorePrivate::initialize(const QHash<QString, QString> ¶ms readMaintenanceConfigFiles(QCoreApplication::applicationDirPath()); #endif } + processFilesForDelayedDeletion(); + m_data.setDynamicPredefinedVariables(); + + disconnect(this, &PackageManagerCorePrivate::installationStarted, + ProgressCoordinator::instance(), &ProgressCoordinator::reset); + connect(this, &PackageManagerCorePrivate::installationStarted, + ProgressCoordinator::instance(), &ProgressCoordinator::reset); + disconnect(this, &PackageManagerCorePrivate::uninstallationStarted, + ProgressCoordinator::instance(), &ProgressCoordinator::reset); + connect(this, &PackageManagerCorePrivate::uninstallationStarted, + ProgressCoordinator::instance(), &ProgressCoordinator::reset); - foreach (Operation *currentOperation, m_performedOperationsOld) - currentOperation->setValue(QLatin1String("installer"), QVariant::fromValue(m_core)); - - disconnect(this, SIGNAL(installationStarted()), ProgressCoordinator::instance(), SLOT(reset())); - connect(this, SIGNAL(installationStarted()), ProgressCoordinator::instance(), SLOT(reset())); - disconnect(this, SIGNAL(uninstallationStarted()), ProgressCoordinator::instance(), SLOT(reset())); - connect(this, SIGNAL(uninstallationStarted()), ProgressCoordinator::instance(), SLOT(reset())); - - m_updaterApplication.updateSourcesInfo()->setFileName(QString()); - KDUpdater::PackagesInfo &packagesInfo = *m_updaterApplication.packagesInfo(); - packagesInfo.setFileName(componentsXmlPath()); + if (!isInstaller()) + m_localPackageHub->setFileName(componentsXmlPath()); - // Note: force overwriting the application name and version in case we run as installer. Both will be - // set to wrong initial values if we install into an already existing installation. This can happen - // if the components.xml path has not been changed, but name or version of the new installer. - if (isInstaller() || packagesInfo.applicationName().isEmpty()) { + if (isInstaller() || m_localPackageHub->applicationName().isEmpty()) { // TODO: this seems to be wrong, we should ask for ProductName defaulting to applicationName... - packagesInfo.setApplicationName(m_data.settings().applicationName()); + m_localPackageHub->setApplicationName(m_data.settings().applicationName()); } - if (isInstaller() || packagesInfo.applicationVersion().isEmpty()) { - packagesInfo.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION))); - } + if (isInstaller() || m_localPackageHub->applicationVersion().isEmpty()) + m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION))); - if (isInstaller()) { - // TODO: this seems to be wrong, we should ask for ProductName defaulting to applicationName... - m_updaterApplication.addUpdateSource(m_data.settings().applicationName(), - m_data.settings().applicationName(), QString(), QUrl(QLatin1String("resource://metadata/")), 0); - m_updaterApplication.updateSourcesInfo()->setModified(false); - } + if (isInstaller()) + m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0)); m_metadataJob.disconnect(); m_metadataJob.setAutoDelete(false); m_metadataJob.setPackageManagerCore(m_core); - connect(&m_metadataJob, SIGNAL(infoMessage(KDJob*, QString)), this, - SLOT(infoMessage(KDJob*, QString))); - connect(&m_metadataJob, SIGNAL(progress(KDJob *, quint64, quint64)), this, - SLOT(infoProgress(KDJob *, quint64, quint64))); + connect(&m_metadataJob, &Job::infoMessage, this, &PackageManagerCorePrivate::infoMessage); + connect(&m_metadataJob, &Job::progress, this, &PackageManagerCorePrivate::infoProgress); KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory()); } @@ -656,7 +652,7 @@ QByteArray PackageManagerCorePrivate::replaceVariables(const QByteArray &ba) con */ Operation *PackageManagerCorePrivate::createOwnedOperation(const QString &type) { - m_ownedOperations.append(KDUpdater::UpdateOperationFactory::instance().create(type)); + m_ownedOperations.append(KDUpdater::UpdateOperationFactory::instance().create(type, m_core)); return m_ownedOperations.last(); } @@ -737,24 +733,30 @@ void PackageManagerCorePrivate::writeMaintenanceConfigFiles() // write current state (variables) to the maintenance tool ini file const QString iniPath = targetDir() + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile(); - QVariantHash variables; + QVariantHash variables; // Do not change to QVariantMap! Breaks existing .ini files, + // cause the variant types do not match while restoring the variables from the file. QSettingsWrapper cfg(iniPath, QSettingsWrapper::IniFormat); foreach (const QString &key, m_data.keys()) { - if (key != scRunProgramDescription && key != scRunProgram && key != scRunProgramArguments) - variables.insert(key, m_data.value(key)); + if (key == scRunProgramDescription || key == scRunProgram || key == scRunProgramArguments) + continue; + QVariant value = m_data.value(key); + if (value.canConvert(QVariant::String)) + value = replacePath(value.toString(), targetDir(), QLatin1String(scRelocatable)); + variables.insert(key, value); } cfg.setValue(QLatin1String("Variables"), variables); - QVariantList repos; + QVariantList repos; // Do not change either! foreach (const Repository &repo, m_data.settings().defaultRepositories()) repos.append(QVariant().fromValue(repo)); cfg.setValue(QLatin1String("DefaultRepositories"), repos); - cfg.sync(); + cfg.setValue(QLatin1String("FilesForDelayedDeletion"), m_filesForDelayedDeletion); + cfg.sync(); if (cfg.status() != QSettingsWrapper::NoError) { const QString reason = cfg.status() == QSettingsWrapper::AccessError ? tr("Access error") : tr("Format error"); - throw Error(tr("Could not write installer configuration to %1: %2").arg(iniPath, reason)); + throw Error(tr("Cannot write installer configuration to %1: %2").arg(iniPath, reason)); } QFile file(targetDir() + QLatin1Char('/') + QLatin1String("network.xml")); @@ -799,17 +801,22 @@ void PackageManagerCorePrivate::readMaintenanceConfigFiles(const QString &target { QSettingsWrapper cfg(targetDir + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile(), QSettingsWrapper::IniFormat); - const QVariantHash vars = cfg.value(QLatin1String("Variables")).toHash(); - for (QHash<QString, QVariant>::ConstIterator it = vars.constBegin(); it != vars.constEnd(); ++it) - m_data.setValue(it.key(), it.value().toString()); - + const QVariantHash v = cfg.value(QLatin1String("Variables")).toHash(); // Do not change to + // QVariantMap! Breaks reading from existing .ini files, cause the variant types do not match. + for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); ++it) { + m_data.setValue(it.key(), replacePath(it.value().toString(), QLatin1String(scRelocatable), + targetDir)); + } QSet<Repository> repos; - const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories")).toList(); + const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories")) + .toList(); // Do not change either! foreach (const QVariant &variant, variants) repos.insert(variant.value<Repository>()); if (!repos.isEmpty()) m_data.settings().setDefaultRepositories(repos); + m_filesForDelayedDeletion = cfg.value(QLatin1String("FilesForDelayedDeletion")).toStringList(); + QFile file(targetDir + QLatin1String("/network.xml")); if (!file.open(QIODevice::ReadOnly)) return; @@ -1008,13 +1015,13 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q { QFile dummy(resourcePath.filePath(QLatin1String("installer.dat"))); if (dummy.exists() && !dummy.remove()) { - throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(), + throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(), dummy.errorString())); } } if (!dataOut.rename(resourcePath.filePath(QLatin1String("installer.dat")))) { - throw Error(tr("Could not write maintenance tool data to %1: %2").arg(out.fileName(), + throw Error(tr("Cannot write maintenance tool data to %1: %2").arg(out.fileName(), out.errorString())); } dataOut.setAutoRemove(false); @@ -1033,13 +1040,13 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q { QFile dummy(maintenanceToolRenamedName); if (dummy.exists() && !dummy.remove()) { - throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(), + throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(), dummy.errorString())); } } if (!out.copy(maintenanceToolRenamedName)) { - throw Error(tr("Could not write maintenance tool to %1: %2").arg(maintenanceToolRenamedName, + throw Error(tr("Cannot write maintenance tool to \"%1\": %2").arg(maintenanceToolRenamedName, out.errorString())); } @@ -1071,8 +1078,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp file.remove(); // clear all possible leftovers m_core->setValue(QString::fromLatin1("DefaultResourceReplacement"), QString()); } else { - qWarning() << QString::fromLatin1("Could not replace default resource with '%1'.") - .arg(newDefaultResource); + qWarning() << "Cannot replace default resource with" << QDir::toNativeSeparators(newDefaultResource); } } @@ -1085,9 +1091,6 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp const qint64 operationsStart = output->pos(); QInstaller::appendInt64(output, performedOperations.count()); foreach (Operation *operation, performedOperations) { - // the installer can't be put into XML, remove it first - operation->clearValue(QLatin1String("installer")); - QInstaller::appendString(output, operation->name()); QInstaller::appendString(output, operation->toXml().toString()); @@ -1263,17 +1266,17 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper if (!replacementBinary.remove()) { // Is there anything more sensible we can do with this error? I think not. It's not serious // enough for throwing / aborting the process. - qDebug() << QString::fromLatin1("Could not remove installer base binary '%1' after updating " - "the maintenance tool: %2").arg(installerBaseBinary, replacementBinary.errorString()); + qDebug() << "Cannot remove installer base binary" << installerBaseBinary + << "after updating the maintenance tool:" << replacementBinary.errorString(); } else { - qDebug() << QString::fromLatin1("Removed installer base binary '%1' after updating the " - "maintenance tool.").arg(installerBaseBinary); + qDebug() << "Removed installer base binary" << installerBaseBinary + << "after updating the maintenance tool."; } m_installerBaseBinaryUnreplaced.clear(); } else if (!installerBaseBinary.isEmpty() && !QFileInfo(installerBaseBinary).exists()) { - qWarning() << QString::fromLatin1("The current maintenance tool could not be " - "updated. '%1' does not exist. Please fix the 'setInstallerBaseBinary(<temp_installer_base_" - "binary_path>)' call in your script.").arg(installerBaseBinary); + qWarning() << "The current maintenance tool could not be updated." << installerBaseBinary + << "does not exist. Please fix the \"setInstallerBaseBinary(<temp_installer_base_" + "binary_path>)\" call in your script."; } QFile input; @@ -1283,9 +1286,9 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper try { if (isInstaller()) { if (QFile::exists(dataFile)) { - qWarning() << QString::fromLatin1("Found binary data file '%1' but " + qWarning() << "Found binary data file" << dataFile << "but " "deliberately not used. Running as installer requires to read the " - "resources from the application binary.").arg(dataFile); + "resources from the application binary."; } throw Error(); } @@ -1334,12 +1337,12 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper QFile dummy(dataFile + QLatin1String(".new")); if (dummy.exists() && !dummy.remove()) { - throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(), + throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(), dummy.errorString())); } if (!file.rename(dataFile + QLatin1String(".new"))) { - throw Error(tr("Could not write maintenance tool binary data to %1: %2") + throw Error(tr("Cannot write maintenance tool binary data to %1: %2") .arg(file.fileName(), file.errorString())); } file.setAutoRemove(false); @@ -1399,7 +1402,7 @@ QString PackageManagerCorePrivate::registerPath() } QString path = QLatin1String("HKEY_CURRENT_USER"); - if (m_data.value(QLatin1String("AllUsers"), scFalse).toString() == scTrue) + if (m_data.value(scAllUsers, scFalse).toString() == scTrue) path = QLatin1String("HKEY_LOCAL_MACHINE"); return path + QLatin1String("\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\") @@ -1491,14 +1494,13 @@ bool PackageManagerCorePrivate::runInstaller() componentsInstallPartProgressSize = double(1); // Force an update on the components xml as the install dir might have changed. - KDUpdater::PackagesInfo &info = *m_updaterApplication.packagesInfo(); - info.setFileName(componentsXmlPath()); + m_localPackageHub->setFileName(componentsXmlPath()); // Clear the packages as we might install into an already existing installation folder. - info.clearPackageInfoList(); + m_localPackageHub->clearPackageInfos(); // also update the application name, might be set from a script as well - info.setApplicationName(m_data.value(QLatin1String("ProductName"), + m_localPackageHub->setApplicationName(m_data.value(QLatin1String("ProductName"), m_data.settings().applicationName()).toString()); - info.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION))); + m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION))); const int progressOperationCount = countProgressOperations(componentsToInstall) // add one more operation as we support progress @@ -1526,7 +1528,6 @@ bool PackageManagerCorePrivate::runInstaller() binaryFile = resourcePath.filePath(QLatin1String("installer.dat")); #endif createRepo->setValue(QLatin1String("uninstall-only"), true); - createRepo->setValue(QLatin1String("installer"), QVariant::fromValue(m_core)); createRepo->setArguments(QStringList() << binaryFile << target + QLatin1String("/repository")); @@ -1867,7 +1868,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr bool ignoreError = false; bool ok = performOperationThreaded(operation); while (!ok && !ignoreError && m_core->status() != PackageManagerCore::Canceled) { - qDebug() << QString::fromLatin1("Operation '%1' with arguments: '%2' failed: %3") + qDebug() << QString::fromLatin1("Operation \"%1\" with arguments \"%2\" failed: %3") .arg(operation->name(), operation->arguments().join(QLatin1String("; ")), operation->errorString()); const QMessageBox::StandardButton button = @@ -1905,7 +1906,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr if (!component->stopProcessForUpdateRequests().isEmpty()) { Operation *stopProcessForUpdatesOp = KDUpdater::UpdateOperationFactory::instance() - .create(QLatin1String("FakeStopProcessForUpdate")); + .create(QLatin1String("FakeStopProcessForUpdate"), m_core); const QStringList arguments(component->stopProcessForUpdateRequests().join(QLatin1String(","))); stopProcessForUpdatesOp->setArguments(arguments); addPerformed(stopProcessForUpdatesOp); @@ -1913,12 +1914,18 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr } // now mark the component as installed - KDUpdater::PackagesInfo &packages = *m_updaterApplication.packagesInfo(); - packages.installPackage(component->name(), component->value(scVersion), component->value(scDisplayName), - component->value(scDescription), component->dependencies(), component->forcedInstallation(), - component->isVirtual(), component->value(scUncompressedSize).toULongLong(), - component->value(scInheritVersion)); - packages.writeToDisk(); + m_localPackageHub->addPackage(component->name(), + component->value(scVersion), + component->value(scDisplayName), + component->value(scDescription), + component->dependencies(), + component->autoDependencies(), + component->forcedInstallation(), + component->isVirtual(), + component->value(scUncompressedSize).toULongLong(), + component->value(scInheritVersion), + component->isCheckable()); + m_localPackageHub->writeToDisk(); component->setInstalled(); component->markAsPerformedInstallation(); @@ -2039,7 +2046,6 @@ void PackageManagerCorePrivate::unregisterMaintenanceTool() void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOperations, double progressSize, bool adminRightsGained, bool deleteOperation) { - KDUpdater::PackagesInfo &packages = *m_updaterApplication.packagesInfo(); try { foreach (Operation *undoOperation, undoOperations) { if (statusCanceledOrFailed()) @@ -2075,7 +2081,7 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera component = componentsToReplace().value(componentName).second; if (component) { component->setUninstalled(); - packages.removePackage(component->name()); + m_localPackageHub->removePackage(component->name()); } } @@ -2086,13 +2092,13 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera delete undoOperation; } } catch (const Error &error) { - packages.writeToDisk(); + m_localPackageHub->writeToDisk(); throw Error(error.message()); } catch (...) { - packages.writeToDisk(); + m_localPackageHub->writeToDisk(); throw Error(tr("Unknown error")); } - packages.writeToDisk(); + m_localPackageHub->writeToDisk(); } PackagesList PackageManagerCorePrivate::remotePackages() @@ -2103,12 +2109,14 @@ PackagesList PackageManagerCorePrivate::remotePackages() m_updates = false; delete m_updateFinder; - m_updateFinder = new KDUpdater::UpdateFinder(&m_updaterApplication); + m_updateFinder = new KDUpdater::UpdateFinder; m_updateFinder->setAutoDelete(false); + m_updateFinder->setPackageSources(m_packageSources); + m_updateFinder->setLocalPackageHub(m_localPackageHub); m_updateFinder->run(); if (m_updateFinder->updates().isEmpty()) { - setStatus(PackageManagerCore::Failure, tr("Could not retrieve remote tree: %1.") + setStatus(PackageManagerCore::Failure, tr("Cannot retrieve remote tree %1.") .arg(m_updateFinder->errorString())); return PackagesList(); } @@ -2124,27 +2132,32 @@ PackagesList PackageManagerCorePrivate::remotePackages() */ LocalPackagesHash PackageManagerCorePrivate::localInstalledPackages() { + if (isInstaller()) + return LocalPackagesHash(); + LocalPackagesHash installedPackages; + if (m_localPackageHub->error() != LocalPackageHub::NoError) { + if (m_localPackageHub->fileName().isEmpty()) + m_localPackageHub->setFileName(componentsXmlPath()); + else + m_localPackageHub->refresh(); - if (!isInstaller()) { - KDUpdater::PackagesInfo &packagesInfo = *m_updaterApplication.packagesInfo(); - if (!packagesInfo.isValid()) { - packagesInfo.setFileName(componentsXmlPath()); - if (packagesInfo.applicationName().isEmpty()) - packagesInfo.setApplicationName(m_data.settings().applicationName()); - if (packagesInfo.applicationVersion().isEmpty()) - packagesInfo.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION))); - } + if (m_localPackageHub->applicationName().isEmpty()) + m_localPackageHub->setApplicationName(m_data.settings().applicationName()); + if (m_localPackageHub->applicationVersion().isEmpty()) + m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION))); + } - if (packagesInfo.error() != KDUpdater::PackagesInfo::NoError) - setStatus(PackageManagerCore::Failure, tr("Failure to read packages from: %1.").arg(componentsXmlPath())); + if (m_localPackageHub->error() != LocalPackageHub::NoError) { + setStatus(PackageManagerCore::Failure, tr("Failure to read packages from %1.") + .arg(componentsXmlPath())); + } - foreach (const LocalPackage &package, packagesInfo.packageInfos()) { - if (statusCanceledOrFailed()) - break; - installedPackages.insert(package.name, package); - } - } + foreach (const LocalPackage &package, m_localPackageHub->packageInfos()) { + if (statusCanceledOrFailed()) + break; + installedPackages.insert(package.name, package); + } return installedPackages; } @@ -2162,12 +2175,12 @@ bool PackageManagerCorePrivate::fetchMetaInformationFromRepositories() m_metadataJob.start(); m_metadataJob.waitForFinished(); } catch (Error &error) { - setStatus(PackageManagerCore::Failure, tr("Could not retrieve meta information: %1") + setStatus(PackageManagerCore::Failure, tr("Cannot retrieve meta information: %1") .arg(error.message())); return m_repoFetched; } - if (m_metadataJob.error() != KDJob::NoError) { + if (m_metadataJob.error() != Job::NoError) { switch (m_metadataJob.error()) { case QInstaller::UserIgnoreError: break; // we can simply ignore this error, the user knows about it @@ -2192,19 +2205,13 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe return m_updateSourcesAdded; } - // forces an refresh / clear on all update sources - m_updaterApplication.updateSourcesInfo()->refresh(); - if (isInstaller()) { - m_updaterApplication.addUpdateSource(m_data.settings().applicationName(), - m_data.settings().applicationName(), QString(), - QUrl(QLatin1String("resource://metadata/")), 0); - m_updaterApplication.updateSourcesInfo()->setModified(false); - } + m_packageSources.clear(); + if (isInstaller()) + m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0)); m_updates = false; m_updateSourcesAdded = false; - const QString &appName = m_data.settings().applicationName(); foreach (const Metadata &data, metadata) { if (statusCanceledOrFailed()) return false; @@ -2219,7 +2226,7 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe QInstaller::openForRead(&updatesFile); } catch(const Error &e) { qDebug() << "Error opening Updates.xml:" << e.message(); - setStatus(PackageManagerCore::Failure, tr("Could not add temporary update source information.")); + setStatus(PackageManagerCore::Failure, tr("Cannot add temporary update source information.")); return false; } @@ -2228,9 +2235,9 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe QString error; QDomDocument doc; if (!doc.setContent(&updatesFile, &error, &line, &column)) { - qDebug() << QString::fromLatin1("Parse error in file %4: %1 at line %2 col %3").arg(error, - QString::number(line), QString::number(column), updatesFile.fileName()); - setStatus(PackageManagerCore::Failure, tr("Could not add temporary update source information.")); + qDebug().nospace() << "Parse error in file" << updatesFile.fileName() + << ": " << error << " at line " << line << " col " << column; + setStatus(PackageManagerCore::Failure, tr("Cannot add temporary update source information.")); return false; } @@ -2238,14 +2245,12 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe if (!checksum.isNull()) m_core->setTestChecksum(checksum.toElement().text().toLower() == scTrue); } - m_updaterApplication.addUpdateSource(appName, appName, QString(), - QUrl::fromLocalFile(data.directory), 1); + m_packageSources.insert(PackageSource(QUrl::fromLocalFile(data.directory), 1)); ProductKeyCheck::instance()->addPackagesFromXml(data.directory + QLatin1String("/Updates.xml")); } - m_updaterApplication.updateSourcesInfo()->setModified(false); - if (m_updaterApplication.updateSourcesInfo()->updateSourceInfoCount() == 0) { - setStatus(PackageManagerCore::Failure, tr("Could not find any update source information.")); + if (m_packageSources.count() == 0) { + setStatus(PackageManagerCore::Failure, tr("Cannot find any update source information.")); return false; } @@ -2297,25 +2302,20 @@ OperationList PackageManagerCorePrivate::sortOperationsBasedOnComponentDependenc const QString componentName = operation->value(QLatin1String("component")).toString(); if (componentName.isEmpty()) sortedOperations.append(operation); - else { - OperationList componentOperationList = componentOperationHash.value(componentName); - componentOperationList.append(operation); - componentOperationHash.insert(operation->value(QLatin1String("component")).toString(), - componentOperationList); - } + else + componentOperationHash[componentName].append(operation); } - const QString empty; const QRegExp dash(QLatin1String("-.*")); Graph<QString> componentGraph; // create the complete component graph foreach (const Component* node, m_core->components(PackageManagerCore::ComponentType::All)) { componentGraph.addNode(node->name()); - componentGraph.addEdges(node->name(), node->dependencies().replaceInStrings(dash, empty)); + componentGraph.addEdges(node->name(), node->dependencies().replaceInStrings(dash, QString())); } const QStringList resolvedComponents = componentGraph.sort(); if (componentGraph.hasCycle()) { - throw Error(tr("Dependency cycle between components detected: '%1' and '%2'.") + throw Error(tr("Dependency cycle between components \"%1\" and \"%2\" detected.") .arg(componentGraph.cycle().first, componentGraph.cycle().second)); } foreach (const QString &componentName, resolvedComponents) @@ -2331,4 +2331,20 @@ void PackageManagerCorePrivate::handleMethodInvocationRequest(const QString &inv QMetaObject::invokeMethod(obj, qPrintable(invokableMethodName)); } +void PackageManagerCorePrivate::processFilesForDelayedDeletion() +{ + if (m_filesForDelayedDeletion.isEmpty()) + return; + + const QStringList filesForDelayedDeletion = std::move(m_filesForDelayedDeletion); + foreach (const QString &i, filesForDelayedDeletion) { + QFile file(i); //TODO: this should happen asnyc and report errors, I guess + if (file.exists() && !file.remove()) { + qWarning("Cannot delete file %s: %s", qPrintable(i), + qPrintable(file.errorString())); + m_filesForDelayedDeletion << i; // try again next time + } + } +} + } // namespace QInstaller |