diff options
-rw-r--r-- | doc/scripting-api/packagemanagercore.qdoc | 8 | ||||
-rw-r--r-- | src/libs/installer/binarycontent.h | 9 | ||||
-rw-r--r-- | src/libs/installer/component.cpp | 5 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 66 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.h | 5 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.cpp | 11 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.h | 7 | ||||
-rw-r--r-- | tests/auto/installer/cliinterface/data/repository/Updates.xml | 21 | ||||
-rw-r--r-- | tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/Updates.xml | 10 | ||||
-rw-r--r-- | tests/auto/installer/cliinterface/tst_cliinterface.cpp | 16 |
10 files changed, 139 insertions, 19 deletions
diff --git a/doc/scripting-api/packagemanagercore.qdoc b/doc/scripting-api/packagemanagercore.qdoc index bacf50f27..f4d71ee97 100644 --- a/doc/scripting-api/packagemanagercore.qdoc +++ b/doc/scripting-api/packagemanagercore.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -861,6 +861,12 @@ */ /*! + \qmlmethod boolean installer::isPackageViewer() + + Returns \c true if the current installer is executed as package viewer. +*/ + +/*! \qmlmethod boolean installer::isUserSetBinaryMarker() Returns \c true if the magic binary marker has been set by user. diff --git a/src/libs/installer/binarycontent.h b/src/libs/installer/binarycontent.h index a21cd69e7..7d50c0e28 100644 --- a/src/libs/installer/binarycontent.h +++ b/src/libs/installer/binarycontent.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -48,6 +48,13 @@ public: static const qint64 MagicUpdaterMarker = 0x12023235UL; static const qint64 MagicPackageManagerMarker = 0x12023236UL; + // additional distinguishers only used at runtime, not written to the binary itself + enum MagicMarkerSupplement { + Default = 0x0, + OfflineGenerator = 0x1, + PackageViewer = 0x2 + }; + // the cookie put at the end of the file static const quint64 MagicCookie = 0xc2630a1c99d668f8LL; // binary static const quint64 MagicCookieDat = 0xc2630a1c99d668f9LL; // data diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp index c5d74cdfa..8142cd4e1 100644 --- a/src/libs/installer/component.cpp +++ b/src/libs/installer/component.cpp @@ -306,6 +306,8 @@ void Component::loadDataFromPackage(const KDUpdater::LocalPackage &package) /*! Sets variables according to the values set in the package.xml file of \a package. Also loads UI files, licenses and translations if they are referenced in the package.xml. + If the \c PackageManagerCore object of this component is run as package viewer, then + only sets the variables without loading referenced files. */ void Component::loadDataFromPackage(const Package &package) { @@ -344,6 +346,9 @@ void Component::loadDataFromPackage(const Package &package) setValue(scForcedInstallation, forced); setValue(scContentSha1, package.data(scContentSha1).toString()); + if (d->m_core->isPackageViewer()) + return; + setLocalTempPath(QInstaller::pathFromUrl(package.packageSource().url)); const QStringList uis = package.data(QLatin1String("UserInterfaces")).toString() .split(QInstaller::commaRegExp(), QString::SkipEmptyParts); diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index d619c1182..e03179ebb 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -2177,21 +2177,32 @@ ComponentModel *PackageManagerCore::updaterComponentModel() const */ void PackageManagerCore::listAvailablePackages(const QString ®exp) { + setPackageViewer(); qCDebug(QInstaller::lcInstallerInstallLog) << "Searching packages with regular expression:" << regexp; + + ComponentModel *model = defaultComponentModel(); d->fetchMetaInformationFromRepositories(DownloadType::UpdatesXML); d->addUpdateResourcesFromRepositories(true); QRegularExpression re(regexp); const PackagesList &packages = d->remotePackages(); + if (!fetchAllPackages(packages, LocalPackagesHash())) { + qCWarning(QInstaller::lcInstallerInstallLog) + << "There was a problem with loading the package data."; + return; + } PackagesList matchedPackages; foreach (Package *package, packages) { const QString name = package->data(scName).toString(); - if (re.match(name).hasMatch() && - (virtualComponentsVisible() ? true : !package->data(scVirtual, false).toBool())) { + Component *component = componentByName(name); + if (!component) + continue; + + const QModelIndex &idx = model->indexFromComponentName(component->treeName()); + if (idx.isValid() && re.match(name).hasMatch()) matchedPackages.append(package); - } } if (matchedPackages.count() == 0) qCDebug(QInstaller::lcInstallerInstallLog) << "No matching packages found."; @@ -2267,10 +2278,26 @@ bool PackageManagerCore::checkComponentsForInstallation(const QStringList &compo model->setData(idx, Qt::Checked, Qt::CheckStateRole); installComponentsFound = true; } - } else { // idx is invalid and component valid when we have invisible virtual component - component->isVirtual() - ? errorMessage.append(tr("Cannot install %1. Component is virtual.\n").arg(name)) - : errorMessage.append(tr("Cannot install %1. Component not found.\n").arg(name)); + } else { + auto isDescendantOfVirtual = [&]() { + Component *trace = component; + forever { + trace = trace->parentComponent(); + if (!trace) { + // We already checked the root component if there is no parent + return false; + } else if (trace->isVirtual()) { + errorMessage.append(tr("Cannot install %1. Component is descendant " + "of a virtual component %2.\n").arg(name, trace->name())); + return true; + } + } + }; + // idx is invalid and component valid when we have invisible virtual component + if (component->isVirtual()) + errorMessage.append(tr("Cannot install %1. Component is virtual.\n").arg(name)); + else if (!isDescendantOfVirtual()) + errorMessage.append(tr("Cannot install %1. Component not found.\n").arg(name)); } } if (!installComponentsFound) @@ -2284,6 +2311,7 @@ bool PackageManagerCore::checkComponentsForInstallation(const QStringList &compo */ void PackageManagerCore::listInstalledPackages(const QString ®exp) { + setPackageViewer(); LocalPackagesHash installedPackages = this->localInstalledPackages(); if (!regexp.isEmpty()) { @@ -3372,11 +3400,11 @@ bool PackageManagerCore::isPackageManager() const } /*! - Sets current installer to be offline generator based on \a offlineGenerator. + Sets current installer to be offline generator. */ -void PackageManagerCore::setOfflineGenerator(bool offlineGenerator) +void PackageManagerCore::setOfflineGenerator() { - d->m_offlineGenerator = offlineGenerator; + d->m_magicMarkerSupplement = BinaryContent::OfflineGenerator; } /*! @@ -3390,6 +3418,24 @@ bool PackageManagerCore::isOfflineGenerator() const } /*! + Sets the current installer as the package viewer. +*/ +void PackageManagerCore::setPackageViewer() +{ + d->m_magicMarkerSupplement = BinaryContent::PackageViewer; +} + +/*! + Returns \c true if the current installer is executed as package viewer. + + \sa {installer::isPackageViewer}{installer.isPackageViewer} +*/ +bool PackageManagerCore::isPackageViewer() const +{ + return d->isPackageViewer(); +} + +/*! Sets the installer magic binary marker based on \a magicMarker and userSetBinaryMarker to \c true. */ diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h index c845fb1fa..a5554782d 100644 --- a/src/libs/installer/packagemanagercore.h +++ b/src/libs/installer/packagemanagercore.h @@ -264,9 +264,12 @@ public: Q_INVOKABLE void setPackageManager(); Q_INVOKABLE bool isPackageManager() const; - void setOfflineGenerator(bool offlineGenerator = true); + void setOfflineGenerator(); Q_INVOKABLE bool isOfflineGenerator() const; + void setPackageViewer(); + Q_INVOKABLE bool isPackageViewer() const; + void setUserSetBinaryMarker(qint64 magicMarker); Q_INVOKABLE bool isUserSetBinaryMarker() const; diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index e6220ba35..1b14c306b 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -225,6 +225,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core) , m_repoFetched(false) , m_updateSourcesAdded(false) , m_magicBinaryMarker(0) // initialize with pseudo marker + , m_magicMarkerSupplement(BinaryContent::Default) , m_componentsToInstallCalculated(false) , m_componentScriptEngine(nullptr) , m_controlScriptEngine(nullptr) @@ -243,7 +244,6 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core) , m_autoAcceptLicenses(false) , m_disableWriteMaintenanceTool(false) , m_autoConfirmCommand(false) - , m_offlineGenerator(false) { } @@ -264,6 +264,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q , m_repoFetched(false) , m_updateSourcesAdded(false) , m_magicBinaryMarker(magicInstallerMaker) + , m_magicMarkerSupplement(BinaryContent::Default) , m_componentsToInstallCalculated(false) , m_componentScriptEngine(nullptr) , m_controlScriptEngine(nullptr) @@ -282,7 +283,6 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q , m_autoAcceptLicenses(false) , m_disableWriteMaintenanceTool(false) , m_autoConfirmCommand(false) - , m_offlineGenerator(false) { foreach (const OperationBlob &operation, performedOperations) { QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance() @@ -717,7 +717,12 @@ bool PackageManagerCorePrivate::isPackageManager() const bool PackageManagerCorePrivate::isOfflineGenerator() const { - return m_offlineGenerator; + return m_magicMarkerSupplement == BinaryContent::OfflineGenerator; +} + +bool PackageManagerCorePrivate::isPackageViewer() const +{ + return m_magicMarkerSupplement == BinaryContent::PackageViewer; } bool PackageManagerCorePrivate::statusCanceledOrFailed() const diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h index 4d5021471..b29808228 100644 --- a/src/libs/installer/packagemanagercore_p.h +++ b/src/libs/installer/packagemanagercore_p.h @@ -132,6 +132,8 @@ public: bool runOfflineGenerator(); bool isOfflineGenerator() const; + bool isPackageViewer() const; + QString replaceVariables(const QString &str) const; QByteArray replaceVariables(const QByteArray &str) const; @@ -265,9 +267,10 @@ private: bool m_repoFetched; bool m_updateSourcesAdded; qint64 m_magicBinaryMarker; + int m_magicMarkerSupplement; + bool m_componentsToInstallCalculated; - bool m_foundEssentialUpdate; - bool m_offlineGenerator; + bool m_foundEssentialUpdate;; mutable ScriptEngine *m_componentScriptEngine; mutable ScriptEngine *m_controlScriptEngine; diff --git a/tests/auto/installer/cliinterface/data/repository/Updates.xml b/tests/auto/installer/cliinterface/data/repository/Updates.xml index c7b11dc03..e5bc4f8af 100644 --- a/tests/auto/installer/cliinterface/data/repository/Updates.xml +++ b/tests/auto/installer/cliinterface/data/repository/Updates.xml @@ -35,6 +35,27 @@ <DownloadableArchives>content.7z</DownloadableArchives> <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> </PackageUpdate> + <PackageUpdate> + <Name>C.virt</Name> + <DisplayName>Virtual subcomponent of C</DisplayName> + <Description>Example virtual component</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Virtual>true</Virtual> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>C.virt.subcomponent</Name> + <DisplayName>Subcomponent of virtual component</DisplayName> + <Description>Example subcomponent of virtual component</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> <PackageUpdate> <Name>AB</Name> <DisplayName>AB</DisplayName> diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/Updates.xml b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/Updates.xml index e0aedffdd..f0c724db8 100644 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/Updates.xml +++ b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/Updates.xml @@ -37,4 +37,14 @@ <SHA1>cfa136fa1d7a4196896c90af72d510727ba799ae</SHA1> <Virtual>true</Virtual> </PackageUpdate> + <PackageUpdate> + <Name>B.subcomponent</Name> + <DisplayName>Subcomponent of B</DisplayName> + <Description>Example non-virtual subcomponent of B</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>cfa136fa1d7a4196896c90af72d510727ba799ae</SHA1> + </PackageUpdate> </Updates> diff --git a/tests/auto/installer/cliinterface/tst_cliinterface.cpp b/tests/auto/installer/cliinterface/tst_cliinterface.cpp index 550f45da2..98ea99133 100644 --- a/tests/auto/installer/cliinterface/tst_cliinterface.cpp +++ b/tests/auto/installer/cliinterface/tst_cliinterface.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -89,6 +89,15 @@ private slots: " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n" "</availablepackages>\n"); core->listAvailablePackages(QLatin1String("^C")); + + // Need to change rules here to catch messages + QLoggingCategory::setFilterRules("ifw.* = true\n"); + + QTest::ignoreMessage(QtDebugMsg, "No matching packages found."); + core->listAvailablePackages(QLatin1String("C.virt")); + + QTest::ignoreMessage(QtDebugMsg, "No matching packages found."); + core->listAvailablePackages(QLatin1String("C.virt.subcomponent")); } void testInstallPackageFails() @@ -117,6 +126,11 @@ private slots: << QLatin1String("B"))); QTest::ignoreMessage(QtDebugMsg, "Preparing meta information download..."); + QTest::ignoreMessage(QtDebugMsg, "Cannot install B.subcomponent. Component is descendant of a virtual component B.\n"); + QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() + << QLatin1String("B.subcomponent"))); + + QTest::ignoreMessage(QtDebugMsg, "Preparing meta information download..."); QTest::ignoreMessage(QtDebugMsg, "Cannot install MissingComponent. Component not found.\n"); QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() << QLatin1String("MissingComponent"))); |