summaryrefslogtreecommitdiffstats
path: root/tools/devtool
diff options
context:
space:
mode:
Diffstat (limited to 'tools/devtool')
-rw-r--r--tools/devtool/binarydump.cpp20
-rw-r--r--tools/devtool/binaryreplace.cpp24
-rw-r--r--tools/devtool/main.cpp149
-rw-r--r--tools/devtool/operationrunner.cpp6
4 files changed, 141 insertions, 58 deletions
diff --git a/tools/devtool/binarydump.cpp b/tools/devtool/binarydump.cpp
index 4a6094e66..26e8260dd 100644
--- a/tools/devtool/binarydump.cpp
+++ b/tools/devtool/binarydump.cpp
@@ -47,19 +47,19 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
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;
+ std::cerr << qPrintable(QString::fromLatin1("Target directory \"%1\" already exists and "
+ "is not empty.").arg(QDir::toNativeSeparators(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;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot create \"%1\".").arg(
+ QDir::toNativeSeparators(targetDir.path()))) << std::endl;
return EXIT_FAILURE;
}
}
- QInstaller::CopyDirectoryOperation copyMetadata;
+ QInstaller::CopyDirectoryOperation copyMetadata(0);
copyMetadata.setArguments(QStringList() << QLatin1String(":/")
<< (targetDir.path() + QLatin1Char('/'))); // Add "/" at the end to make operation work.
if (!copyMetadata.performOperation()) {
@@ -68,8 +68,8 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
}
if (!targetDir.cd(QLatin1String("metadata"))) {
- std::cerr << qPrintable(QString::fromLatin1("Could not switch to '%1/metadata'.")
- .arg(targetDir.path())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot switch to \"%1/metadata\".")
+ .arg(QDir::toNativeSeparators(targetDir.path()))) << std::endl;
return EXIT_FAILURE;
}
@@ -81,8 +81,8 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
QString error;
QDomDocument doc;
if (!doc.setContent(&updatesXml, &error)) {
- throw QInstaller::Error(QString::fromLatin1("Could not read: '%1'. %2").arg(updatesXml
- .fileName(), error));
+ throw QInstaller::Error(QString::fromLatin1("Cannot read: \"%1\": %2").arg(
+ QDir::toNativeSeparators(updatesXml.fileName()), error));
}
QHash<QString, QString> versionMap;
@@ -113,7 +113,7 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
continue;
if (!targetDir.mkpath(name)) {
- throw QInstaller::Error(QString::fromLatin1("Could not create target dir: %1.")
+ throw QInstaller::Error(QString::fromLatin1("Cannot create target dir: %1.")
.arg(targetDir.filePath(name)));
}
diff --git a/tools/devtool/binaryreplace.cpp b/tools/devtool/binaryreplace.cpp
index 65f124a7a..910526b6a 100644
--- a/tools/devtool/binaryreplace.cpp
+++ b/tools/devtool/binaryreplace.cpp
@@ -39,7 +39,9 @@
#include <errors.h>
#include <fileio.h>
#include <fileutils.h>
+#include <lib7z_extract.h>
#include <lib7z_facade.h>
+#include <lib7z_list.h>
#include <QDir>
#include <QFutureWatcher>
@@ -81,19 +83,19 @@ int BinaryReplace::replace(const QString &source, const QString &target)
.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;
+ std::cerr << qPrintable(QString::fromLatin1("Error while extracting \"%1\": %2")
+ .arg(QDir::toNativeSeparators(newInstallerBasePath), e.message())) << std::endl;
} catch (...) {
std::cerr << qPrintable(QString::fromLatin1("Unknown exception caught while "
- "extracting '%1'.").arg(newInstallerBasePath)) << std::endl;
+ "extracting \"%1\".").arg(QDir::toNativeSeparators(newInstallerBasePath))) << std::endl;
}
} else {
- std::cerr << qPrintable(QString::fromLatin1("Could not open '%1' for reading: %2.")
- .arg(newInstallerBasePath, archive.errorString())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot open \"%1\" for reading: %2")
+ .arg(QDir::toNativeSeparators(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;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot delete file \"%1\": %2")
+ .arg(QDir::toNativeSeparators(newInstallerBasePath), archive.errorString())) << std::endl;
}
if (result != EXIT_SUCCESS)
return result;
@@ -130,19 +132,19 @@ int BinaryReplace::replace(const QString &source, const QString &target)
#endif
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;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot delete \"%1\": %2")
+ .arg(QDir::toNativeSeparators(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")
+ std::cerr << qPrintable(QString::fromLatin1("Cannot 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")
+ std::cerr << qPrintable(QString::fromLatin1("Cannot copy \"%1\" to \"%2\": %3")
.arg(installerBaseNew.fileName(), oldBasePath, installerBaseNew.errorString()))
<< std::endl;
} else {
diff --git a/tools/devtool/main.cpp b/tools/devtool/main.cpp
index df9b8bbc7..c9aaab71c 100644
--- a/tools/devtool/main.cpp
+++ b/tools/devtool/main.cpp
@@ -36,7 +36,6 @@
#include "operationrunner.h"
#include <binarycontent.h>
-#include <binaryformat.h>
#include <binaryformatenginehandler.h>
#include <errors.h>
#include <fileio.h>
@@ -49,39 +48,122 @@
#include <QFileInfo>
#include <QResource>
+#include <iomanip>
#include <iostream>
+struct Command
+{
+ const char* command;
+ const char* description;
+ qint32 argC;
+ const char* arguments;
+ const char* argDescription;
+} Commands[] = {
+ { "dump", "Dumps the binary content that belongs to an installer or maintenance tool into "
+ "target directory.", 2, "<binary> <targetdirecory>", "The <binary> containing the data to "
+ "dump.\nThe <targetdirectory> to dump the data in."
+ },
+
+ { "update", "Updates existing installer or maintenance tool with a new installer base.", 2,
+ "<binary> <installerbase>", "The <binary> to update.\nThe <installerbase> to use as update."
+ },
+
+ { "operation", "Executes an operation with with a given mode and a list of arguments. ", 2,
+ "<binary> <mode,name,args,...>", "The <binary> to run the operation with.\n"
+ "<mode,name,args,...> 'mode' can be DO or UNDO. 'name' of the operation. 'args,...' "
+ "used to run the operation."
+ }
+};
+
+#define DESCRITION_LENGTH 60
+#define SETW_ALIGNLEFT(X) std::setw(X) << std::setiosflags(std::ios::left)
+
+static int fail(const QString &message)
+{
+ std::cerr << qPrintable(message) << " See 'devtool --help'." << std::endl;
+ return EXIT_FAILURE;
+}
+
+static QStringList split(int index, const QString &description)
+{
+ QStringList result;
+ if (description.length() <= DESCRITION_LENGTH)
+ return result << description;
+
+ const int lastIndexOf = description.left(index + DESCRITION_LENGTH)
+ .lastIndexOf(QLatin1Char(' '));
+ result << description.left(lastIndexOf);
+ return result + split(lastIndexOf + 1, description.mid(lastIndexOf + 1));
+}
+
+// -- main
+
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 that belongs to an installer or maintenance tool "
- "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.addHelpOption();
- parser.addVersionOption();
+ QCommandLineOption help = parser.addHelpOption();
+ QCommandLineOption version = parser.addVersionOption();
+ QCommandLineOption verbose(QLatin1String("verbose"), QLatin1String("Verbose mode. Prints out "
+ "more information."));
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);
+ parser.parse(app.arguments());
+ if (parser.isSet(version)) {
+ parser.showVersion();
+ return EXIT_SUCCESS;
+ }
+
+ if (parser.isSet(help)) {
+ const QString command = parser.positionalArguments().value(0);
+ if (!command.isEmpty()) {
+ for (const auto &c : Commands) {
+ if (QLatin1String(c.command) == command) {
+ parser.clearPositionalArguments();
+ parser.addPositionalArgument(QString::fromLatin1("%1 %2").arg(QLatin1String(c
+ .command), QLatin1String(c.arguments)), QLatin1String(c.argDescription));
+ parser.showHelp(EXIT_SUCCESS);
+ }
+ }
+ return fail(QString::fromLatin1("\"%1\" is not a devtool command.").arg(command));
+ }
+
+ QString helpText = parser.helpText();
+ helpText.insert(helpText.indexOf(QLatin1Char(']')) + 1, QLatin1String(" command <args>"));
+ std::cout << qPrintable(helpText) << std::endl;
+ std::cout << "Available commands (mutually exclusive):" << std::endl;
+ for (const auto &c : Commands) {
+ QStringList lines = split(0, QLatin1String(c.description));
+ std::cout << SETW_ALIGNLEFT(2) << " " << SETW_ALIGNLEFT(16) << c.command
+ << SETW_ALIGNLEFT(DESCRITION_LENGTH) << qPrintable(lines.takeFirst()) << std::endl;
+ foreach (const QString &line, lines) {
+ std::cout << SETW_ALIGNLEFT(18) << QByteArray(18, ' ').constData()
+ << qPrintable(line) << std::endl;
+ }
+ }
+ std::cout << std::endl << "Use 'devtool --help <command>' to read about a specific command."
+ << std::endl;
+ return EXIT_SUCCESS;
+ }
+
+ QStringList arguments = parser.positionalArguments();
+ if (arguments.isEmpty())
+ return fail(QLatin1String("Missing command."));
+
+ bool found = false;
+ const QString command = arguments.takeFirst();
+ for (const auto &c : Commands) {
+ if ((found = (QLatin1String(c.command) == command))) {
+ if (arguments.count() != c.argC)
+ return fail(QString::fromLatin1("%1: wrong argument count.").arg(command));
+ break;
+ }
+ }
+
+ if (!found)
+ return fail(QString::fromLatin1("\"%1\" is not a devtool command.").arg(command));
QInstaller::init();
QInstaller::setVerbose(parser.isSet(verbose));
@@ -100,7 +182,7 @@ int main(int argc, char *argv[])
QInstaller::openForRead(&tmp);
if (!tmp.seek(QInstaller::BinaryContent::findMagicCookie(&tmp, cookie) - sizeof(qint64)))
- throw QInstaller::Error(QLatin1String("Could not seek to read magic marker."));
+ throw QInstaller::Error(QLatin1String("Cannot seek to read magic marker."));
QInstaller::BinaryLayout layout;
layout.magicMarker = QInstaller::retrieveInt64(&tmp);
@@ -120,9 +202,9 @@ int main(int argc, char *argv[])
layout = QInstaller::BinaryContent::binaryLayout(&tmp, cookie);
tmp.close();
- if (parser.isSet(update)) {
+ if (command == QLatin1String("update")) {
BinaryReplace br(layout); // To update the binary we do not need any mapping.
- return br.replace(parser.value(update), QFileInfo(arguments.first())
+ return br.replace(arguments.last(), QFileInfo(arguments.first())
.absoluteFilePath());
}
}
@@ -145,28 +227,29 @@ int main(int argc, char *argv[])
const QByteArray ba = resource->readAll();
if (!QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata")))
- throw QInstaller::Error(QLatin1String("Could not register in-binary resource."));
+ throw QInstaller::Error(QLatin1String("Cannot register in-binary resource."));
resourceMappings.append(ba);
if (!isOpen)
resource->close();
}
- if (parser.isSet(dump)) {
+ if (command == QLatin1String("dump")) {
// To dump the content we do not need the binary format engine.
BinaryDump bd;
- result = bd.dump(manager, parser.value(dump));
- } else if (parser.isSet(run)) {
+ result = bd.dump(manager, arguments.last());
+ } else if (command == QLatin1String("operation")) {
QInstaller::BinaryFormatEngineHandler::instance()->registerResources(manager
.collections()); // setup the binary format engine
OperationRunner runner(magicMarker, operations);
- const QStringList arguments = parser.value(run).split(QLatin1Char(','));
+ const QStringList arguments = arguments.last().split(QLatin1Char(','));
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);
else
- std::cerr << "Malformed argument: " << qPrintable(parser.value(run)) << std::endl;
+ std::cerr << "Malformed argument: " << qPrintable(arguments.last()) << std::endl;
+
}
} catch (const QInstaller::Error &error) {
std::cerr << qPrintable(error.message()) << std::endl;
diff --git a/tools/devtool/operationrunner.cpp b/tools/devtool/operationrunner.cpp
index 97bdfd7d7..41cc9d41b 100644
--- a/tools/devtool/operationrunner.cpp
+++ b/tools/devtool/operationrunner.cpp
@@ -34,7 +34,7 @@
#include "operationrunner.h"
#include <errors.h>
-#include <kdupdaterupdateoperationfactory.h>
+#include <updateoperationfactory.h>
#include <packagemanagercore.h>
#include <QMetaObject>
@@ -59,7 +59,7 @@ int OperationRunner::runOperation(QStringList arguments, RunMode mode)
try {
const QString name = arguments.takeFirst();
QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance()
- .create(name));
+ .create(name, m_core));
if (!op) {
std::cerr << "Cannot instantiate operation: " << qPrintable(name) << std::endl;
return EXIT_FAILURE;
@@ -71,8 +71,6 @@ int OperationRunner::runOperation(QStringList arguments, RunMode mode)
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)