summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2020-02-25 11:50:48 +0200
committerKatja Marttila <katja.marttila@qt.io>2020-03-12 07:54:50 +0000
commitd98e8e8b62c90ee867e8f25fabca4f3adeeacbea (patch)
tree22a48482d17addd7aa786191f711acda8c7770fa
parent3c7b8025e0db7607ee6ca718a3faf6ddfc677a51 (diff)
Perform headless commands without GUI dependency
Task-number: QTIFW-1633 Change-Id: I207cd152a471fddd51c152223460f8a9873f4382 Reviewed-by: Iikka Eklund <iikka.eklund@qt.io>
-rw-r--r--examples/openreadme/packages/or.qtproject.ifw.example.openreadme/meta/installscript.qs6
-rw-r--r--examples/registerfileextension/packages/org.qtproject.ifw.example.registerfileextension/meta/installscript.qs20
-rw-r--r--src/libs/installer/packagemanagercore.cpp38
-rw-r--r--src/sdk/commandlineinterface.cpp226
-rw-r--r--src/sdk/commandlineinterface.h (renamed from src/sdk/updatechecker.h)28
-rw-r--r--src/sdk/installerbase.cpp419
-rw-r--r--src/sdk/installerbase.h7
-rw-r--r--src/sdk/main.cpp23
-rw-r--r--src/sdk/sdk.pro4
-rw-r--r--src/sdk/sdkapp.h237
-rw-r--r--src/sdk/updatechecker.cpp116
11 files changed, 602 insertions, 522 deletions
diff --git a/examples/openreadme/packages/or.qtproject.ifw.example.openreadme/meta/installscript.qs b/examples/openreadme/packages/or.qtproject.ifw.example.openreadme/meta/installscript.qs
index e644afbe6..2cd5e8728 100644
--- a/examples/openreadme/packages/or.qtproject.ifw.example.openreadme/meta/installscript.qs
+++ b/examples/openreadme/packages/or.qtproject.ifw.example.openreadme/meta/installscript.qs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the FOO module of the Qt Toolkit.
@@ -52,8 +52,8 @@ Component.prototype.installationFinished = function()
{
try {
if (installer.isInstaller() && installer.status == QInstaller.Success) {
- var isReadMeCheckBoxChecked = component.userInterface( "ReadMeCheckBoxForm" ).readMeCheckBox.checked;
- if (isReadMeCheckBoxChecked) {
+ var checkboxForm = component.userInterface( "ReadMeCheckBoxForm" );
+ if (checkboxForm && checkboxForm.readMeCheckBox.checked) {
QDesktopServices.openUrl("file:///" + installer.value("TargetDir") + "/README.txt");
}
}
diff --git a/examples/registerfileextension/packages/org.qtproject.ifw.example.registerfileextension/meta/installscript.qs b/examples/registerfileextension/packages/org.qtproject.ifw.example.registerfileextension/meta/installscript.qs
index a5a6bb174..aa3fa3a67 100644
--- a/examples/registerfileextension/packages/org.qtproject.ifw.example.registerfileextension/meta/installscript.qs
+++ b/examples/registerfileextension/packages/org.qtproject.ifw.example.registerfileextension/meta/installscript.qs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the FOO module of the Qt Toolkit.
@@ -49,9 +49,10 @@ addRegisterFileCheckBox = function()
{
// don't show when updating or uninstalling
if (installer.isInstaller()) {
- installer.addWizardPageItem(component, "RegisterFileCheckBoxForm", QInstaller.TargetDirectory);
- component.userInterface("RegisterFileCheckBoxForm").RegisterFileCheckBox.text =
- component.userInterface("RegisterFileCheckBoxForm").RegisterFileCheckBox.text + component.unusualFileType;
+ if (installer.addWizardPageItem(component, "RegisterFileCheckBoxForm", QInstaller.TargetDirectory)) {
+ component.userInterface("RegisterFileCheckBoxForm").RegisterFileCheckBox.text =
+ component.userInterface("RegisterFileCheckBoxForm").RegisterFileCheckBox.text + component.unusualFileType;
+ }
}
}
@@ -61,7 +62,9 @@ Component.prototype.createOperations = function()
// call default implementation to actually install the registeredfile
component.createOperations();
- var isRegisterFileChecked = component.userInterface("RegisterFileCheckBoxForm").RegisterFileCheckBox.checked;
+ if (component.userInterface("RegisterFileCheckBoxForm")) {
+ var isRegisterFileChecked = component.userInterface("RegisterFileCheckBoxForm").RegisterFileCheckBox.checked;
+ }
if (installer.value("os") === "win") {
var iconId = 0;
var notepadPath = installer.environmentVariable("SystemRoot") + "\\notepad.exe";
@@ -93,8 +96,9 @@ openRegisteredFileIfChecked = function()
addOpenFileCheckBoxToFinishPage = function()
{
if (installer.isInstaller() && installer.status == QInstaller.Success) {
- installer.addWizardPageItem(component, "OpenFileCheckBoxForm", QInstaller.InstallationFinished);
- component.userInterface("OpenFileCheckBoxForm").OpenRegisteredFileCheckBox.text =
- component.userInterface("OpenFileCheckBoxForm").OpenRegisteredFileCheckBox.text + component.unusualFileType;
+ if (installer.addWizardPageItem(component, "OpenFileCheckBoxForm", QInstaller.InstallationFinished)) {
+ component.userInterface("OpenFileCheckBoxForm").OpenRegisteredFileCheckBox.text =
+ component.userInterface("OpenFileCheckBoxForm").OpenRegisteredFileCheckBox.text + component.unusualFileType;
+ }
}
}
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 878737dc1..36c9935ce 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -1453,9 +1453,13 @@ bool PackageManagerCore::fetchPackagesTree(const PackagesList &packages, const L
*/
bool PackageManagerCore::addWizardPage(Component *component, const QString &name, int page)
{
- if (QWidget* const widget = component->userInterface(name)) {
- emit wizardPageInsertionRequested(widget, static_cast<WizardPage>(page));
- return true;
+ if (!isCommandLineInstance()) {
+ if (QWidget* const widget = component->userInterface(name)) {
+ emit wizardPageInsertionRequested(widget, static_cast<WizardPage>(page));
+ return true;
+ }
+ } else {
+ qCDebug(QInstaller::lcGeneral) << "Headless installation: skip wizard page addition: " << name;
}
return false;
}
@@ -1473,9 +1477,13 @@ bool PackageManagerCore::addWizardPage(Component *component, const QString &name
*/
bool PackageManagerCore::removeWizardPage(Component *component, const QString &name)
{
- if (QWidget* const widget = component->userInterface(name)) {
- emit wizardPageRemovalRequested(widget);
- return true;
+ if (!isCommandLineInstance()) {
+ if (QWidget* const widget = component->userInterface(name)) {
+ emit wizardPageRemovalRequested(widget);
+ return true;
+ }
+ } else {
+ qCDebug(QInstaller::lcGeneral) << "Headless installation: skip wizard page removal: " << name;
}
return false;
}
@@ -1533,9 +1541,13 @@ void PackageManagerCore::setValidatorForCustomPage(Component *component, const Q
*/
bool PackageManagerCore::addWizardPageItem(Component *component, const QString &name, int page)
{
- if (QWidget* const widget = component->userInterface(name)) {
- emit wizardWidgetInsertionRequested(widget, static_cast<WizardPage>(page));
- return true;
+ if (!isCommandLineInstance()) {
+ if (QWidget* const widget = component->userInterface(name)) {
+ emit wizardWidgetInsertionRequested(widget, static_cast<WizardPage>(page));
+ return true;
+ }
+ } else {
+ qCDebug(QInstaller::lcGeneral) << "Headless installation: skip wizard page item addition: " << name;
}
return false;
}
@@ -1554,9 +1566,11 @@ bool PackageManagerCore::addWizardPageItem(Component *component, const QString &
*/
bool PackageManagerCore::removeWizardPageItem(Component *component, const QString &name)
{
- if (QWidget* const widget = component->userInterface(name)) {
- emit wizardWidgetRemovalRequested(widget);
- return true;
+ if (!isCommandLineInstance()) {
+ if (QWidget* const widget = component->userInterface(name)) {
+ emit wizardWidgetRemovalRequested(widget);
+ return true;
+ }
}
return false;
}
diff --git a/src/sdk/commandlineinterface.cpp b/src/sdk/commandlineinterface.cpp
new file mode 100644
index 000000000..26c4d216c
--- /dev/null
+++ b/src/sdk/commandlineinterface.cpp
@@ -0,0 +1,226 @@
+/**************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "commandlineinterface.h"
+
+#include <component.h>
+#include <init.h>
+#include <packagemanagercore.h>
+#include <globals.h>
+#include <productkeycheck.h>
+
+#include <QDir>
+#include <QDomDocument>
+
+#include <iostream>
+
+CommandLineInterface::CommandLineInterface(int &argc, char *argv[])
+ : SDKApp<QCoreApplication>(argc, argv)
+{
+ QInstaller::init(); // register custom operations
+ m_parser.parse(arguments());
+}
+
+bool CommandLineInterface::initialize()
+{
+ QString errorMessage;
+ if (!init(errorMessage)) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << errorMessage;
+ return false;
+ }
+ return true;
+}
+
+int CommandLineInterface::checkUpdates()
+{
+ if (!initialize())
+ return EXIT_FAILURE;
+ if (m_core->isInstaller()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << "Cannot start installer binary as updater.";
+ return EXIT_FAILURE;
+ }
+ m_core->setUpdater();
+ if (!m_core->fetchRemotePackagesTree()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << m_core->error();
+ return EXIT_FAILURE;
+ }
+
+ const QList<QInstaller::Component *> components =
+ m_core->components(QInstaller::PackageManagerCore::ComponentType::Root);
+ if (components.isEmpty()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << "There are currently no updates available.";
+ return EXIT_SUCCESS;
+ }
+
+ QDomDocument doc;
+ QDomElement root = doc.createElement(QLatin1String("updates"));
+ doc.appendChild(root);
+
+ foreach (QInstaller::Component *component, components) {
+ QDomElement update = doc.createElement(QLatin1String("update"));
+ update.setAttribute(QLatin1String("name"), component->value(QInstaller::scDisplayName));
+ update.setAttribute(QLatin1String("version"), component->value(QInstaller::scVersion));
+ update.setAttribute(QLatin1String("size"), component->value(QInstaller::scUncompressedSize));
+ root.appendChild(update);
+ }
+
+ std::cout << qPrintable(doc.toString(4)) << std::endl;
+ return EXIT_SUCCESS;
+}
+
+int CommandLineInterface::silentUpdate()
+{
+ if (!initialize())
+ return EXIT_FAILURE;
+ if (m_core->isInstaller()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << "Cannot start installer binary as updater.";
+ return EXIT_FAILURE;
+ }
+ if (!checkLicense())
+ return EXIT_FAILURE;
+ m_core->updateComponentsSilently(QStringList());
+ return EXIT_SUCCESS;
+}
+
+int CommandLineInterface::listInstalledPackages()
+{
+ if (!initialize())
+ return EXIT_FAILURE;
+ if (m_core->isInstaller()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << "Cannot start installer binary as package manager.";
+ return EXIT_FAILURE;
+ }
+ m_core->setPackageManager();
+ m_core->listInstalledPackages();
+ return EXIT_SUCCESS;
+}
+
+int CommandLineInterface::listAvailablePackages()
+{
+ if (!initialize())
+ return EXIT_FAILURE;
+ if (!m_core->isInstaller())
+ m_core->setPackageManager();
+ if (!checkLicense())
+ return EXIT_FAILURE;
+ QString regexp = m_parser.value(QLatin1String(CommandLineOptions::ListPackages));
+ m_core->listAvailablePackages(regexp);
+ return EXIT_SUCCESS;
+}
+
+int CommandLineInterface::updatePackages()
+{
+ if (!initialize())
+ return EXIT_FAILURE;
+ if (m_core->isInstaller()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << "Cannot start installer binary as updater.";
+ return EXIT_FAILURE;
+ }
+ if (!checkLicense())
+ return EXIT_FAILURE;
+ QStringList packages;
+ const QString &value = m_parser.value(QLatin1String(CommandLineOptions::UpdatePackages));
+ if (!value.isEmpty())
+ packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
+ m_core->updateComponentsSilently(packages);
+ return EXIT_SUCCESS;
+}
+
+int CommandLineInterface::install()
+{
+ if (!initialize() || (m_core->isInstaller() && !setTargetDir()) || !checkLicense())
+ return EXIT_FAILURE;
+ QStringList packages;
+ const QString &value = m_parser.value(QLatin1String(CommandLineOptions::InstallPackages));
+ if (!value.isEmpty())
+ packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
+ m_core->installSelectedComponentsSilently(packages);
+ return EXIT_SUCCESS;
+}
+
+int CommandLineInterface::installDefault()
+{
+ if (!initialize())
+ return EXIT_FAILURE;
+ if (!m_core->isInstaller()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << "Cannot start installer binary as updater.";
+ return EXIT_FAILURE;
+ }
+ if (!setTargetDir() || !checkLicense())
+ return EXIT_FAILURE;
+ m_core->installDefaultComponentsSilently();
+ return EXIT_SUCCESS;
+}
+
+int CommandLineInterface::uninstallPackages()
+{
+ if (!initialize())
+ return EXIT_FAILURE;
+ if (m_core->isInstaller()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << "Cannot start installer binary as package manager.";
+ return EXIT_FAILURE;
+ }
+ m_core->setPackageManager();
+ QStringList packages;
+ const QString &value = m_parser.value(QLatin1String(CommandLineOptions::UninstallSelectedPackages));
+ if (!value.isEmpty())
+ packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
+ m_core->uninstallComponentsSilently(packages);
+ return EXIT_SUCCESS;
+}
+
+bool CommandLineInterface::checkLicense()
+{
+ const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
+ if (!productKeyCheck->hasValidLicense()) {
+ qCWarning(QInstaller::lcPackageLicenses) << "No valid license found.";
+ return false;
+ }
+ return true;
+}
+
+bool CommandLineInterface::setTargetDir()
+{
+ QString targetDir;
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::TargetDir))) {
+ targetDir = m_parser.value(QLatin1String(CommandLineOptions::TargetDir));
+ } else {
+ targetDir = m_core->value(QLatin1String("TargetDir"));
+ qCDebug(QInstaller::lcInstallerInstallLog) << "No target directory specified, using default value:" << targetDir;
+ }
+ if (m_core->checkTargetDir(targetDir)) {
+ QString targetDirWarning = m_core->targetDirWarning(targetDir);
+ if (!targetDirWarning.isEmpty()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << m_core->targetDirWarning(targetDir);
+ } else {
+ m_core->setValue(QLatin1String("TargetDir"), targetDir);
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/sdk/updatechecker.h b/src/sdk/commandlineinterface.h
index d6bdef025..d68c5fc31 100644
--- a/src/sdk/updatechecker.h
+++ b/src/sdk/commandlineinterface.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -26,19 +26,31 @@
**
**************************************************************************/
-#ifndef UPDATECHECKER_H
-#define UPDATECHECKER_H
+#ifndef COMMANDLINEINTERFACE_H
+#define COMMANDLINEINTERFACE_H
#include "sdkapp.h"
-class UpdateChecker : public SDKApp<QCoreApplication>
+class CommandLineInterface : public SDKApp<QCoreApplication>
{
Q_OBJECT
- Q_DISABLE_COPY(UpdateChecker)
+ Q_DISABLE_COPY(CommandLineInterface)
public:
- UpdateChecker(int &argc, char *argv[]);
- int check();
+ CommandLineInterface(int &argc, char *argv[]);
+ int checkUpdates();
+ int silentUpdate();
+ int listInstalledPackages();
+ int listAvailablePackages();
+ int updatePackages();
+ int install();
+ int installDefault();
+ int uninstallPackages();
+
+private:
+ bool initialize();
+ bool checkLicense();
+ bool setTargetDir();
};
-#endif // UPDATECHECKER_H
+#endif // COMMANDLINEINTERFACE_H
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index e1b553b83..3cc5db5a5 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -26,37 +26,21 @@
**
**************************************************************************/
-#include "commandlineparser.h"
#include "installerbase.h"
+
#include "installerbasecommons.h"
#include "tabcontroller.h"
-#include <binaryformatenginehandler.h>
-#include <copydirectoryoperation.h>
-#include <errors.h>
#include <init.h>
-#include <updateoperations.h>
#include <messageboxhandler.h>
#include <packagemanagercore.h>
-#include <packagemanagerproxyfactory.h>
-#include <qprocesswrapper.h>
-#include <protocol.h>
-#include <productkeycheck.h>
-#include <settings.h>
-#include <utils.h>
#include <globals.h>
-#include <constants.h>
-
#include <runoncechecker.h>
-#include <filedownloaderfactory.h>
#include <QDir>
#include <QDirIterator>
#include <QFontDatabase>
-#include <QTemporaryFile>
#include <QTranslator>
-#include <QUuid>
-#include <QLoggingCategory>
#ifdef ENABLE_SQUISH
#include <qtbuiltinhook.h>
@@ -64,7 +48,6 @@
InstallerBase::InstallerBase(int &argc, char *argv[])
: SDKApp<QApplication>(argc, argv)
- , m_core(nullptr)
{
QInstaller::init(); // register custom operations
}
@@ -76,224 +59,35 @@ InstallerBase::~InstallerBase()
int InstallerBase::run()
{
- RunOnceChecker runCheck(QDir::tempPath()
- + QLatin1Char('/')
- + qApp->applicationName()
- + QLatin1String("1234865.lock"));
- if (runCheck.isRunning(RunOnceChecker::ConditionFlag::Lockfile)) {
- // It is possible that two installers with the same name get executed
- // concurrently and thus try to access the same lock file. This causes
- // a warning to be shown (when verbose output is enabled) but let's
- // just silently ignore the fact that we could not create the lock file
- // and check the running processes.
- if (runCheck.isRunning(RunOnceChecker::ConditionFlag::ProcessList)) {
- QInstaller::MessageBoxHandler::information(nullptr, QLatin1String("AlreadyRunning"),
- tr("Waiting for %1").arg(qAppName()),
- tr("Another %1 instance is already running. Wait "
- "until it finishes, close it, or restart your system.").arg(qAppName()));
- return EXIT_FAILURE;
- }
- }
-
- QFile binary(binaryFile());
-
-#ifdef Q_OS_WIN
- // On some admin user installations it is possible that the installer.dat
- // file is left without reading permissions for non-administrator users,
- // we should check this and prompt the user to run the executable as admin if needed.
- if (!binary.open(QIODevice::ReadOnly)) {
- QFileInfo binaryInfo(binary.fileName());
- QInstaller::MessageBoxHandler::information(nullptr, QLatin1String("NoReadingPermissions"),
- tr("Cannot open file \"%1\" for reading").arg(binaryInfo.fileName()),
- tr("Please make sure that the current user has reading access "
- "to file \"%1\" or try running %2 as an administrator.").arg(binaryInfo.fileName(), qAppName()));
+ QString errorMessage;
+ if (!init(errorMessage)) {
+ QInstaller::MessageBoxHandler::information(nullptr, QLatin1String("UnableToStart"),
+ tr("Unable to start installer"), errorMessage);
return EXIT_FAILURE;
}
- binary.close();
-#endif
- QString fileName = datFile(binaryFile());
- quint64 cookie = QInstaller::BinaryContent::MagicCookieDat;
- if (fileName.isEmpty()) {
- fileName = binaryFile();
- cookie = QInstaller::BinaryContent::MagicCookie;
- }
-
- binary.setFileName(fileName);
- QInstaller::openForRead(&binary);
-
- qint64 magicMarker;
- QInstaller::ResourceCollectionManager manager;
- QList<QInstaller::OperationBlob> oldOperations;
- QInstaller::BinaryContent::readBinaryContent(&binary, &oldOperations, &manager, &magicMarker,
- cookie);
-
- // Usually resources simply get mapped into memory and therefore the file does not need to be
- // kept open during application runtime. Though in case of offline installers we need to access
- // the appended binary content (packages etc.), so we close only in maintenance mode.
- if (magicMarker != QInstaller::BinaryContent::MagicInstallerMarker)
- binary.close();
-
- CommandLineParser parser;
- parser.parse(arguments());
- QString loggingRules(QLatin1String("ifw.* = false")); // disable all by default
- bool isCliInterface = false;
- foreach (const QString &option, CommandLineOptions::scCommandLineInterfaceOptions) {
- if (parser.isSet(option)) {
- isCliInterface = true;
- break;
- }
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::ShowVirtualComponents))) {
+ QFont f;
+ f.setItalic(true);
+ QInstaller::PackageManagerCore::setVirtualComponentsFont(f);
}
- if (QInstaller::isVerbose()) {
- if (parser.isSet(QLatin1String(CommandLineOptions::LoggingRules))) {
- loggingRules = parser.value(QLatin1String(CommandLineOptions::LoggingRules))
- .split(QLatin1Char(','), QString::SkipEmptyParts)
- .join(QLatin1Char('\n')); // take rules from command line
- } else if (isCliInterface) {
- loggingRules = QLatin1String("ifw.* = false\n"
- "ifw.installer.* = true\n"
- "ifw.server = true\n"
- "ifw.package.name = true\n"
- "ifw.package.version = true\n"
- "ifw.package.displayname = true\n");
- } else {
- // enable all in verbose mode except detailed package information
- loggingRules = QLatin1String("ifw.* = true\n"
- "ifw.package.* = false\n"
- "ifw.package.name = true\n"
- "ifw.package.version = true\n"
- "ifw.package.displayname = true\n");
+ QString controlScript;
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::Script))) {
+ controlScript = m_parser.value(QLatin1String(CommandLineOptions::Script));
+ if (!QFileInfo(controlScript).exists()) {
+ qCDebug(QInstaller::lcInstallerInstallLog) << "Script file does not exist.";
+ return false;
}
- }
- QLoggingCategory::setFilterRules(loggingRules);
-
- qCDebug(QInstaller::lcTranslations) << "Language:" << QLocale().uiLanguages()
- .value(0, QLatin1String("No UI language set")).toUtf8().constData();
- qCDebug(QInstaller::lcInstallerInstallLog).noquote() << "Arguments:" << arguments().join(QLatin1String(", "));
- SDKApp::registerMetaResources(manager.collectionByName("QResources"));
- if (parser.isSet(QLatin1String(CommandLineOptions::StartClient))) {
- const QStringList arguments = parser.value(QLatin1String(CommandLineOptions::StartClient))
- .split(QLatin1Char(','), QString::SkipEmptyParts);
- m_core = new QInstaller::PackageManagerCore(
- magicMarker, oldOperations,
- arguments.value(0, QLatin1String(QInstaller::Protocol::DefaultSocket)),
- arguments.value(1, QLatin1String(QInstaller::Protocol::DefaultAuthorizationKey)),
- QInstaller::Protocol::Mode::Debug);
- } else {
- m_core = new QInstaller::PackageManagerCore(magicMarker, oldOperations,
- QUuid::createUuid().toString(), QUuid::createUuid().toString());
- m_core->setCommandLineInstance(isCliInterface);
- }
-
- {
- using namespace QInstaller;
- ProductKeyCheck::instance()->init(m_core);
- ProductKeyCheck::instance()->addPackagesFromXml(QLatin1String(":/metadata/Updates.xml"));
- BinaryFormatEngineHandler::instance()->registerResources(manager.collections());
- }
-
- dumpResourceTree();
-
- QString controlScript;
- if (parser.isSet(QLatin1String(CommandLineOptions::Script))) {
- controlScript = parser.value(QLatin1String(CommandLineOptions::Script));
- if (!QFileInfo(controlScript).exists())
- throw QInstaller::Error(QLatin1String("Script file does not exist."));
} else if (!m_core->settings().controlScript().isEmpty()) {
controlScript = QLatin1String(":/metadata/installer-config/")
+ m_core->settings().controlScript();
}
+ qCDebug(QInstaller::lcTranslations) << "Language:" << QLocale().uiLanguages()
+ .value(0, QLatin1String("No UI language set")).toUtf8().constData();
+ qCDebug(QInstaller::lcInstallerInstallLog).noquote() << "Arguments:" << arguments().join(QLatin1String(", "));
- // From Qt5.8 onwards a separate command line option --proxy is not needed as system
- // proxy is used by default. If Qt is built with QT_USE_SYSTEM_PROXIES false
- // then system proxies are not used by default.
- if (parser.isSet(QLatin1String(CommandLineOptions::NoProxy))) {
- m_core->settings().setProxyType(QInstaller::Settings::NoProxy);
- KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
- } else if ((parser.isSet(QLatin1String(CommandLineOptions::Proxy))
- || QNetworkProxyFactory::usesSystemConfiguration())) {
- m_core->settings().setProxyType(QInstaller::Settings::SystemProxy);
- KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::ShowVirtualComponents))) {
- QFont f;
- f.setItalic(true);
- QInstaller::PackageManagerCore::setVirtualComponentsFont(f);
- QInstaller::PackageManagerCore::setVirtualComponentsVisible(true);
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::Updater))) {
- if (m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as updater."));
- m_core->setUserSetBinaryMarker(QInstaller::BinaryContent::MagicUpdaterMarker);
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::ManagePackages))) {
- if (m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as package manager."));
- m_core->setUserSetBinaryMarker(QInstaller::BinaryContent::MagicPackageManagerMarker);
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::Uninstaller))) {
- if (m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as uninstaller."));
- m_core->setUserSetBinaryMarker(QInstaller::BinaryContent::MagicUninstallerMarker);
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::AddRepository))) {
- const QStringList repoList = repositories(parser
- .value(QLatin1String(CommandLineOptions::AddRepository)));
- if (repoList.isEmpty())
- throw QInstaller::Error(QLatin1String("Empty repository list for option 'addRepository'."));
- m_core->addUserRepositories(repoList);
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::AddTmpRepository))) {
- const QStringList repoList = repositories(parser
- .value(QLatin1String(CommandLineOptions::AddTmpRepository)));
- if (repoList.isEmpty())
- throw QInstaller::Error(QLatin1String("Empty repository list for option 'addTempRepository'."));
- m_core->setTemporaryRepositories(repoList, false);
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::SetTmpRepository))) {
- const QStringList repoList = repositories(parser
- .value(QLatin1String(CommandLineOptions::SetTmpRepository)));
- if (repoList.isEmpty())
- throw QInstaller::Error(QLatin1String("Empty repository list for option 'setTempRepository'."));
- m_core->setTemporaryRepositories(repoList, true);
- }
-
- if (parser.isSet(QLatin1String(CommandLineOptions::InstallCompressedRepository))) {
- const QStringList repoList = repositories(parser
- .value(QLatin1String(CommandLineOptions::InstallCompressedRepository)));
- if (repoList.isEmpty())
- throw QInstaller::Error(QLatin1String("Empty repository list for option 'installCompressedRepository'."));
- foreach (QString repository, repoList) {
- if (!QFileInfo::exists(repository)) {
- qCWarning(QInstaller::lcInstallerInstallLog) << "The file " << repository << "does not exist.";
- return EXIT_FAILURE;
- }
- }
- m_core->setTemporaryRepositories(repoList, false, true);
- }
-
- QInstaller::PackageManagerCore::setNoForceInstallation(parser
- .isSet(QLatin1String(CommandLineOptions::NoForceInstallation)));
- QInstaller::PackageManagerCore::setCreateLocalRepositoryFromBinary(parser
- .isSet(QLatin1String(CommandLineOptions::CreateLocalRepository))
- || m_core->settings().createLocalRepository());
-
- const QStringList positionalArguments = parser.positionalArguments();
- foreach (const QString &argument, positionalArguments) {
- if (argument.contains(QLatin1Char('='))) {
- const QString name = argument.section(QLatin1Char('='), 0, 0);
- const QString value = argument.section(QLatin1Char('='), 1, 1);
- m_core->setValue(name, value);
- }
- }
+ dumpResourceTree();
const QString directory = QLatin1String(":/translations");
const QStringList translations = m_core->settings().translations();
@@ -334,113 +128,54 @@ int InstallerBase::run()
qCWarning(QInstaller::lcInstallerInstallLog) << "Failed to register font!";
}
}
+ //create the wizard GUI
+ TabController controller(nullptr);
+ controller.setManager(m_core);
+ controller.setControlScript(controlScript);
+ if (m_core->isInstaller())
+ controller.setGui(new InstallerGui(m_core));
+ else
+ controller.setGui(new MaintenanceGui(m_core));
- if (parser.isSet(QLatin1String(CommandLineOptions::SilentUpdate))) {
- if (m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as updater."));
- checkLicense();
- m_core->updateComponentsSilently(QStringList());
- } else if (parser.isSet(QLatin1String(CommandLineOptions::ListInstalledPackages))){
- if (m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as package manager."));
- checkLicense();
- m_core->setPackageManager();
- m_core->listInstalledPackages();
- } else if (parser.isSet(QLatin1String(CommandLineOptions::ListPackages))){
- if (!m_core->isInstaller())
- m_core->setPackageManager();
- checkLicense();
- QString regexp = parser.value(QLatin1String(CommandLineOptions::ListPackages));
- m_core->listAvailablePackages(regexp);
- } else if (parser.isSet(QLatin1String(CommandLineOptions::UpdatePackages))) {
- if (m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as updater."));
- checkLicense();
- QStringList packages;
- const QString &value = parser.value(QLatin1String(CommandLineOptions::UpdatePackages));
- if (!value.isEmpty())
- packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
- m_core->updateComponentsSilently(packages);
- } else if (parser.isSet(QLatin1String(CommandLineOptions::InstallPackages))) {
- checkLicense();
- m_core->autoRejectMessageBoxes();
- if (m_core->isInstaller()) {
- if (!setTargetDirForCommandLineInterface(parser))
- return EXIT_FAILURE;
- }
-
- QStringList packages;
- const QString &value = parser.value(QLatin1String(CommandLineOptions::InstallPackages));
- if (!value.isEmpty())
- packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
- m_core->installSelectedComponentsSilently(packages);
- } else if (parser.isSet(QLatin1String(CommandLineOptions::InstallDefault))) {
- if (!m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as installer."));
- checkLicense();
- m_core->autoRejectMessageBoxes();
- if (!setTargetDirForCommandLineInterface(parser))
- return EXIT_FAILURE;
- m_core->installDefaultComponentsSilently();
- } else if (parser.isSet(QLatin1String(CommandLineOptions::UninstallSelectedPackages))) {
- if (m_core->isInstaller())
- throw QInstaller::Error(QLatin1String("Cannot start installer binary as package manager."));
- m_core->setPackageManager();
- QStringList packages;
- const QString &value = parser.value(QLatin1String(CommandLineOptions::UninstallSelectedPackages));
- if (!value.isEmpty())
- packages = value.split(QLatin1Char(','), QString::SkipEmptyParts);
- m_core->uninstallComponentsSilently(packages);
- } else {
- //create the wizard GUI
- TabController controller(nullptr);
- controller.setManager(m_core);
- controller.setControlScript(controlScript);
- if (m_core->isInstaller())
- controller.setGui(new InstallerGui(m_core));
- else
- controller.setGui(new MaintenanceGui(m_core));
-
- QInstaller::PackageManagerCore::Status status =
- QInstaller::PackageManagerCore::Status(controller.init());
- if (status != QInstaller::PackageManagerCore::Success)
- return status;
+ QInstaller::PackageManagerCore::Status status =
+ QInstaller::PackageManagerCore::Status(controller.init());
+ if (status != QInstaller::PackageManagerCore::Success)
+ return status;
#ifdef ENABLE_SQUISH
- int squishPort = 11233;
- if (parser.isSet(QLatin1String(CommandLineOptions::SquishPort))) {
- squishPort = parser.value(QLatin1String(CommandLineOptions::SquishPort)).toInt();
- }
- if (squishPort != 0) {
- if (Squish::allowAttaching(squishPort))
- qCDebug(QInstaller::lcGeneral) << "Attaching to squish port " << squishPort << " succeeded";
- else
- qCDebug(QInstaller::lcGeneral) << "Attaching to squish failed.";
- } else {
- qCWarning(QInstaller::lcGeneral) << "Invalid squish port number: " << squishPort;
- }
+ int squishPort = 11233;
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::SquishPort))) {
+ squishPort = m_parser.value(QLatin1String(CommandLineOptions::SquishPort)).toInt();
+ }
+ if (squishPort != 0) {
+ if (Squish::allowAttaching(squishPort))
+ qCDebug(QInstaller::lcGeneral) << "Attaching to squish port " << squishPort << " succeeded";
+ else
+ qCDebug(QInstaller::lcGeneral) << "Attaching to squish failed.";
+ } else {
+ qCWarning(QInstaller::lcGeneral) << "Invalid squish port number: " << squishPort;
+ }
#endif
- const int result = QCoreApplication::instance()->exec();
- if (result != 0)
- return result;
+ const int result = QCoreApplication::instance()->exec();
+ if (result != 0)
+ return result;
- if (m_core->finishedWithSuccess())
- return QInstaller::PackageManagerCore::Success;
+ if (m_core->finishedWithSuccess())
+ return QInstaller::PackageManagerCore::Success;
- status = m_core->status();
- switch (status) {
- case QInstaller::PackageManagerCore::Success:
- return status;
+ status = m_core->status();
+ switch (status) {
+ case QInstaller::PackageManagerCore::Success:
+ return status;
- case QInstaller::PackageManagerCore::Canceled:
- return status;
+ case QInstaller::PackageManagerCore::Canceled:
+ return status;
- default:
- break;
- }
- return QInstaller::PackageManagerCore::Failure;
+ default:
+ break;
}
- return QInstaller::PackageManagerCore::Success;
+ return QInstaller::PackageManagerCore::Failure;
+
}
@@ -457,41 +192,3 @@ void InstallerBase::dumpResourceTree() const
qCDebug(QInstaller::lcResources) << " " << it.filePath().toUtf8().constData();
}
}
-
-QStringList InstallerBase::repositories(const QString &list) const
-{
- const QStringList items = list.split(QLatin1Char(','), QString::SkipEmptyParts);
- foreach (const QString &item, items)
- qCDebug(QInstaller::lcInstallerInstallLog).noquote() << "Adding custom repository:" << item;
- return items;
-}
-
-void InstallerBase::checkLicense()
-{
- const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
- if (!productKeyCheck->hasValidLicense()) {
- qCWarning(QInstaller::lcPackageLicenses) << "No valid license found.";
- throw QInstaller::Error(QLatin1String("No valid license found."));
- }
-}
-
-bool InstallerBase::setTargetDirForCommandLineInterface(CommandLineParser &parser)
-{
- QString targetDir;
- if (parser.isSet(QLatin1String(CommandLineOptions::TargetDir))) {
- targetDir = parser.value(QLatin1String(CommandLineOptions::TargetDir));
- } else {
- targetDir = m_core->value(QLatin1String("TargetDir"));
- qCDebug(QInstaller::lcInstallerInstallLog) << "No target directory specified, using default value:" << targetDir;
- }
- if (m_core->checkTargetDir(targetDir)) {
- QString targetDirWarning = m_core->targetDirWarning(targetDir);
- if (!targetDirWarning.isEmpty()) {
- qCWarning(QInstaller::lcInstallerInstallLog) << m_core->targetDirWarning(targetDir);
- } else {
- m_core->setValue(QLatin1String("TargetDir"), targetDir);
- return true;
- }
- }
- return false;
-}
diff --git a/src/sdk/installerbase.h b/src/sdk/installerbase.h
index a23a7856d..2efb6276e 100644
--- a/src/sdk/installerbase.h
+++ b/src/sdk/installerbase.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -50,11 +50,6 @@ public:
private:
void dumpResourceTree() const;
QStringList repositories(const QString &list) const;
- void checkLicense();
- bool setTargetDirForCommandLineInterface(CommandLineParser &parser);
-
-private:
- QInstaller::PackageManagerCore *m_core;
};
#endif // INSTALLERBASE_H
diff --git a/src/sdk/main.cpp b/src/sdk/main.cpp
index c2b5c9f01..5ce0615c7 100644
--- a/src/sdk/main.cpp
+++ b/src/sdk/main.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -31,7 +31,7 @@
#include "commandlineparser.h"
#include "installerbase.h"
#include "sdkapp.h"
-#include "updatechecker.h"
+#include "commandlineinterface.h"
#include <errors.h>
#include <selfrestarter.h>
@@ -216,13 +216,28 @@ int main(int argc, char *argv[])
if (parser.isSet(QLatin1String(CommandLineOptions::NoProxy)))
QNetworkProxyFactory::setUseSystemConfiguration(false);
+ const SelfRestarter restarter(argc, argv);
+
if (parser.isSet(QLatin1String(CommandLineOptions::CheckUpdates)))
- return UpdateChecker(argc, argv).check();
+ return CommandLineInterface(argc, argv).checkUpdates();
+ if (parser.isSet(QLatin1String(CommandLineOptions::SilentUpdate)))
+ return CommandLineInterface(argc, argv).silentUpdate();
+ if (parser.isSet(QLatin1String(CommandLineOptions::ListInstalledPackages)))
+ return CommandLineInterface(argc, argv).listInstalledPackages();
+ if (parser.isSet(QLatin1String(CommandLineOptions::ListPackages)))
+ return CommandLineInterface(argc, argv).listAvailablePackages();
+ if (parser.isSet(QLatin1String(CommandLineOptions::UpdatePackages)))
+ return CommandLineInterface(argc, argv).updatePackages();
+ if (parser.isSet(QLatin1String(CommandLineOptions::InstallPackages)))
+ return CommandLineInterface(argc, argv).install();
+ if (parser.isSet(QLatin1String(CommandLineOptions::InstallDefault)))
+ return CommandLineInterface(argc, argv).installDefault();
+ if (parser.isSet(QLatin1String(CommandLineOptions::UninstallSelectedPackages)))
+ return CommandLineInterface(argc, argv).uninstallPackages();
if (QInstaller::isVerbose())
std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl;
- const SelfRestarter restarter(argc, argv);
return InstallerBase(argc, argv).run();
} catch (const QInstaller::Error &e) {
diff --git a/src/sdk/sdk.pro b/src/sdk/sdk.pro
index 04c1c5016..08d08db39 100644
--- a/src/sdk/sdk.pro
+++ b/src/sdk/sdk.pro
@@ -100,7 +100,7 @@ HEADERS += \
settingsdialog.h \
console.h \
sdkapp.h \
- updatechecker.h \
+ commandlineinterface.h \
installerbase.h \
commandlineparser.h
@@ -110,7 +110,7 @@ SOURCES = \
tabcontroller.cpp \
installerbasecommons.cpp \
settingsdialog.cpp \
- updatechecker.cpp \
+ commandlineinterface.cpp \
commandlineparser.cpp
win32 {
diff --git a/src/sdk/sdkapp.h b/src/sdk/sdkapp.h
index 68d7a2434..235486086 100644
--- a/src/sdk/sdkapp.h
+++ b/src/sdk/sdkapp.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -29,23 +29,39 @@
#ifndef SDKAPP_H
#define SDKAPP_H
+#include "commandlineparser.h"
+
#include <binarycontent.h>
#include <binaryformat.h>
#include <fileio.h>
#include <fileutils.h>
+#include <constants.h>
+#include <packagemanagercore.h>
+#include <settings.h>
+#include <productkeycheck.h>
+#include <binaryformatenginehandler.h>
+#include <filedownloaderfactory.h>
+#include <packagemanagerproxyfactory.h>
+#include <utils.h>
+#include <runoncechecker.h>
+#include <globals.h>
#include <QApplication>
#include <QDir>
#include <QFileInfo>
#include <QResource>
+#include <QLoggingCategory>
+#include <QUuid>
template<class T>
class SDKApp : public T
{
public:
SDKApp(int& argc, char** argv)
- : T(argc, argv)
+ : T(argc, argv), m_runCheck(QDir::tempPath() + QLatin1Char('/')
+ + qApp->applicationName() + QLatin1String("1234865.lock"))
{
+ m_parser.parse(QCoreApplication::arguments());
}
virtual ~SDKApp()
@@ -66,6 +82,210 @@ public:
return false;
}
+ bool init(QString &errorMessage) {
+ QString appname = qApp->applicationName();
+
+ if (m_runCheck.isRunning(RunOnceChecker::ConditionFlag::Lockfile)) {
+ // It is possible to install an application and thus the maintenance tool into a
+ // directory that requires elevated permission to create a lock file. Since this
+ // cannot be done without requesting credentials from the user, we silently ignore
+ // the fact that we could not create the lock file and check the running processes.
+ if (m_runCheck.isRunning(RunOnceChecker::ConditionFlag::ProcessList)) {
+ errorMessage = QObject::tr("Another %1 instance is already running. Wait "
+ "until it finishes, close it, or restart your system.").arg(qAppName());
+ return false;
+ }
+ }
+ QFile binary(binaryFile());
+ #ifdef Q_OS_WIN
+ // On some admin user installations it is possible that the installer.dat
+ // file is left without reading permissions for non-administrator users,
+ // we should check this and prompt the user to run the executable as admin if needed.
+ if (!binary.open(QIODevice::ReadOnly)) {
+ QFileInfo binaryInfo(binary.fileName());
+ errorMessage = QObject::tr("Please make sure that the current user has reading access "
+ "to file \"%1\" or try running %2 as an administrator.").arg(binaryInfo.fileName(), qAppName());
+ return false;
+ }
+ binary.close();
+ #endif
+ QString fileName = datFile(binaryFile());
+ quint64 cookie = QInstaller::BinaryContent::MagicCookieDat;
+ if (fileName.isEmpty()) {
+ fileName = binaryFile();
+ cookie = QInstaller::BinaryContent::MagicCookie;
+ }
+
+ binary.setFileName(fileName);
+ QInstaller::openForRead(&binary);
+
+ qint64 magicMarker;
+ QInstaller::ResourceCollectionManager manager;
+ QList<QInstaller::OperationBlob> oldOperations;
+
+ QInstaller::BinaryContent::readBinaryContent(&binary, &oldOperations, &manager, &magicMarker,
+ cookie);
+ // Usually resources simply get mapped into memory and therefore the file does not need to be
+ // kept open during application runtime. Though in case of offline installers we need to access
+ // the appended binary content (packages etc.), so we close only in maintenance mode.
+ if (magicMarker != QInstaller::BinaryContent::MagicInstallerMarker)
+ binary.close();
+
+ QString loggingRules(QLatin1String("ifw.* = false")); // disable all by default
+ bool isCliInterface = false;
+ foreach (const QString &option, CommandLineOptions::scCommandLineInterfaceOptions) {
+ if (m_parser.isSet(option)) {
+ isCliInterface = true;
+ break;
+ }
+ }
+ if (QInstaller::isVerbose()) {
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::LoggingRules))) {
+ loggingRules = m_parser.value(QLatin1String(CommandLineOptions::LoggingRules))
+ .split(QLatin1Char(','), QString::SkipEmptyParts)
+ .join(QLatin1Char('\n')); // take rules from command line
+ } else if (isCliInterface) {
+ loggingRules = QLatin1String("ifw.* = false\n"
+ "ifw.installer.* = true\n"
+ "ifw.server = true\n"
+ "ifw.package.name = true\n"
+ "ifw.package.version = true\n"
+ "ifw.package.displayname = true\n");
+ } else {
+ // enable all in verbose mode except detailed package information
+ loggingRules = QLatin1String("ifw.* = true\n"
+ "ifw.package.* = false\n"
+ "ifw.package.name = true\n"
+ "ifw.package.version = true\n"
+ "ifw.package.displayname = true\n");
+ }
+ }
+ QLoggingCategory::setFilterRules(loggingRules);
+
+ SDKApp::registerMetaResources(manager.collectionByName("QResources"));
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::StartClient))) {
+ const QStringList arguments = m_parser.value(QLatin1String(CommandLineOptions::StartClient))
+ .split(QLatin1Char(','), QString::SkipEmptyParts);
+ m_core = new QInstaller::PackageManagerCore(
+ magicMarker, oldOperations,
+ arguments.value(0, QLatin1String(QInstaller::Protocol::DefaultSocket)),
+ arguments.value(1, QLatin1String(QInstaller::Protocol::DefaultAuthorizationKey)),
+ QInstaller::Protocol::Mode::Debug);
+ } else {
+ m_core = new QInstaller::PackageManagerCore(magicMarker, oldOperations,
+ QUuid::createUuid().toString(), QUuid::createUuid().toString());
+ m_core->setCommandLineInstance(isCliInterface);
+ }
+
+ {
+ using namespace QInstaller;
+ ProductKeyCheck::instance()->init(m_core);
+ ProductKeyCheck::instance()->addPackagesFromXml(QLatin1String(":/metadata/Updates.xml"));
+ BinaryFormatEngineHandler::instance()->registerResources(manager.collections());
+ }
+
+ // From Qt5.8 onwards a separate command line option --proxy is not needed as system
+ // proxy is used by default. If Qt is built with QT_USE_SYSTEM_PROXIES false
+ // then system proxies are not used by default.
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::NoProxy))) {
+ m_core->settings().setProxyType(QInstaller::Settings::NoProxy);
+ KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
+ } else if ((m_parser.isSet(QLatin1String(CommandLineOptions::Proxy))
+ || QNetworkProxyFactory::usesSystemConfiguration())) {
+ m_core->settings().setProxyType(QInstaller::Settings::SystemProxy);
+ KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
+ }
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::ShowVirtualComponents)))
+ QInstaller::PackageManagerCore::setVirtualComponentsVisible(true);
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::Updater))) {
+ if (m_core->isInstaller()) {
+ errorMessage = QObject::tr("Cannot start installer binary as updater.");
+ return false;
+ }
+ m_core->setUserSetBinaryMarker(QInstaller::BinaryContent::MagicUpdaterMarker);
+ }
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::ManagePackages))) {
+ if (m_core->isInstaller()) {
+ errorMessage = QObject::tr("Cannot start installer binary as package manager.");
+ return false;
+ }
+ m_core->setUserSetBinaryMarker(QInstaller::BinaryContent::MagicPackageManagerMarker);
+ }
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::Uninstaller))) {
+ if (m_core->isInstaller()) {
+ errorMessage = QObject::tr("Cannot start installer binary as uninstaller.");
+ return false;
+ }
+ m_core->setUserSetBinaryMarker(QInstaller::BinaryContent::MagicUninstallerMarker);
+ }
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::AddRepository))) {
+ const QStringList repoList = repositories(m_parser
+ .value(QLatin1String(CommandLineOptions::AddRepository)));
+ if (repoList.isEmpty()) {
+ errorMessage = QObject::tr("Empty repository list for option 'addRepository'.");
+ return false;
+ }
+ m_core->addUserRepositories(repoList);
+ }
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::AddTmpRepository))) {
+ const QStringList repoList = repositories(m_parser
+ .value(QLatin1String(CommandLineOptions::AddTmpRepository)));
+ if (repoList.isEmpty()) {
+ errorMessage = QObject::tr("Empty repository list for option 'addTempRepository'.");
+ return false;
+ }
+ m_core->setTemporaryRepositories(repoList, false);
+ }
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::SetTmpRepository))) {
+ const QStringList repoList = repositories(m_parser
+ .value(QLatin1String(CommandLineOptions::SetTmpRepository)));
+ if (repoList.isEmpty()) {
+ errorMessage = QObject::tr("Empty repository list for option 'setTempRepository'.");
+ return false;
+ }
+ m_core->setTemporaryRepositories(repoList, true);
+ }
+
+ if (m_parser.isSet(QLatin1String(CommandLineOptions::InstallCompressedRepository))) {
+ const QStringList repoList = repositories(m_parser
+ .value(QLatin1String(CommandLineOptions::InstallCompressedRepository)));
+ if (repoList.isEmpty()) {
+ errorMessage = QObject::tr("Empty repository list for option 'installCompressedRepository'.");
+ return false;
+ }
+ foreach (QString repository, repoList) {
+ if (!QFileInfo::exists(repository)) {
+ errorMessage = QObject::tr("The file %1 does not exist.").arg(repository);
+ return false;
+ }
+ }
+ m_core->setTemporaryRepositories(repoList, false, true);
+ }
+
+ QInstaller::PackageManagerCore::setNoForceInstallation(m_parser
+ .isSet(QLatin1String(CommandLineOptions::NoForceInstallation)));
+ QInstaller::PackageManagerCore::setCreateLocalRepositoryFromBinary(m_parser
+ .isSet(QLatin1String(CommandLineOptions::CreateLocalRepository))
+ || m_core->settings().createLocalRepository());
+
+ const QStringList positionalArguments = m_parser.positionalArguments();
+ foreach (const QString &argument, positionalArguments) {
+ if (argument.contains(QLatin1Char('='))) {
+ const QString name = argument.section(QLatin1Char('='), 0, 0);
+ const QString value = argument.section(QLatin1Char('='), 1, 1);
+ m_core->setValue(name, value);
+ }
+ }
+ return true;
+ }
+
/*!
Returns the installer binary or installer.dat. In case of an installer this will be the
installer binary itself, which contains the binary layout and the binary content. In case
@@ -147,8 +367,21 @@ public:
}
}
+ QStringList repositories(const QString &list) const
+ {
+ const QStringList items = list.split(QLatin1Char(','), QString::SkipEmptyParts);
+ foreach (const QString &item, items)
+ qCDebug(QInstaller::lcGeneral) << "Adding custom repository:" << item;
+ return items;
+ }
+
private:
QList<QByteArray> m_resourceMappings;
+
+public:
+ QInstaller::PackageManagerCore *m_core;
+ CommandLineParser m_parser;
+ RunOnceChecker m_runCheck;
};
#endif // SDKAPP_H
diff --git a/src/sdk/updatechecker.cpp b/src/sdk/updatechecker.cpp
deleted file mode 100644
index 63bac8b9f..000000000
--- a/src/sdk/updatechecker.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/**************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-**************************************************************************/
-
-#include "updatechecker.h"
-
-#include <binaryformatenginehandler.h>
-#include <component.h>
-#include <errors.h>
-#include <init.h>
-#include <runoncechecker.h>
-#include <packagemanagercore.h>
-#include <productkeycheck.h>
-
-#include <QDir>
-#include <QDomDocument>
-
-#include <iostream>
-
-UpdateChecker::UpdateChecker(int &argc, char *argv[])
- : SDKApp<QCoreApplication>(argc, argv)
-{
- QInstaller::init(); // register custom operations
-}
-
-int UpdateChecker::check()
-{
- RunOnceChecker runCheck(QDir::tempPath()
- + QLatin1Char('/')
- + qApp->applicationName()
- + QLatin1String("15021976.lock"));
- if (runCheck.isRunning(RunOnceChecker::ConditionFlag::Lockfile)) {
- // It is possible to install an application and thus the maintenance tool into a
- // directory that requires elevated permission to create a lock file. Since this
- // cannot be done without requesting credentials from the user, we silently ignore
- // the fact that we could not create the lock file and check the running processes.
- if (runCheck.isRunning(RunOnceChecker::ConditionFlag::ProcessList))
- throw QInstaller::Error(QLatin1String("An instance is already checking for updates."));
- }
-
- QString fileName = datFile(binaryFile());
- quint64 cookie = QInstaller::BinaryContent::MagicCookieDat;
- if (fileName.isEmpty()) {
- fileName = binaryFile();
- cookie = QInstaller::BinaryContent::MagicCookie;
- }
-
- QFile binary(fileName);
- QInstaller::openForRead(&binary);
-
- qint64 magicMarker;
- QList<QInstaller::OperationBlob> operations;
- QInstaller::ResourceCollectionManager manager;
- QInstaller::BinaryContent::readBinaryContent(&binary, &operations, &manager, &magicMarker,
- cookie);
-
- if (magicMarker == QInstaller::BinaryContent::MagicInstallerMarker)
- throw QInstaller::Error(QLatin1String("Installers cannot check for updates."));
-
- SDKApp::registerMetaResources(manager.collectionByName("QResources"));
-
- QInstaller::PackageManagerCore core(QInstaller::BinaryContent::MagicUpdaterMarker, operations);
- QInstaller::PackageManagerCore::setVirtualComponentsVisible(true);
- {
- using namespace QInstaller;
- ProductKeyCheck::instance()->init(&core);
- ProductKeyCheck::instance()->addPackagesFromXml(QLatin1String(":/metadata/Updates.xml"));
- BinaryFormatEngineHandler::instance()->registerResources(manager.collections());
- }
- if (!core.fetchRemotePackagesTree())
- throw QInstaller::Error(core.error());
-
- const QList<QInstaller::Component *> components =
- core.components(QInstaller::PackageManagerCore::ComponentType::Root);
- if (components.isEmpty())
- throw QInstaller::Error(QLatin1String("There are currently no updates available."));
-
- QDomDocument doc;
- QDomElement root = doc.createElement(QLatin1String("updates"));
- doc.appendChild(root);
-
- foreach (QInstaller::Component *component, components) {
- QDomElement update = doc.createElement(QLatin1String("update"));
- update.setAttribute(QLatin1String("name"), component->value(QInstaller::scDisplayName));
- update.setAttribute(QLatin1String("version"), component->value(QInstaller::scVersion));
- update.setAttribute(QLatin1String("size"), component->value(QInstaller::scUncompressedSize));
- root.appendChild(update);
- }
-
- std::cout << qPrintable(doc.toString(4)) << std::endl;
- return EXIT_SUCCESS;
-}