diff options
author | Arttu Tarkiainen <arttu.tarkiainen@qt.io> | 2020-12-01 13:00:15 +0200 |
---|---|---|
committer | Arttu Tarkiainen <arttu.tarkiainen@qt.io> | 2021-01-15 09:27:07 +0200 |
commit | 20f354b38b83e4aab107b388fe3c5e2ccd878946 (patch) | |
tree | 9da138aca91abdd931eb9fb4c74ffb35dddc7377 /src/libs/installer/packagemanagercore.cpp | |
parent | f61c19eb81dc692b9c5215f5bf94f3426b0f4f86 (diff) |
Add support for generating offline installer from online
Task-number: QTIFW-1945
Change-Id: Ic8a076a28385e99ad09cfbccd07c7012d6570639
Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/libs/installer/packagemanagercore.cpp')
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 185 |
1 files changed, 156 insertions, 29 deletions
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 8e205b7d7..ca128c6ea 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -317,6 +317,18 @@ using namespace QInstaller; */ /*! + \fn QInstaller::PackageManagerCore::offlineGenerationStarted() + + \sa {installer::offlineGenerationStarted()}{installer.offlineGenerationStarted()} +*/ + +/*! + \fn QInstaller::PackageManagerCore::offlineGenerationFinished() + + \sa {installer::offlineGenerationFinished()}{installer.offlineGenerationFinished()} +*/ + +/*! \fn QInstaller::PackageManagerCore::titleMessageChanged(const QString &title) Emitted when the text of the installer status (on the PerformInstallation page) changes to @@ -2249,6 +2261,47 @@ bool PackageManagerCore::componentUninstallableFromCommandLine(const QString &co } /*! + \internal + + Tries to set \c Qt::CheckStateRole to \c Qt::Checked for given \a components in the + default component model. Returns \c true if \a components contains at least one component + eligible for installation, otherwise returns \c false. An error message can be retrieved + with \a errorMessage. +*/ +bool PackageManagerCore::checkComponentsForInstallation(const QStringList &components, QString &errorMessage) +{ + bool installComponentsFound = false; + + ComponentModel *model = defaultComponentModel(); + foreach (const QString &name, components) { + const QModelIndex &idx = model->indexFromComponentName(name); + Component *component = componentByName(name); + if (component && idx.isValid()) { + if ((model->data(idx, Qt::CheckStateRole) == QVariant::Invalid) && !component->forcedInstallation()) { + // User cannot select the component, check why + if (component->autoDependencies().count() > 0) { + errorMessage.append(tr("Cannot install component %1. Component is installed only as automatic " + "dependency to %2.\n").arg(name, component->autoDependencies().join(QLatin1Char(',')))); + } else if (!component->isCheckable()) { + errorMessage.append(tr("Cannot install component %1. Component is not checkable meaning you " + "have to select one of the subcomponents.\n").arg(name)); + } + } else if (component->isInstalled()) { + errorMessage.append(tr("Component %1 already installed\n").arg(name)); + } else { + model->setData(idx, Qt::Checked, Qt::CheckStateRole); + installComponentsFound = true; + } + } else { // idx is invalid and component valid when we have invisible virtual component + 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)); + } + } + return installComponentsFound; +} + +/*! Lists installed packages without GUI. List of packages can be filtered with \a regexp. */ void PackageManagerCore::listInstalledPackages(const QString ®exp) @@ -2451,6 +2504,33 @@ PackageManagerCore::Status PackageManagerCore::removeInstallationSilently() } /*! + Creates an offline installer from selected \a componentsToAdd without displaying + a user interface. Virtual components cannot be selected unless made visible with + --show-virtual-components as in installation. AutoDependOn nor non-checkable components + cannot be selected directly. Returns \c PackageManagerCore::Status. +*/ +PackageManagerCore::Status PackageManagerCore::createOfflineInstaller(const QStringList &componentsToAdd) +{ + setOfflineGenerator(); + // init default model before fetching remote packages tree + ComponentModel *model = defaultComponentModel(); + Q_UNUSED(model); + if (!fetchRemotePackagesTree()) + return status(); + + QString errorMessage; + if (checkComponentsForInstallation(componentsToAdd, errorMessage)) { + if (d->calculateComponentsAndRun()) { + qCDebug(QInstaller::lcInstallerInstallLog) + << "Created installer to:" << offlineBinaryName(); + } + } else { + qCDebug(QInstaller::lcInstallerInstallLog).noquote().nospace() << errorMessage; + } + return status(); +} + +/*! Installs the selected components \a components without displaying a user interface. Virtual components cannot be installed unless made visible with --show-virtual-components. AutoDependOn nor non-checkable components cannot @@ -2475,39 +2555,18 @@ PackageManagerCore::Status PackageManagerCore::installSelectedComponentsSilently } } + // init default model before fetching remote packages tree ComponentModel *model = defaultComponentModel(); + Q_UNUSED(model); if (!fetchRemotePackagesTree()) return status(); - bool installComponentsFound = false; - foreach (const QString &name, components){ - const QModelIndex &idx = model->indexFromComponentName(name); - Component *component = componentByName(name); - if (idx.isValid()) { - if ((model->data(idx, Qt::CheckStateRole) == QVariant::Invalid) && - !component->forcedInstallation()) { // User cannot select the component, check why - if (component && component->autoDependencies().count() > 0) - qCDebug(QInstaller::lcInstallerInstallLog).noquote().nospace() << "Cannot install component "<< name - << ". Component is installed only as automatic dependency to "<< component->autoDependencies().join(QLatin1Char(',')) << "."; - if (component && !component->isCheckable()) - qCDebug(QInstaller::lcInstallerInstallLog).noquote().nospace() << "Cannot install component "<< name - <<". Component is not checkable meaning you have to select one of the subcomponents."; - } else if (component->isInstalled()) { - qCDebug(QInstaller::lcInstallerInstallLog).noquote().nospace() << "Component " << name <<" already installed"; - } else { - model->setData(idx, Qt::Checked, Qt::CheckStateRole); - installComponentsFound = true; - } - } else { // idx is invalid and component valid when we have invisible virtual component - if (component && component->isVirtual()) - qCDebug(QInstaller::lcInstallerInstallLog).noquote().nospace() << "Cannot install " << name <<". Component is virtual."; - else - qCDebug(QInstaller::lcInstallerInstallLog).noquote().nospace() << "Cannot install " << name <<". Component not found."; - } - } - if (installComponentsFound) { + QString errorMessage; + if (checkComponentsForInstallation(components, errorMessage)) { if (d->calculateComponentsAndRun()) qCDebug(QInstaller::lcInstallerInstallLog) << "Components installed successfully"; + } else { + qCDebug(QInstaller::lcInstallerInstallLog).noquote().nospace() << errorMessage; } return status(); } @@ -3045,6 +3104,27 @@ void PackageManagerCore::setInstallerBaseBinary(const QString &path) } /*! + Sets the \c installerbase binary located at \a path to use when writing the + offline installer. Setting this makes it possible to run the offline generator + in cases where we are not running a real installer, i.e. when executing autotests. + + For normal runs, the executable segment of the running installer will be used. +*/ +void PackageManagerCore::setOfflineBaseBinary(const QString &path) +{ + d->m_offlineBaseBinaryUnreplaced = path; +} + +/*! + Adds the resource collection in \a rcPath to the list of resource files + to be included into the generated offline installer binary. +*/ +void PackageManagerCore::addResourcesForOfflineGeneration(const QString &rcPath) +{ + d->m_offlineGeneratorResourceCollections.append(rcPath); +} + +/*! Returns the installer value for \a key. If \a key is not known to the system, \a defaultValue is returned. Additionally, on Windows, \a key can be a registry key. @@ -3199,6 +3279,22 @@ QString PackageManagerCore::installerBinaryPath() const } /*! + Sets the \a name for the generated offline binary. +*/ +void PackageManagerCore::setOfflineBinaryName(const QString &name) +{ + setValue(scOfflineBinaryName, name); +} + +/*! + Returns the path set for the generated offline binary. +*/ +QString PackageManagerCore::offlineBinaryName() const +{ + return d->offlineBinaryName(); +} + +/*! \sa {installer::setInstaller}{installer.setInstaller} \sa isInstaller(), setUpdater(), setPackageManager() */ @@ -3293,6 +3389,24 @@ bool PackageManagerCore::isPackageManager() const } /*! + Sets current installer to be offline generator based on \a offlineGenerator. +*/ +void PackageManagerCore::setOfflineGenerator(bool offlineGenerator) +{ + d->m_offlineGenerator = offlineGenerator; +} + +/*! + Returns \c true if current installer is executed as offline generator. + + \sa {installer::isOfflineGenerator}{installer.isOfflineGenerator} +*/ +bool PackageManagerCore::isOfflineGenerator() const +{ + return d->isOfflineGenerator(); +} + +/*! Sets the installer magic binary marker based on \a magicMarker and userSetBinaryMarker to \c true. */ @@ -3380,6 +3494,16 @@ bool PackageManagerCore::runPackageUpdater() } /*! + Runs the offline generator. Returns \c true on success, \c false otherwise. + + \sa {installer::runOfflineGenerator}{installer.runOfflineGenerator} +*/ +bool PackageManagerCore::runOfflineGenerator() +{ + return d->runOfflineGenerator(); +} + +/*! \sa {installer::languageChanged}{installer.languageChanged} */ void PackageManagerCore::languageChanged() @@ -3389,17 +3513,20 @@ void PackageManagerCore::languageChanged() } /*! - Runs the installer, uninstaller, updater, or package manager, depending on + Runs the installer, uninstaller, updater, package manager, or offline generator depending on the type of this binary. Returns \c true on success, otherwise \c false. */ bool PackageManagerCore::run() { - if (isInstaller()) + if (isOfflineGenerator()) + return d->runOfflineGenerator(); + else if (isInstaller()) return d->runInstaller(); else if (isUninstaller()) return d->runUninstaller(); else if (isMaintainer()) return d->runPackageUpdater(); + return false; } |