mirror of
https://github.com/QuasarApp/installer-framework.git
synced 2025-04-27 22:14:32 +00:00
Introduce developer tool.
Supports dump binary content, run operation and update existing binary with new installer base. The support for starting with binary data of a different installer got dropped completely, use update and run instead. Change-Id: I41073d0bfc9a4c4da18fbb9f49fd3e65bb54b501 Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
parent
e6390254c6
commit
2a364e7135
@ -71,7 +71,6 @@ HEADERS += packagemanagercore.h \
|
||||
downloadarchivesjob.h \
|
||||
init.h \
|
||||
updater.h \
|
||||
operationrunner.h \
|
||||
adminauthorization.h \
|
||||
elevatedexecuteoperation.h \
|
||||
fakestopprocessforupdateoperation.h \
|
||||
@ -153,7 +152,6 @@ SOURCES += packagemanagercore.cpp \
|
||||
downloadarchivesjob.cpp \
|
||||
init.cpp \
|
||||
updater.cpp \
|
||||
operationrunner.cpp \
|
||||
elevatedexecuteoperation.cpp \
|
||||
fakestopprocessforupdateoperation.cpp \
|
||||
lazyplaintextedit.cpp \
|
||||
|
@ -1,185 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012-2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**************************************************************************/
|
||||
#include "operationrunner.h"
|
||||
|
||||
#include "errors.h"
|
||||
#include "init.h"
|
||||
#include "packagemanagercore.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "kdupdaterupdateoperationfactory.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
class OutputHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
void drawItToCommandLine(const QString &outPut)
|
||||
{
|
||||
std::cout << qPrintable(outPut) << std::endl;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using namespace QInstaller;
|
||||
using namespace QInstallerCreator;
|
||||
|
||||
OperationRunner::OperationRunner()
|
||||
: m_core(0)
|
||||
{
|
||||
m_path = QCoreApplication::applicationFilePath();
|
||||
#ifdef Q_OS_OSX
|
||||
QDir resourcePath(QFileInfo(m_path).dir());
|
||||
resourcePath.cdUp();
|
||||
resourcePath.cd(QLatin1String("Resources"));
|
||||
m_path = resourcePath.filePath(QLatin1String("installer.dat"));
|
||||
#endif
|
||||
}
|
||||
|
||||
OperationRunner::OperationRunner(const QString &path)
|
||||
: m_core(0)
|
||||
, m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
OperationRunner::~OperationRunner()
|
||||
{
|
||||
delete m_core;
|
||||
}
|
||||
|
||||
bool OperationRunner::init()
|
||||
{
|
||||
try {
|
||||
QInstaller::init();
|
||||
|
||||
m_bc = BinaryContent::readAndRegisterFromBinary(m_path);
|
||||
m_core = new PackageManagerCore(m_bc.magicMarker(), m_bc.performedOperations());
|
||||
} catch (const Error &e) {
|
||||
std::cerr << qPrintable(e.message()) << std::endl;
|
||||
return false;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OperationRunner::setVerbose(bool verbose)
|
||||
{
|
||||
QInstaller::setVerbose(verbose);
|
||||
}
|
||||
|
||||
int OperationRunner::runOperation(const QStringList &arguments)
|
||||
{
|
||||
if (!init()) {
|
||||
qDebug() << "Could not init the package manager core - without this not all operations are working "
|
||||
"as expected.";
|
||||
}
|
||||
|
||||
bool isPerformType = arguments.contains(QLatin1String("--runoperation"));
|
||||
bool isUndoType = arguments.contains(QLatin1String("--undooperation"));
|
||||
|
||||
if ((!isPerformType && !isUndoType) || (isPerformType && isUndoType)) {
|
||||
std::cerr << "wrong arguments are used, cannot run this operation";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
QStringList argumentList;
|
||||
|
||||
if (isPerformType)
|
||||
argumentList = arguments.mid(arguments.indexOf(QLatin1String("--runoperation")) + 1);
|
||||
else
|
||||
argumentList = arguments.mid(arguments.indexOf(QLatin1String("--undooperation")) + 1);
|
||||
|
||||
|
||||
try {
|
||||
const QString operationName = argumentList.takeFirst();
|
||||
KDUpdater::UpdateOperation* const operation = KDUpdater::UpdateOperationFactory::instance()
|
||||
.create(operationName);
|
||||
if (!operation) {
|
||||
std::cerr << "Can not find the operation: " << qPrintable(operationName) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
OutputHandler myOutPutHandler;
|
||||
QObject *const operationObject = dynamic_cast<QObject *>(operation);
|
||||
if (operationObject != 0) {
|
||||
const QMetaObject *const mo = operationObject->metaObject();
|
||||
if (mo->indexOfSignal(QMetaObject::normalizedSignature("outputTextChanged(QString)")) > -1) {
|
||||
QObject::connect(operationObject, SIGNAL(outputTextChanged(QString)),
|
||||
&myOutPutHandler, SLOT(drawItToCommandLine(QString)));
|
||||
}
|
||||
}
|
||||
|
||||
operation->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
|
||||
|
||||
operation->setArguments(argumentList);
|
||||
|
||||
bool readyPerformed = false;
|
||||
if (isPerformType)
|
||||
readyPerformed = operation->performOperation();
|
||||
|
||||
if (isUndoType)
|
||||
readyPerformed = operation->undoOperation();
|
||||
|
||||
std::cout << "========================================" << std::endl;
|
||||
if (readyPerformed) {
|
||||
std::cout << "Operation was successfully performed." << std::endl;
|
||||
} else {
|
||||
std::cerr << "There was a problem while performing the operation: "
|
||||
<< qPrintable(operation->errorString()) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} catch (const QInstaller::Error &e) {
|
||||
std::cerr << qPrintable(e.message()) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
} catch (...) {
|
||||
std::cerr << "Caught unknown exception" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#include "operationrunner.moc"
|
147
tools/devtool/binarydump.cpp
Normal file
147
tools/devtool/binarydump.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "binarydump.h"
|
||||
|
||||
#include <copydirectoryoperation.h>
|
||||
#include <errors.h>
|
||||
#include <fileio.h>
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QDomDocument>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int BinaryDump::dump(const QInstallerCreator::ComponentIndex &index, const QString &target)
|
||||
{
|
||||
QDir targetDir(QFileInfo(target).absoluteFilePath());
|
||||
if (targetDir.exists()) {
|
||||
if (!targetDir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty()) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Target directory '%1' already exists and "
|
||||
"is not empty.").arg(targetDir.path())) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
if (!QDir().mkpath(targetDir.path())) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Could not create '%1'.").arg(targetDir
|
||||
.path())) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
QInstaller::CopyDirectoryOperation copyMetadata;
|
||||
copyMetadata.setArguments(QStringList() << QLatin1String(":/")
|
||||
<< (targetDir.path() + QLatin1Char('/'))); // Add "/" at the end to make operation work.
|
||||
if (!copyMetadata.performOperation()) {
|
||||
std::cerr << qPrintable(copyMetadata.errorString()) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!targetDir.cd(QLatin1String("metadata"))) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Could not switch to '%1/metadata'.")
|
||||
.arg(targetDir.path())) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int result = EXIT_FAILURE;
|
||||
try {
|
||||
QFile updatesXml(targetDir.filePath(QLatin1String("Updates.xml")));
|
||||
QInstaller::openForRead(&updatesXml);
|
||||
|
||||
QString error;
|
||||
QDomDocument doc;
|
||||
if (!doc.setContent(&updatesXml, &error)) {
|
||||
throw QInstaller::Error(QString::fromLatin1("Could not read: '%1'. %2").arg(updatesXml
|
||||
.fileName(), error));
|
||||
}
|
||||
|
||||
QHash<QString, QString> versionMap;
|
||||
const QDomElement root = doc.documentElement();
|
||||
const QDomNodeList rootChildNodes = root.childNodes();
|
||||
for (int i = 0; i < rootChildNodes.count(); ++i) {
|
||||
const QDomElement element = rootChildNodes.at(i).toElement();
|
||||
if (element.isNull())
|
||||
continue;
|
||||
|
||||
QString name, version;
|
||||
if (element.tagName() == QLatin1String("PackageUpdate")) {
|
||||
const QDomNodeList elementChildNodes = element.childNodes();
|
||||
for (int j = 0; j < elementChildNodes.count(); ++j) {
|
||||
const QDomElement e = elementChildNodes.at(j).toElement();
|
||||
if (e.tagName() == QLatin1String("Name"))
|
||||
name = e.text();
|
||||
else if (e.tagName() == QLatin1String("Version"))
|
||||
version = e.text();
|
||||
}
|
||||
versionMap.insert(name, version);
|
||||
}
|
||||
}
|
||||
|
||||
QDirIterator it(targetDir, QDirIterator::Subdirectories);
|
||||
while (it.hasNext() && !it.next().isEmpty()) {
|
||||
if (!it.fileInfo().isDir())
|
||||
continue;
|
||||
|
||||
const QString fileName = it.fileName();
|
||||
QInstallerCreator::Component c = index.componentByName(fileName.toUtf8());
|
||||
if (c.archives().count() <= 0)
|
||||
continue;
|
||||
|
||||
typedef QSharedPointer<QInstallerCreator::Archive> Archive;
|
||||
QVector<Archive> archives = c.archives();
|
||||
foreach (const Archive &archive, archives) {
|
||||
if (!archive->open(QIODevice::ReadOnly))
|
||||
continue; // TODO: should we throw here?
|
||||
|
||||
QFile target(targetDir.filePath(fileName) + QDir::separator()
|
||||
+ QString::fromUtf8(archive->name()));
|
||||
QInstaller::openForWrite(&target);
|
||||
archive->copyData(&target); // copy the 7z files into the target directory
|
||||
}
|
||||
}
|
||||
result = EXIT_SUCCESS;
|
||||
} catch (const QInstaller::Error &error) {
|
||||
std::cerr << qPrintable(error.message()) << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << "Unknown exception caught." << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
56
tools/devtool/binarydump.h
Normal file
56
tools/devtool/binarydump.h
Normal file
@ -0,0 +1,56 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef BINARYDUMP_H
|
||||
#define BINARYDUMP_H
|
||||
|
||||
#include <binaryformat.h>
|
||||
|
||||
class BinaryDump
|
||||
{
|
||||
Q_DISABLE_COPY(BinaryDump)
|
||||
|
||||
public:
|
||||
BinaryDump() {}
|
||||
int dump(const QInstallerCreator::ComponentIndex &index, const QString &target);
|
||||
};
|
||||
|
||||
#endif // BINARYDUMP_H
|
167
tools/devtool/binaryreplace.cpp
Normal file
167
tools/devtool/binaryreplace.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "binaryreplace.h"
|
||||
|
||||
#include <copyfiletask.h>
|
||||
#include <downloadfiletask.h>
|
||||
#include <errors.h>
|
||||
#include <fileio.h>
|
||||
#include <fileutils.h>
|
||||
#include <lib7z_facade.h>
|
||||
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
BinaryReplace::BinaryReplace(const QInstaller::BinaryLayout &layout)
|
||||
: m_binaryLayout(layout)
|
||||
{}
|
||||
|
||||
int BinaryReplace::replace(const QString &source, const QString &target)
|
||||
{
|
||||
const QUrl url = QUrl::fromUserInput(source);
|
||||
QFutureWatcher<QInstaller::FileTaskResult> taskWatcher;
|
||||
if (url.isLocalFile()) {
|
||||
taskWatcher.setFuture(QtConcurrent::run(&QInstaller::CopyFileTask::doTask,
|
||||
new QInstaller::CopyFileTask(QInstaller::FileTaskItem(url.toLocalFile()))));
|
||||
} else {
|
||||
taskWatcher.setFuture(QtConcurrent::run(&QInstaller::DownloadFileTask::doTask,
|
||||
new QInstaller::DownloadFileTask(QInstaller::FileTaskItem(url.toString()))));
|
||||
}
|
||||
|
||||
bool result = EXIT_FAILURE;
|
||||
try {
|
||||
taskWatcher.waitForFinished(); // throws on error
|
||||
const QFuture<QInstaller::FileTaskResult> future = taskWatcher.future();
|
||||
if (future.resultCount() <= 0)
|
||||
return result;
|
||||
|
||||
QString newInstallerBasePath = future.result().target();
|
||||
if (Lib7z::isSupportedArchive(newInstallerBasePath)) {
|
||||
QFile archive(newInstallerBasePath);
|
||||
if (archive.open(QIODevice::ReadOnly)) {
|
||||
try {
|
||||
Lib7z::extractArchive(&archive, QDir::tempPath());
|
||||
const QVector<Lib7z::File> files = Lib7z::listArchive(&archive);
|
||||
newInstallerBasePath = QDir::tempPath() + QLatin1Char('/') + files.value(0)
|
||||
.path;
|
||||
result = EXIT_SUCCESS;
|
||||
} catch (const Lib7z::SevenZipException& e) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Error while extracting '%1': %2.")
|
||||
.arg(newInstallerBasePath, e.message())) << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Unknown exception caught while "
|
||||
"extracting '%1'.").arg(newInstallerBasePath)) << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Could not open '%1' for reading: %2.")
|
||||
.arg(newInstallerBasePath, archive.errorString())) << std::endl;
|
||||
}
|
||||
if (!archive.remove()) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Could not delete file '%1': %2.")
|
||||
.arg(newInstallerBasePath, archive.errorString())) << std::endl;
|
||||
}
|
||||
if (result != EXIT_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = EXIT_FAILURE;
|
||||
try {
|
||||
QFile installerBaseNew(newInstallerBasePath);
|
||||
#ifndef Q_OS_OSX
|
||||
QFile installerBaseOld(target);
|
||||
QInstaller::openForAppend(&installerBaseNew);
|
||||
|
||||
installerBaseNew.seek(installerBaseNew.size());
|
||||
if (m_binaryLayout.magicMarker == QInstaller::MagicInstallerMarker) {
|
||||
QInstaller::openForRead(&installerBaseOld);
|
||||
installerBaseOld.seek(m_binaryLayout.metadataResourceSegments.first().start());
|
||||
QInstaller::appendData(&installerBaseNew, &installerBaseOld, installerBaseOld
|
||||
.size() - installerBaseOld.pos());
|
||||
installerBaseOld.close();
|
||||
} else {
|
||||
QInstaller::appendInt64(&installerBaseNew, 0);
|
||||
QInstaller::appendInt64(&installerBaseNew, 4 * sizeof(qint64));
|
||||
QInstaller::appendInt64(&installerBaseNew, QInstaller::MagicUninstallerMarker);
|
||||
QInstaller::appendInt64(&installerBaseNew, QInstaller::MagicCookie);
|
||||
}
|
||||
installerBaseNew.close();
|
||||
#else
|
||||
QString bundlePath;
|
||||
QInstaller::isInBundle(target, &bundlePath);
|
||||
QFile installerBaseOld(QDir(bundlePath).filePath(bundlePath
|
||||
+ QLatin1String("/Contents/MacOS/") + QFileInfo(bundlePath).completeBaseName()));
|
||||
#endif
|
||||
installerBaseNew.setPermissions(installerBaseOld.permissions());
|
||||
|
||||
QFile backup(installerBaseOld.fileName() + QLatin1String(".bak"));
|
||||
if (backup.exists() && (!backup.remove())) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Could not delete '%1'. %2")
|
||||
.arg(backup.fileName(), backup.errorString())) << std::endl;
|
||||
}
|
||||
|
||||
const QString oldBasePath = installerBaseOld.fileName();
|
||||
if (!installerBaseOld.rename(oldBasePath + QLatin1String(".bak"))) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Could not rename '%1' to '%2'. %3")
|
||||
.arg(oldBasePath, oldBasePath + QLatin1String(".bak"),
|
||||
installerBaseOld.errorString())) << std::endl;
|
||||
}
|
||||
|
||||
if (!installerBaseNew.rename(oldBasePath)) {
|
||||
std::cerr << qPrintable(QString::fromLatin1("Could not copy '%1' to '%2'. %3")
|
||||
.arg(installerBaseNew.fileName(), oldBasePath, installerBaseNew.errorString()))
|
||||
<< std::endl;
|
||||
} else {
|
||||
result = EXIT_SUCCESS;
|
||||
}
|
||||
} catch (const QInstaller::Error &error) {
|
||||
std::cerr << qPrintable(error.message()) << std::endl;
|
||||
}
|
||||
} catch (const QInstaller::FileTaskException &e) {
|
||||
std::cerr << qPrintable(e.message()) << std::endl;
|
||||
} catch (const QUnhandledException &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << "Unknown exception caught."<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
59
tools/devtool/binaryreplace.h
Normal file
59
tools/devtool/binaryreplace.h
Normal file
@ -0,0 +1,59 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef BINARYREPLACE_H
|
||||
#define BINARYREPLACE_H
|
||||
|
||||
#include <binaryformat.h>
|
||||
|
||||
class BinaryReplace
|
||||
{
|
||||
Q_DISABLE_COPY(BinaryReplace)
|
||||
|
||||
public:
|
||||
BinaryReplace(const QInstaller::BinaryLayout &layout);
|
||||
int replace(const QString &source, const QString &target);
|
||||
|
||||
private:
|
||||
QInstaller::BinaryLayout m_binaryLayout;
|
||||
};
|
||||
|
||||
#endif // BINARYREPLACE_H
|
21
tools/devtool/devtool.pro
Normal file
21
tools/devtool/devtool.pro
Normal file
@ -0,0 +1,21 @@
|
||||
TEMPLATE = app
|
||||
TARGET = devtool
|
||||
|
||||
include(../../installerfw.pri)
|
||||
|
||||
QT -= gui
|
||||
QT += network xml
|
||||
|
||||
CONFIG += console
|
||||
DESTDIR = $$IFW_APP_PATH
|
||||
|
||||
HEADERS += operationrunner.h \
|
||||
binaryreplace.h \
|
||||
binarydump.h
|
||||
|
||||
SOURCES += main.cpp \
|
||||
operationrunner.cpp \
|
||||
binaryreplace.cpp \
|
||||
binarydump.cpp
|
||||
|
||||
osx:include(../../no_app_bundle.pri)
|
212
tools/devtool/main.cpp
Normal file
212
tools/devtool/main.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "binarydump.h"
|
||||
#include "binaryreplace.h"
|
||||
#include "operationrunner.h"
|
||||
|
||||
#include <binaryformat.h>
|
||||
#include <binaryformatenginehandler.h>
|
||||
#include <errors.h>
|
||||
#include <fileio.h>
|
||||
#include <fileutils.h>
|
||||
#include <init.h>
|
||||
#include <kdupdaterupdateoperationfactory.h>
|
||||
#include <utils.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QFileInfo>
|
||||
#include <QResource>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace QInstallerCreator;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setApplicationVersion(QLatin1String("1.0.0"));
|
||||
|
||||
QCommandLineOption verbose(QLatin1String("verbose"),
|
||||
QLatin1String("Verbose mode. Prints out more information."));
|
||||
QCommandLineOption dump(QLatin1String("dump"),
|
||||
QLatin1String("Dumps the binary content attached to an installer into target."),
|
||||
QLatin1String("folder"));
|
||||
QCommandLineOption run(QLatin1String("operation"),
|
||||
QLatin1String("Executes an operation with a list of arguments. Mode can be DO or UNDO."),
|
||||
QLatin1String("mode,name,args,..."));
|
||||
QCommandLineOption update(QLatin1String("update"),
|
||||
QLatin1String("Updates existing installer or maintenance tool with a new installer base."),
|
||||
QLatin1String("file"));
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addVersionOption();
|
||||
parser.addOption(verbose);
|
||||
parser.addOption(update);
|
||||
parser.addOption(dump);
|
||||
parser.addOption(run);
|
||||
parser.addPositionalArgument(QLatin1String("binary"), QLatin1String("Existing installer or "
|
||||
"maintenance tool."));
|
||||
|
||||
parser.process(app.arguments());
|
||||
const QStringList arguments = parser.positionalArguments();
|
||||
if (arguments.isEmpty() || (arguments.count() > 1))
|
||||
parser.showHelp(EXIT_FAILURE);
|
||||
|
||||
QInstaller::init();
|
||||
QInstaller::setVerbose(parser.isSet(verbose));
|
||||
|
||||
QString bundlePath;
|
||||
QString path = QFileInfo(arguments.first()).absoluteFilePath();
|
||||
if (QInstaller::isInBundle(path, &bundlePath))
|
||||
path = QDir(bundlePath).filePath(QLatin1String("Contents/Resources/installer.dat"));
|
||||
|
||||
int result = EXIT_FAILURE;
|
||||
QVector<QByteArray> resourceMappings;
|
||||
try {
|
||||
QFile *file = new QFile(path);
|
||||
QInstaller::openForRead(file);
|
||||
qint64 pos = QInstaller::findMagicCookie(file, QInstaller::MagicCookie);
|
||||
QInstaller::BinaryLayout layout = QInstaller::BinaryContent::readBinaryLayout(file, pos);
|
||||
|
||||
if (layout.magicMarker == QInstaller::MagicUninstallerMarker) {
|
||||
QFileInfo fi(path);
|
||||
if (QInstaller::isInBundle(fi.absoluteFilePath(), &bundlePath))
|
||||
fi.setFile(bundlePath);
|
||||
path = fi.absolutePath() + QLatin1Char('/') + fi.baseName() + QLatin1String(".dat");
|
||||
|
||||
file->setFileName(path);
|
||||
pos = QInstaller::findMagicCookie(file, QInstaller::MagicCookie);
|
||||
layout = QInstaller::BinaryContent::readBinaryLayout(file, pos);
|
||||
}
|
||||
|
||||
if (parser.isSet(update)) {
|
||||
// To update the binary we do not need any mapping.
|
||||
BinaryReplace br(layout);
|
||||
return br.replace(parser.value(update), path);
|
||||
}
|
||||
|
||||
// map the inbuilt resources
|
||||
foreach (const Range<qint64> &segment, layout.metadataResourceSegments) {
|
||||
if (segment.length() <= 0)
|
||||
continue;
|
||||
if (!file->seek(segment.start()))
|
||||
throw QInstaller::Error(QLatin1String("Could not seek to segment position."));
|
||||
const QByteArray ba = QInstaller::retrieveData(file, segment.length());
|
||||
if (!QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata")))
|
||||
throw QInstaller::Error(QLatin1String("Could not register in-binary resource."));
|
||||
resourceMappings.append(ba);
|
||||
}
|
||||
|
||||
// instantiate the operations we support
|
||||
const qint64 dataBlockStart = layout.endOfData - layout.dataBlockSize;
|
||||
const qint64 operationsStart = layout.operationsStart + dataBlockStart;
|
||||
if (!file->seek(operationsStart))
|
||||
throw QInstaller::Error(QLatin1String("Could not seek to operation list."));
|
||||
|
||||
QList<QInstaller::Operation *> performedOperations;
|
||||
const qint64 operationsCount = QInstaller::retrieveInt64(file);
|
||||
for (int i = 0; i < operationsCount; ++i) {
|
||||
const QString name = QInstaller::retrieveString(file);
|
||||
const QString data = QInstaller::retrieveString(file);
|
||||
|
||||
QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance()
|
||||
.create(name));
|
||||
if (op.isNull()) {
|
||||
throw QInstaller::Error(QString::fromLatin1("Could not load unknown operation %1")
|
||||
.arg(name));
|
||||
}
|
||||
if (!op->fromXml(data)) {
|
||||
throw QInstaller::Error(QString::fromLatin1("Could not load XML for operation: %1")
|
||||
.arg(name));
|
||||
}
|
||||
performedOperations.append(op.take());
|
||||
}
|
||||
|
||||
// seek to the position of the component index
|
||||
const qint64 resourceOffsetAndLengtSize = 2 * sizeof(qint64);
|
||||
const qint64 resourceSectionSize = resourceOffsetAndLengtSize * layout.resourceCount;
|
||||
const qint64 offset = layout.endOfData - layout.indexSize - resourceSectionSize
|
||||
- resourceOffsetAndLengtSize;
|
||||
if (!file->seek(offset))
|
||||
throw QInstaller::Error(QLatin1String("Could not seek to read component index info."));
|
||||
|
||||
const qint64 compIndexStart = QInstaller::retrieveInt64(file) + dataBlockStart;
|
||||
if (!file->seek(compIndexStart))
|
||||
throw QInstaller::Error(QLatin1String("Could not seek to start of component index."));
|
||||
|
||||
// setup the component index
|
||||
QSharedPointer<QFile> data(file);
|
||||
ComponentIndex index = ComponentIndex::read(data, dataBlockStart);
|
||||
|
||||
if (parser.isSet(dump)) {
|
||||
// To dump the content we do not need the binary format engine.
|
||||
if (layout.magicMarker != QInstaller::MagicInstallerMarker)
|
||||
throw QInstaller::Error(QLatin1String("Source file is not an installer."));
|
||||
BinaryDump bd;
|
||||
return bd.dump(index, parser.value(dump));
|
||||
}
|
||||
|
||||
// setup the binary format engine
|
||||
QScopedPointer<BinaryFormatEngineHandler> binaryFormatEngineHandler;
|
||||
binaryFormatEngineHandler.reset(new BinaryFormatEngineHandler(index));
|
||||
|
||||
if (parser.isSet(run)) {
|
||||
OperationRunner runner(layout.magicMarker, performedOperations);
|
||||
const QStringList arguments = parser.values(run);
|
||||
if (arguments.first() == QLatin1String("DO"))
|
||||
result = runner.runOperation(arguments.mid(1), OperationRunner::RunMode::Do);
|
||||
else if (arguments.first() == QLatin1String("UNDO"))
|
||||
result = runner.runOperation(arguments.mid(1), OperationRunner::RunMode::Undo);
|
||||
}
|
||||
} catch (const QInstaller::Error &error) {
|
||||
std::cerr << qPrintable(error.message()) << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << "Unknown exception caught." << std::endl;
|
||||
}
|
||||
|
||||
// unmap resources
|
||||
foreach (const QByteArray &rccData, resourceMappings)
|
||||
QResource::unregisterResource((const uchar*) rccData.data(), QLatin1String(":/metadata"));
|
||||
|
||||
return result;
|
||||
}
|
108
tools/devtool/operationrunner.cpp
Normal file
108
tools/devtool/operationrunner.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012-2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "operationrunner.h"
|
||||
|
||||
#include <errors.h>
|
||||
#include <kdupdaterupdateoperationfactory.h>
|
||||
#include <packagemanagercore.h>
|
||||
|
||||
#include <QMetaObject>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
OperationRunner::OperationRunner(qint64 magicMarker, const QInstaller::OperationList &oldOperations)
|
||||
: m_core(new QInstaller::PackageManagerCore(magicMarker, oldOperations))
|
||||
{
|
||||
// We need a package manager core as some operations expect them to be available.
|
||||
}
|
||||
|
||||
OperationRunner::~OperationRunner()
|
||||
{
|
||||
delete m_core;
|
||||
}
|
||||
|
||||
int OperationRunner::runOperation(QStringList arguments, RunMode mode)
|
||||
{
|
||||
int result = EXIT_FAILURE;
|
||||
try {
|
||||
const QString name = arguments.takeFirst();
|
||||
QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance()
|
||||
.create(name));
|
||||
if (!op) {
|
||||
std::cerr << "Cannot instantiate operation: " << qPrintable(name) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (QObject *const object = dynamic_cast<QObject*> (op.data())) {
|
||||
const QMetaObject *const mo = object->metaObject();
|
||||
if (mo->indexOfSignal(mo->normalizedSignature("outputTextChanged(QString)")) > -1)
|
||||
connect(object, SIGNAL(outputTextChanged(QString)), this, SLOT(print(QString)));
|
||||
}
|
||||
op->setArguments(arguments);
|
||||
op->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
|
||||
|
||||
|
||||
bool readyPerformed = false;
|
||||
if (mode == RunMode::Do)
|
||||
readyPerformed = op->performOperation();
|
||||
if (mode == RunMode::Undo)
|
||||
readyPerformed = op->undoOperation();
|
||||
|
||||
if (readyPerformed) {
|
||||
result = EXIT_SUCCESS;
|
||||
std::cout << "Operation finished successfully." << std::endl;
|
||||
} else {
|
||||
std::cerr << "An error occurred while performing the operation: "
|
||||
<< qPrintable(op->errorString()) << std::endl;
|
||||
}
|
||||
} catch (const QInstaller::Error &e) {
|
||||
std::cerr << qPrintable(e.message()) << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << "Unknown exception caught." << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void OperationRunner::print(const QString &value)
|
||||
{
|
||||
std::cout << qPrintable(value) << std::endl;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012-2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2012-2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
@ -42,33 +42,34 @@
|
||||
#ifndef OPERATIONRUNNER_H
|
||||
#define OPERATIONRUNNER_H
|
||||
|
||||
#include "binaryformat.h"
|
||||
#include "installer_global.h"
|
||||
#include <qinstallerglobal.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QStringList)
|
||||
#include <QObject>
|
||||
|
||||
namespace QInstaller {
|
||||
class PackageManagerCore;
|
||||
}
|
||||
|
||||
class PackageManagerCore;
|
||||
|
||||
class INSTALLER_EXPORT OperationRunner
|
||||
class OperationRunner : public QObject
|
||||
{
|
||||
public:
|
||||
OperationRunner();
|
||||
explicit OperationRunner(const QString &path);
|
||||
~OperationRunner();
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(OperationRunner)
|
||||
|
||||
bool init();
|
||||
void setVerbose(bool verbose);
|
||||
int runOperation(const QStringList &arguments);
|
||||
public:
|
||||
enum struct RunMode {
|
||||
Do,
|
||||
Undo
|
||||
};
|
||||
|
||||
OperationRunner(qint64 magicMarker, const QInstaller::OperationList &oldOperations);
|
||||
~OperationRunner();
|
||||
int runOperation(QStringList arguments, RunMode mode);
|
||||
|
||||
private slots:
|
||||
void print(const QString &value);
|
||||
|
||||
private:
|
||||
PackageManagerCore *m_core;
|
||||
|
||||
QString m_path;
|
||||
BinaryContent m_bc;
|
||||
QInstaller::PackageManagerCore *m_core;
|
||||
};
|
||||
|
||||
} // namespace QInstaller
|
||||
|
||||
#endif
|
||||
#endif // OPERATIONRUNNER_H
|
@ -4,7 +4,8 @@ TEMPLATE = subdirs
|
||||
SUBDIRS += \
|
||||
archivegen \
|
||||
binarycreator \
|
||||
repogen
|
||||
repogen \
|
||||
devtool
|
||||
|
||||
EXTRASUBDIRS = \
|
||||
repocompare \
|
||||
|
Loading…
x
Reference in New Issue
Block a user