summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/archivegen/archivegen.pro2
-rw-r--r--tools/binarycreator/binarycreator.cpp250
-rw-r--r--tools/binarycreator/binarycreator.pro2
-rw-r--r--tools/common/repositorygen.cpp448
-rw-r--r--tools/common/repositorygen.h20
-rw-r--r--tools/extractbinarydata/extractbinarydata.pro3
-rw-r--r--tools/getrepositorycontent/domnodedebugstreamoperator.cpp53
-rw-r--r--tools/getrepositorycontent/domnodedebugstreamoperator.h51
-rw-r--r--tools/getrepositorycontent/downloader.cpp118
-rw-r--r--tools/getrepositorycontent/downloader.h (renamed from tools/repogenfromonlinerepo/downloadmanager.h)42
-rw-r--r--tools/getrepositorycontent/getrepositorycontent.pro23
-rw-r--r--tools/getrepositorycontent/main.cpp450
-rw-r--r--tools/getrepositorycontent/textprogressbar.cpp (renamed from tools/repogenfromonlinerepo/textprogressbar.cpp)0
-rw-r--r--tools/getrepositorycontent/textprogressbar.h (renamed from tools/repogenfromonlinerepo/textprogressbar.h)0
-rw-r--r--tools/repocompare/repocompare.pro3
-rw-r--r--tools/repogen/repogen.cpp126
-rw-r--r--tools/repogen/repogen.pro2
-rw-r--r--tools/repogenfromonlinerepo/downloadmanager.cpp171
-rw-r--r--tools/repogenfromonlinerepo/main.cpp332
-rw-r--r--tools/repogenfromonlinerepo/repogenfromonlinerepo.pro19
-rw-r--r--tools/tools.pro2
21 files changed, 1154 insertions, 963 deletions
diff --git a/tools/archivegen/archivegen.pro b/tools/archivegen/archivegen.pro
index f6a40da4f..51bccb11b 100644
--- a/tools/archivegen/archivegen.pro
+++ b/tools/archivegen/archivegen.pro
@@ -13,3 +13,5 @@ DESTDIR = $$IFW_APP_PATH
SOURCES += archive.cpp \
../common/repositorygen.cpp
HEADERS += ../common/repositorygen.h
+
+macx:include(../../no_app_bundle.pri)
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp
index 594686e61..8589192bb 100644
--- a/tools/binarycreator/binarycreator.cpp
+++ b/tools/binarycreator/binarycreator.cpp
@@ -46,6 +46,7 @@
#include <errors.h>
#include <fileutils.h>
#include <init.h>
+#include <repository.h>
#include <settings.h>
#include <utils.h>
@@ -113,15 +114,8 @@ static void chmod755(const QString &absolutFilePath)
}
#endif
-static int assemble(Input input, const QString &configFile)
+static int assemble(Input input, const QInstaller::Settings &settings)
{
- const QString configDir = QFileInfo(configFile).canonicalPath();
- const QInstaller::Settings &settings = QInstaller::Settings::fromFileAndPrefix(configFile, configDir);
-
-#ifdef Q_OS_LINUX
-Q_UNUSED(settings)
-#endif
-
#ifdef Q_OS_MAC
if (QFileInfo(input.installerExePath).isBundle()) {
const QString bundle = input.installerExePath;
@@ -144,8 +138,11 @@ Q_UNUSED(settings)
if (isBundle) {
// output should be a bundle
const QFileInfo fi(input.outputPath);
+
+ const QString contentsResourcesPath = fi.filePath() + QLatin1String("/Contents/Resources/");
+
QInstaller::mkpath(fi.filePath() + QLatin1String("/Contents/MacOS"));
- QInstaller::mkpath(fi.filePath() + QLatin1String("/Contents/Resources"));
+ QInstaller::mkpath(contentsResourcesPath);
{
QFile pkgInfo(fi.filePath() + QLatin1String("/Contents/PkgInfo"));
@@ -154,10 +151,20 @@ Q_UNUSED(settings)
pkgInfoStream << QLatin1String("APPL????") << endl;
}
- const QString iconFile = QFile::exists(settings.icon()) ? settings.icon()
- : QString::fromLatin1(":/resources/default_icon_mac.icns");
+ QString iconFile;
+ if (QFile::exists(settings.installerApplicationIcon())) {
+ iconFile = settings.installerApplicationIcon();
+ } else {
+ iconFile = QFile::exists(settings.icon()) ? settings.icon()
+ : QString::fromLatin1(":/resources/default_icon_mac.icns");
+ }
+
const QString iconTargetFile = fi.completeBaseName() + QLatin1String(".icns");
- QFile::copy(iconFile, fi.filePath() + QLatin1String("/Contents/Resources/") + iconTargetFile);
+ QFile::copy(iconFile, contentsResourcesPath + iconTargetFile);
+ if (QDir(qApp->applicationDirPath() + QLatin1String("/qt_menu.nib")).exists()) {
+ copyDirectoryContents(qApp->applicationDirPath() + QLatin1String("/qt_menu.nib"),
+ contentsResourcesPath + QLatin1String("/qt_menu.nib"));
+ }
QFile infoPList(fi.filePath() + QLatin1String("/Contents/Info.plist"));
infoPList.open(QIODevice::WriteOnly);
@@ -175,7 +182,10 @@ Q_UNUSED(settings)
plistStream << QLatin1String(" <key>CFBundleGetInfoString</key>") << endl;
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
- plistStream << QLatin1String(" <string>") << QLatin1String(QUOTE(IFW_VERSION)) << ("</string>") << endl;
+ plistStream << QLatin1String(" <string>") << QLatin1String(QUOTE(IFW_VERSION)) << ("</string>")
+ << endl;
+#undef QUOTE
+#undef QUOTE_
plistStream << QLatin1String(" <key>CFBundleSignature</key>") << endl;
plistStream << QLatin1String(" <string> ???? </string>") << endl;
plistStream << QLatin1String(" <key>CFBundleExecutable</key>") << endl;
@@ -184,14 +194,18 @@ Q_UNUSED(settings)
plistStream << QLatin1String(" <key>CFBundleIdentifier</key>") << endl;
plistStream << QLatin1String(" <string>com.yourcompany.installerbase</string>") << endl;
plistStream << QLatin1String(" <key>NOTE</key>") << endl;
- plistStream << QLatin1String(" <string>This file was generated by Qt/QMake.</string>")
+ plistStream << QLatin1String(" <string>This file was generated by Qt Installer Framework.</string>")
<< endl;
+ plistStream << QLatin1String(" <key>NSPrincipalClass</key>") << endl;
+ plistStream << QLatin1String(" <string>NSApplication</string>") << endl;
plistStream << QLatin1String("</dict>") << endl;
plistStream << QLatin1String("</plist>") << endl;
input.outputPath = QString::fromLatin1("%1/Contents/MacOS/%2").arg(input.outputPath)
.arg(fi.completeBaseName());
}
+#elif defined(Q_OS_LINUX)
+ Q_UNUSED(settings)
#endif
QTemporaryFile file(input.outputPath);
@@ -218,9 +232,13 @@ Q_UNUSED(settings)
#if defined(Q_OS_WIN)
// setting the windows icon must happen before we append our binary data - otherwise they get lost :-/
- if (QFile::exists(settings.icon())) {
+ if (QFile::exists(settings.installerApplicationIcon())) {
// no error handling as this is not fatal
- setApplicationIcon(tempFile, settings.icon());
+ setApplicationIcon(tempFile, settings.installerApplicationIcon());
+ } else {
+ if (QFile::exists(settings.icon())) {
+ setApplicationIcon(tempFile, settings.icon());
+ }
}
#elif defined(Q_OS_MAC)
if (isBundle) {
@@ -311,14 +329,14 @@ Q_UNUSED(settings)
} catch (const Error &e) {
qCritical("Error occurred while assembling the installer: %s", qPrintable(e.message()));
QFile::remove(tempFile);
- return 1;
+ return EXIT_FAILURE;
}
if (!out.commit(KDSaveFile::OverwriteExistingFile)) {
qCritical("Could not write installer to %s: %s", qPrintable(out.fileName()),
qPrintable(out.errorString()));
QFile::remove(tempFile);
- return 1;
+ return EXIT_FAILURE;
}
#ifndef Q_OS_WIN
chmod755(out.fileName());
@@ -342,7 +360,7 @@ Q_UNUSED(settings)
qDebug() << "done." << mkdmgscript;
}
#endif
- return 0;
+ return EXIT_SUCCESS;
}
QT_BEGIN_NAMESPACE
@@ -384,7 +402,7 @@ private:
const QString oldPath;
};
-static QString createBinaryResourceFile(const QString &directory)
+static QString createBinaryResourceFile(const QString &directory, const QString &binaryName)
{
QTemporaryFile projectFile(directory + QLatin1String("/rccprojectXXXXXX.qrc"));
if (!projectFile.open())
@@ -392,16 +410,19 @@ static QString createBinaryResourceFile(const QString &directory)
projectFile.close();
const WorkingDirectoryChange wd(directory);
- const QString binaryName = generateTemporaryFileName();
const QString projectFileName = QFileInfo(projectFile.fileName()).absoluteFilePath();
// 1. create the .qrc file
- runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project")
- << QLatin1String("-o") << projectFileName);
+ if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project") << QLatin1String("-o")
+ << projectFileName) != EXIT_SUCCESS) {
+ throw Error(QString::fromLatin1("Could not create rcc project file."));
+ }
// 2. create the binary resource file from the .qrc file
- runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary")
- << QLatin1String("-o") << binaryName << projectFileName);
+ if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary") << QLatin1String("-o")
+ << binaryName << projectFileName) != EXIT_SUCCESS) {
+ throw Error(QString::fromLatin1("Could not compile rcc project file."));
+ }
return binaryName;
}
@@ -451,6 +472,9 @@ static void printUsage()
std::cout << " -r|--resources r1,.,rn include the given resource files into the binary" << std::endl;
std::cout << " -v|--verbose Verbose output" << std::endl;
+ std::cout << " -rcc|--compile-resource Compiles the default resource and outputs the result into"
+ << std::endl;
+ std::cout << " 'update.rcc' in the current path." << std::endl;
std::cout << std::endl;
std::cout << "Packages are to be found in the current working directory and get listed as "
"their names" << std::endl << std::endl;
@@ -462,97 +486,77 @@ static void printUsage()
std::cout << std::endl;
std::cout << "Example (online installer):" << std::endl;
std::cout << " " << appName << " -c installer-config" << sep << "config.xml -p packages-directory "
- "-e com.nokia.sdk.qt,com.nokia.qtcreator -t installerbase" << suffix << " SDKInstaller"
+ "-e org.qt-project.sdk.qt,org.qt-project.qtcreator -t installerbase" << suffix << " SDKInstaller"
<< suffix << std::endl;
std::cout << std::endl;
std::cout << "Creates an installer for the SDK without qt and qt creator." << std::endl;
std::cout << std::endl;
+ std::cout << "Example update.rcc:" << std::endl;
+ std::cout << " " << appName << " -c installer-config" << sep << "config.xml -p packages-directory "
+ "-rcc" << std::endl;
}
-static QString createMetaDataDirectory(const QInstallerTools::PackageInfoVector &packages,
- const QString &packagesDir, const QString &configFile)
+void copyConfigData(const QString &configFile, const QString &targetDir)
{
- const QInstaller::Settings &settings = QInstaller::Settings::fromFileAndPrefix(configFile, QString());
+ qDebug() << "Begin to copy configuration file and data.";
+
+ const QString sourceConfigFile = QFileInfo(configFile).absoluteFilePath();
+ const QString targetConfigFile = targetDir + QLatin1String("/config.xml");
+ QInstallerTools::copyWithException(sourceConfigFile, targetConfigFile, QLatin1String("configuration"));
- const QString metapath = createTemporaryDirectory();
- generateMetaDataDirectory(metapath, packagesDir, packages, settings.applicationName(),
- settings.applicationVersion());
+ QFile configXml(targetConfigFile);
+ QInstaller::openForRead(&configXml, configXml.fileName());
- const QString configCopy = metapath + QLatin1String("/installer-config");
- QInstaller::mkdir(configCopy);
- QString absoluteConfigPath = QFileInfo(configFile).absolutePath();
+ QDomDocument dom;
+ dom.setContent(&configXml);
+ configXml.close();
- QDirIterator it(absoluteConfigPath, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
- while (it.hasNext()) {
- const QString next = it.next();
- if (next.contains(QLatin1String("/."))) // skip files that are in directories starting with a point
+ // iterate over all child elements, searching for relative file names
+ const QDomNodeList children = dom.documentElement().childNodes();
+ const QString sourceConfigFilePath = QFileInfo(sourceConfigFile).absolutePath();
+ for (int i = 0; i < children.count(); ++i) {
+ QDomElement domElement = children.at(i).toElement();
+ if (domElement.isNull())
continue;
- qDebug() << "\tFound configuration file: " << next;
- const QFileInfo sourceFileInfo(next);
- const QString source = sourceFileInfo.absoluteFilePath();
- QFileInfo targetFileInfo(configCopy, QFileInfo(next).fileName());
-
- if (QFileInfo(next).fileName() == QFileInfo(configFile).fileName())
- targetFileInfo.setFile(configCopy, QLatin1String("config.xml"));
-
- const QDir targetDir = targetFileInfo.dir();
- if (!targetDir.exists())
- QInstaller::mkpath(targetFileInfo.absolutePath());
- const QString target = targetFileInfo.absoluteFilePath();
-
- if (!QFile::copy(source, target))
- throw Error(QString::fromLatin1("Could not copy %1.").arg(source));
-
- if (sourceFileInfo.fileName() == QFileInfo(configFile).fileName()) {
- QFile configXml(targetDir.filePath(QLatin1String("config.xml")));
- configXml.open(QIODevice::ReadOnly);
- QDomDocument dom;
- dom.setContent(&configXml);
- configXml.close();
-
- // iterate over all child elements, searching for relative file names
- const QDomNodeList children = dom.documentElement().childNodes();
- for (int i = 0; i < children.count(); ++i) {
- QDomElement el = children.at(i).toElement();
- if (el.isNull())
- continue;
-
- QFileInfo fi(absoluteConfigPath, el.text());
+ const QString tagName = domElement.tagName();
+ const QString elementText = domElement.text();
+ qDebug() << QString::fromLatin1("Read dom element: <%1>%2</%1>.").arg(tagName, elementText);
+
+ QString newName = domElement.text().replace(QRegExp(QLatin1String("\\\\|/|\\.|:")),
+ QLatin1String("_"));
+
+ QString targetFile;
+ QFileInfo elementFileInfo;
+ if (tagName == QLatin1String("Icon") || tagName == QLatin1String("InstallerApplicationIcon")) {
#if defined(Q_OS_MAC)
- const QFileInfo fiIcon(absoluteConfigPath, el.text() + QLatin1String(".icns"));
+ const QString suffix = QLatin1String(".icns");
#elif defined(Q_OS_WIN)
- const QFileInfo fiIcon(absoluteConfigPath, el.text() + QLatin1String(".ico"));
+ const QString suffix = QLatin1String(".ico");
#else
- const QFileInfo fiIcon(absoluteConfigPath, el.text() + QLatin1String(".png"));
+ const QString suffix = QLatin1String(".png");
#endif
- if (!fi.exists() && fiIcon.exists())
- fi = fiIcon;
-
- if (!fi.exists() || fi.absolutePath() == QFileInfo(configFile).dir().absolutePath())
- continue;
-
- if (fi.isDir())
- continue;
+ elementFileInfo = QFileInfo(sourceConfigFilePath, elementText + suffix);
+ targetFile = targetDir + QLatin1Char('/') + newName + suffix;
+ } else {
+ elementFileInfo = QFileInfo(sourceConfigFilePath, elementText);
+ const QString suffix = elementFileInfo.completeSuffix();
+ if (!suffix.isEmpty())
+ newName.append(QLatin1Char('.') + suffix);
+ targetFile = targetDir + QLatin1Char('/') + newName;
+ }
+ if (!elementFileInfo.exists() || elementFileInfo.isDir())
+ continue;
- const QString newName = el.text().replace(QRegExp(QLatin1String("\\\\|/|\\.")),
- QLatin1String("_"));
+ domElement.replaceChild(dom.createTextNode(newName), domElement.firstChild());
+ QInstallerTools::copyWithException(elementFileInfo.absoluteFilePath(), targetFile, tagName);
+ }
- if (!QFile::exists(targetDir.absoluteFilePath(newName))) {
- if (!QFile::copy(fi.absoluteFilePath(), targetDir.absoluteFilePath(newName)))
- throw Error(QString::fromLatin1("Could not copy %1.").arg(el.text()));
- }
- el.removeChild(el.firstChild());
- el.appendChild(dom.createTextNode(newName));
- }
+ QInstaller::openForWrite(&configXml, configXml.fileName());
+ QTextStream stream(&configXml);
+ dom.save(stream, 4);
- openForWrite(&configXml, configXml.fileName());
- QTextStream stream(&configXml);
- dom.save(stream, 4);
- qDebug() << "\tdone.";
- }
- }
- return metapath;
+ qDebug() << "done.\n";
}
static int printErrorAndUsageAndExit(const QString &err)
@@ -585,6 +589,7 @@ int main(int argc, char **argv)
QStringList resources;
QStringList filteredPackages;
QInstallerTools::FilterType ftype = QInstallerTools::Exclude;
+ bool compileResource = false;
const QStringList args = app.arguments().mid(1);
for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) {
@@ -670,6 +675,8 @@ int main(int argc, char **argv)
} else if (*it == QLatin1String("--ignore-translations")
|| *it == QLatin1String("--ignore-invalid-packages")) {
continue;
+ } else if (*it == QLatin1String("-rcc") || *it == QLatin1String("--compile-resource")) {
+ compileResource = true;
} else {
if (it->startsWith(QLatin1String("-"))) {
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Unknown option \"%1\" used. Maybe you "
@@ -694,11 +701,11 @@ int main(int argc, char **argv)
}
if (onlineOnly) {
- filteredPackages.append(QLatin1String("XXXXXXXXXXXXXXXXX_online_XXXXXXXXXXXXXXXXX"));
+ filteredPackages.append(QLatin1String("X_fake_filter_component_for_online_only_installer_X"));
ftype = QInstallerTools::Include;
}
- if (target.isEmpty())
+ if (target.isEmpty() && !compileResource)
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Target parameter missing."));
if (configFile.isEmpty())
@@ -706,31 +713,37 @@ int main(int argc, char **argv)
qDebug() << "Parsed arguments, ok.";
+ int exitCode = EXIT_FAILURE;
+ const QString tmpMetaDir = QInstaller::createTemporaryDirectory();
try {
- QInstallerTools::PackageInfoVector packages = createListOfPackages(packagesDirectory,
- filteredPackages, ftype);
- const QString metaDir = createMetaDataDirectory(packages, packagesDirectory, configFile);
+ const Settings settings = Settings::fromFileAndPrefix(configFile, QFileInfo(configFile).absolutePath());
+ QInstallerTools::PackageInfoVector packages = QInstallerTools::createListOfPackages(packagesDirectory,
+ &filteredPackages, ftype);
+ QInstallerTools::copyMetaData(tmpMetaDir, packagesDirectory, packages, settings.applicationName(),
+ settings.applicationVersion());
+
+ copyConfigData(configFile, tmpMetaDir + QLatin1String("/installer-config"));
{
- QSettings confInternal(metaDir + QLatin1String("/config/config-internal.ini")
+ QSettings confInternal(tmpMetaDir + QLatin1String("/config/config-internal.ini")
, QSettings::IniFormat);
+ // assume offline installer if there are no repositories
+ offlineOnly |= settings.repositories().isEmpty();
confInternal.setValue(QLatin1String("offlineOnly"), offlineOnly);
}
#if defined(Q_OS_MAC)
// on mac, we enforce building a bundle
- if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg"))) {
+ if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg")))
target += QLatin1String(".app");
- }
#endif
- int result = EXIT_FAILURE;
- {
+ if (!compileResource) {
Input input;
input.outputPath = target;
input.installerExePath = templateBinary;
- input.binaryResourcePath = createBinaryResourceFile(metaDir);
+ input.binaryResourcePath = createBinaryResourceFile(tmpMetaDir, generateTemporaryFileName());
input.binaryResources = createBinaryResourceFiles(resources);
- QInstallerTools::copyComponentData(packagesDirectory, metaDir, packages);
+ QInstallerTools::copyComponentData(packagesDirectory, tmpMetaDir, &packages);
// now put the packages into the components section of the binary
foreach (const QInstallerTools::PackageInfo &info, packages) {
@@ -738,9 +751,9 @@ int main(int argc, char **argv)
comp.setName(info.name.toUtf8());
qDebug() << "Creating component info for" << info.name;
- foreach (const QString &archive, info.copiedArchives) {
+ foreach (const QString &archive, info.copiedFiles) {
const QSharedPointer<Archive> arch(new Archive(archive));
- qDebug() << QString::fromLatin1("\tAppending %1 (%2)").arg(archive,
+ qDebug() << QString::fromLatin1("Appending %1 (%2)").arg(archive,
humanReadableSize(arch->size()));
comp.appendArchive(arch);
}
@@ -748,22 +761,23 @@ int main(int argc, char **argv)
}
qDebug() << "Creating the binary";
- result = assemble(input, configFile);
+ exitCode = assemble(input, settings);
// cleanup
qDebug() << "Cleaning up...";
QFile::remove(input.binaryResourcePath);
foreach (const QString &resource, input.binaryResources)
QFile::remove(resource);
+ } else {
+ createBinaryResourceFile(tmpMetaDir, QDir::currentPath() + QLatin1String("/update.rcc"));
+ exitCode = EXIT_SUCCESS;
}
- removeDirectory(metaDir, true);
- return result;
} catch (const Error &e) {
- std::cerr << "caught exception: " << e.message() << std::endl;
- return EXIT_FAILURE;
+ std::cerr << "Caught exception: " << e.message() << std::endl;
} catch (...) {
std::cerr << "Unknown exception caught" << std::endl;
- return EXIT_FAILURE;
}
- return EXIT_FAILURE;
+
+ QInstaller::removeDirectory(tmpMetaDir, true);
+ return exitCode;
}
diff --git a/tools/binarycreator/binarycreator.pro b/tools/binarycreator/binarycreator.pro
index 342cde286..88e3464d9 100644
--- a/tools/binarycreator/binarycreator.pro
+++ b/tools/binarycreator/binarycreator.pro
@@ -16,3 +16,5 @@ SOURCES = binarycreator.cpp \
../common/repositorygen.cpp
HEADERS = rcc/rcc.h
RESOURCES += binarycreator.qrc
+
+macx:include(../../no_app_bundle.pri)
diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp
index 1549fb896..2af72f0cb 100644
--- a/tools/common/repositorygen.cpp
+++ b/tools/common/repositorygen.cpp
@@ -42,17 +42,17 @@
#include <fileutils.h>
#include <errors.h>
+#include <globals.h>
#include <lib7z_facade.h>
#include <settings.h>
#include <qinstallerglobal.h>
#include <utils.h>
+#include <scriptengine.h>
#include <kdupdater.h>
#include <QtCore/QDirIterator>
-#include <QtScript/QScriptEngine>
-
#include <QtXml/QDomDocument>
#include <iostream>
@@ -72,6 +72,33 @@ void QInstallerTools::printRepositoryGenOptions()
std::cout << " --ignore-invalid-packages Ignore all invalid packages instead of aborting." << std::endl;
}
+QString QInstallerTools::makePathAbsolute(const QString &path)
+{
+ if (QFileInfo(path).isRelative())
+ return QDir::current().absoluteFilePath(path);
+ return path;
+}
+
+void QInstallerTools::copyWithException(const QString &source, const QString &target, const QString &kind)
+{
+ qDebug() << QString::fromLatin1("Copying associated %1 file '%2'").arg(kind, source);
+
+ const QFileInfo targetFileInfo(target);
+ if (!targetFileInfo.dir().exists())
+ QInstaller::mkpath(targetFileInfo.absolutePath());
+
+ QFile sourceFile(source);
+ if (!sourceFile.copy(target)) {
+ qDebug() << "failed!\n";
+ throw QInstaller::Error(QString::fromLatin1("Could not copy the %1 file from\n'%2' to '%3'\nError: "
+ "'%4'.").arg(kind, source, target,
+ /* in case of an existing target the error String does not show the file */
+ (targetFileInfo.exists() ? QLatin1String("Target already exist.") : sourceFile.errorString())));
+ }
+
+ qDebug() << "done.\n";
+}
+
void QInstallerTools::compressPaths(const QStringList &paths, const QString &archivePath)
{
QFile archive(archivePath);
@@ -79,91 +106,92 @@ void QInstallerTools::compressPaths(const QStringList &paths, const QString &arc
Lib7z::createArchive(&archive, paths);
}
-void QInstallerTools::compressMetaDirectories(const QString &repoDir)
+static QStringList copyFilesFromNode(const QString &parentNode, const QString &childNode, const QString &attr,
+ const QString &kind, const QDomNode &package, const PackageInfo &info, const QString &targetDir)
{
- QDir dir(repoDir);
- const QStringList sub = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- foreach (const QString &i, sub) {
- QDir sd(dir);
- sd.cd(i);
- const QString absPath = sd.absolutePath();
- const QString fn = QLatin1String("meta.7z");
- const QString tmpTarget = repoDir + QLatin1String("/") +fn;
- compressPaths(QStringList() << absPath, tmpTarget);
- QFile tmp(tmpTarget);
- const QString finalTarget = absPath + QLatin1String("/") + fn;
- if (!tmp.rename(finalTarget)) {
- throw QInstaller::Error(QString::fromLatin1("Could not move file from '%1' to '%2'").arg(tmpTarget,
- finalTarget));
+ QStringList copiedFiles;
+ const QDomNodeList nodes = package.firstChildElement(parentNode).childNodes();
+ for (int i = 0; i < nodes.count(); ++i) {
+ const QDomNode node = nodes.at(i);
+ if (node.nodeName() != childNode)
+ continue;
+
+ const QDir dir(QString::fromLatin1("%1/meta").arg(info.directory));
+ const QString filter = attr.isEmpty() ? node.toElement().text() : node.toElement().attribute(attr);
+ const QStringList files = dir.entryList(QStringList(filter), QDir::Files);
+ if (files.isEmpty()) {
+ throw QInstaller::Error(QString::fromLatin1("Couldn't find any %1 matching '%2' "
+ "while copying %1 of '%3'.").arg(kind, filter, info.name));
+ }
+
+ foreach (const QString &file, files) {
+ const QString source(QString::fromLatin1("%1/meta/%2").arg(info.directory, file));
+ const QString target(QString::fromLatin1("%1/%2/%3").arg(targetDir, info.name, file));
+ copyWithException(source, target, kind);
+ copiedFiles.append(file);
}
}
+ return copiedFiles;
}
-void QInstallerTools::generateMetaDataDirectory(const QString &outDir, const QString &dataDir,
- const PackageInfoVector &packages, const QString &appName, const QString &appVersion,
- const QString &redirectUpdateUrl)
+void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &metaDataDir,
+ const PackageInfoVector &packages, const QString &appName, const QString &appVersion)
{
- QString metapath = outDir;
- if (QFileInfo(metapath).isRelative())
- metapath = QDir::cleanPath(QDir::current().absoluteFilePath(metapath));
- qDebug() << "Generating meta data...";
-
- if (!QFile::exists(metapath))
- QInstaller::mkpath(metapath);
+ const QString targetDir = makePathAbsolute(_targetDir);
+ if (!QFile::exists(targetDir))
+ QInstaller::mkpath(targetDir);
QDomDocument doc;
QDomElement root;
- // use existing Updates.xml, if any
- QFile existingUpdatesXml(QFileInfo(dataDir, QLatin1String("Updates.xml")).absoluteFilePath());
- if (!existingUpdatesXml.open(QIODevice::ReadOnly) || !doc.setContent(&existingUpdatesXml)) {
- root = doc.createElement(QLatin1String("Updates"));
- root.appendChild(doc.createElement(QLatin1String("ApplicationName"))).appendChild(
- doc.createTextNode(appName));
- root.appendChild(doc.createElement(QLatin1String("ApplicationVersion"))).appendChild(
- doc.createTextNode(appVersion));
- root.appendChild(doc.createElement(QLatin1String("Checksum"))).appendChild(
- doc.createTextNode(QLatin1String("true")));
- if (!redirectUpdateUrl.isEmpty()) {
- root.appendChild(doc.createElement(QLatin1String("RedirectUpdateUrl"))).appendChild(
- doc.createTextNode(redirectUpdateUrl));
+ QFile existingUpdatesXml(QFileInfo(metaDataDir, QLatin1String("Updates.xml")).absoluteFilePath());
+ if (existingUpdatesXml.open(QIODevice::ReadOnly) && doc.setContent(&existingUpdatesXml)) {
+ root = doc.documentElement();
+ // remove entry for this component from existing Updates.xml, if found
+ foreach (const PackageInfo &info, packages) {
+ const QDomNodeList packageNodes = root.childNodes();
+ for (int i = packageNodes.count() - 1; i >= 0; --i) {
+ const QDomNode node = packageNodes.at(i);
+ if (node.nodeName() != QLatin1String("PackageUpdate"))
+ continue;
+ if (node.firstChildElement(QLatin1String("Name")).text() != info.name)
+ continue;
+ root.removeChild(node);
+ }
}
+ existingUpdatesXml.close();
} else {
- root = doc.documentElement();
+ root = doc.createElement(QLatin1String("Updates"));
+ root.appendChild(doc.createElement(QLatin1String("ApplicationName"))).appendChild(doc
+ .createTextNode(appName));
+ root.appendChild(doc.createElement(QLatin1String("ApplicationVersion"))).appendChild(doc
+ .createTextNode(appVersion));
+ root.appendChild(doc.createElement(QLatin1String("Checksum"))).appendChild(doc
+ .createTextNode(QLatin1String("true")));
}
- for (PackageInfoVector::const_iterator it = packages.begin(); it != packages.end(); ++it) {
- const QString packageXmlPath = QString::fromLatin1("%1/meta/package.xml").arg(it->directory);
- qDebug() << QString::fromLatin1("\tGenerating meta data for package %1 using %2.").arg(
- it->name, packageXmlPath);
+ foreach (const PackageInfo &info, packages) {
+ if (!QDir(targetDir).mkpath(info.name))
+ throw QInstaller::Error(QString::fromLatin1("Could not create directory '%1'.").arg(info.name));
- // remove existing entry for this component from existing Updates.xml
- const QDomNodeList packageNodes = root.childNodes();
- for (int i = 0; i < packageNodes.count(); ++i) {
- const QDomNode node = packageNodes.at(i);
- if (node.nodeName() != QLatin1String("PackageUpdate"))
- continue;
- if (node.firstChildElement(QLatin1String("Name")).text() != it->name)
- continue;
- root.removeChild(node);
- --i;
- }
+ const QString packageXmlPath = QString::fromLatin1("%1/meta/package.xml").arg(info.directory);
+ qDebug() << QString::fromLatin1("Copy meta data for package '%1' using '%2'.").arg(info.name,
+ packageXmlPath);
- QDomDocument packageXml;
QFile file(packageXmlPath);
QInstaller::openForRead(&file, packageXmlPath);
+
QString errMsg;
- int col = 0;
int line = 0;
- if (!packageXml.setContent(&file, &errMsg, &line, &col)) {
+ int column = 0;
+ QDomDocument packageXml;
+ if (!packageXml.setContent(&file, &errMsg, &line, &column)) {
throw QInstaller::Error(QString::fromLatin1("Could not parse '%1': line: %2, column: %3: %4 (%5)")
- .arg(packageXmlPath, QString::number(line), QString::number(col), errMsg, it->name));
+ .arg(packageXmlPath).arg(line).arg(column).arg(errMsg, info.name));
}
- const QDomNode package = packageXml.firstChildElement(QLatin1String("Package"));
QDomElement update = doc.createElement(QLatin1String("PackageUpdate"));
- QDomElement nameElement = doc.createElement(QLatin1String("Name"));
- nameElement.appendChild(doc.createTextNode(it->name));
- update.appendChild(nameElement);
+ QDomNode nameElement = update.appendChild(doc.createElement(QLatin1String("Name")));
+ nameElement.appendChild(doc.createTextNode(info.name));
// list of current unused or later transformed tags
QStringList blackList;
@@ -173,6 +201,8 @@ void QInstallerTools::generateMetaDataDirectory(const QString &outDir, const QSt
bool foundDefault = false;
bool foundVirtual = false;
bool foundDisplayName = false;
+ bool foundDownloadableArchives = false;
+ const QDomNode package = packageXml.firstChildElement(QLatin1String("Package"));
const QDomNodeList childNodes = package.childNodes();
for (int i = 0; i < childNodes.count(); ++i) {
const QDomNode node = childNodes.at(i);
@@ -184,16 +214,17 @@ void QInstallerTools::generateMetaDataDirectory(const QString &outDir, const QSt
foundVirtual = true;
if (key == QLatin1String("DisplayName"))
foundDisplayName = true;
+ if (key == QLatin1String("DownloadableArchives"))
+ foundDownloadableArchives = true;
if (node.isComment() || blackList.contains(key))
continue; // just skip comments and some tags...
- const QString value = node.toElement().text();
QDomElement element = doc.createElement(key);
- for (int i = 0; i < node.attributes().size(); i++) {
- element.setAttribute(node.attributes().item(i).toAttr().name(),
- node.attributes().item(i).toAttr().value());
+ for (int j = 0; j < node.attributes().size(); ++j) {
+ element.setAttribute(node.attributes().item(j).toAttr().name(),
+ node.attributes().item(j).toAttr().value());
}
- update.appendChild(element).appendChild(doc.createTextNode(value));
+ update.appendChild(element).appendChild(doc.createTextNode(node.toElement().text()));
}
if (foundDefault && foundVirtual) {
@@ -202,10 +233,10 @@ void QInstallerTools::generateMetaDataDirectory(const QString &outDir, const QSt
}
if (!foundDisplayName) {
- qWarning() << "No DisplayName tag found, using component Name instead.";
+ qWarning() << QString::fromLatin1("No DisplayName tag found at '%1', using component Name instead."
+ ).arg(info.name);
QDomElement displayNameElement = doc.createElement(QLatin1String("DisplayName"));
- displayNameElement.appendChild(doc.createTextNode(it->name));
- update.appendChild(displayNameElement);
+ update.appendChild(displayNameElement).appendChild(doc.createTextNode(info.name));
}
// get the size of the data
@@ -213,19 +244,17 @@ void QInstallerTools::generateMetaDataDirectory(const QString &outDir, const QSt
quint64 compressedComponentSize = 0;
const QDir::Filters filters = QDir::Files | QDir::NoDotAndDotDot;
- const QDir cmpDataDir = QString::fromLatin1("%1/%2/data").arg(dataDir, it->name);
- const QFileInfoList entries = cmpDataDir.exists() ? cmpDataDir.entryInfoList(filters | QDir::Dirs)
- : QDir(QString::fromLatin1("%1/%2").arg(dataDir, it->name)).entryInfoList(filters);
-
+ const QDir dataDir = QString::fromLatin1("%1/%2/data").arg(metaDataDir, info.name);
+ const QFileInfoList entries = dataDir.exists() ? dataDir.entryInfoList(filters | QDir::Dirs)
+ : QDir(QString::fromLatin1("%1/%2").arg(metaDataDir, info.name)).entryInfoList(filters);
+ qDebug() << QString::fromLatin1("calculate size of directory: %1").arg(dataDir.absolutePath());
foreach (const QFileInfo &fi, entries) {
- if (fi.isHidden())
- continue;
-
try {
if (fi.isDir()) {
QDirIterator recursDirIt(fi.filePath(), QDirIterator::Subdirectories);
while (recursDirIt.hasNext()) {
- const quint64 size = QFile(recursDirIt.next()).size();
+ recursDirIt.next();
+ const quint64 size = QInstaller::fileSize(recursDirIt.fileInfo());
componentSize += size;
compressedComponentSize += size;
}
@@ -233,18 +262,20 @@ void QInstallerTools::generateMetaDataDirectory(const QString &outDir, const QSt
// if it's an archive already, list its files and sum the uncompressed sizes
QFile archive(fi.filePath());
compressedComponentSize += archive.size();
- archive.open(QIODevice::ReadOnly);
- const QVector< Lib7z::File > files = Lib7z::listArchive(&archive);
- for (QVector< Lib7z::File >::const_iterator fileIt = files.begin();
- fileIt != files.end(); ++fileIt) {
- componentSize += fileIt->uncompressedSize;
- }
+ QInstaller::openForRead(&archive, archive.fileName());
+
+ QVector<Lib7z::File>::const_iterator fileIt;
+ const QVector<Lib7z::File> files = Lib7z::listArchive(&archive);
+ for (fileIt = files.begin(); fileIt != files.end(); ++fileIt)
+ componentSize += fileIt->uncompressedSize;
} else {
// otherwise just add its size
- const quint64 size = fi.size();
+ const quint64 size = QInstaller::fileSize(fi);
componentSize += size;
compressedComponentSize += size;
}
+ } catch (const QInstaller::Error &error) {
+ qDebug() << error.message();
} catch(...) {
// ignore, that's just about the sizes - and size doesn't matter, you know?
}
@@ -259,206 +290,128 @@ void QInstallerTools::generateMetaDataDirectory(const QString &outDir, const QSt
root.appendChild(update);
- if (!QDir(metapath).mkpath(it->name))
- throw QInstaller::Error(QString::fromLatin1("Could not create directory '%1'.").arg(it->name));
-
- // copy scripts
+ // copy script file
const QString script = package.firstChildElement(QLatin1String("Script")).text();
if (!script.isEmpty()) {
- const QString fromLocation(QString::fromLatin1("%1/meta/%2").arg(it->directory, script));
-
QString scriptContent;
- QFile scriptFile(fromLocation);
+ QFile scriptFile(QString::fromLatin1("%1/meta/%2").arg(info.directory, script));
if (scriptFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&scriptFile);
scriptContent = in.readAll();
}
+
+ // if the user isn't aware of the downloadable archives value we will add it automatically later
+ foundDownloadableArchives |= scriptContent.contains(QLatin1String("addDownloadableArchive"))
+ || scriptContent.contains(QLatin1String("removeDownloadableArchive"));
+
static QScriptEngine testScriptEngine;
testScriptEngine.evaluate(scriptContent, scriptFile.fileName());
if (testScriptEngine.hasUncaughtException()) {
- throw QInstaller::Error(QString::fromLatin1("Exception while loading the component script: '%1'")
+ throw QInstaller::Error(QString::fromLatin1("Exception while loading component script: '%1'")
.arg(QInstaller::uncaughtExceptionString(&testScriptEngine, scriptFile.fileName())));
}
- // added the xml tag RequiresAdminRights to the xml if somewhere addElevatedOperation is used
+ // add RequiresAdminRights tag to xml if addElevatedOperation is used somewhere
if (scriptContent.contains(QLatin1String("addElevatedOperation"))) {
- QDomElement requiresAdminRightsElement =
- doc.createElement(QLatin1String("RequiresAdminRights"));
- requiresAdminRightsElement.appendChild(doc.createTextNode(QLatin1String("true")));
+ QDomElement element = doc.createElement(QLatin1String("RequiresAdminRights"));
+ element.appendChild(doc.createTextNode(QLatin1String("true")));
}
- qDebug() << "\tCopying associated script" << script << "into the meta package...";
- QString toLocation(QString::fromLatin1("%1/%2/%3").arg(metapath, it->name, script));
- if (!scriptFile.copy(toLocation)) {
- qDebug() << "failed!";
- throw QInstaller::Error(QString::fromLatin1("Could not copy the script '%1' to its target location '%2'.")
- .arg(fromLocation, toLocation));
- } else {
- qDebug() << "\tdone.";
- }
+ const QString toLocation(QString::fromLatin1("%1/%2/%3").arg(targetDir, info.name, script));
+ copyWithException(scriptFile.fileName(), toLocation, QLatin1String("script"));
}
- // copy user interfaces
- const QDomNodeList uiNodes = package.firstChildElement(QLatin1String("UserInterfaces")).childNodes();
- QStringList userinterfaces;
- for (int i = 0; i < uiNodes.count(); ++i) {
- const QDomNode node = uiNodes.at(i);
- if (node.nodeName() != QLatin1String("UserInterface"))
- continue;
-
- const QDir dir(QString::fromLatin1("%1/meta").arg(it->directory));
- const QStringList uis = dir.entryList(QStringList(node.toElement().text()), QDir::Files);
- if (uis.isEmpty()) {
- throw QInstaller::Error(QString::fromLatin1("Couldn't find any user interface matching '%1' while "
- "copying user interfaces of '%2'.").arg(node.toElement().text(), it->name));
- }
-
- for (QStringList::const_iterator ui = uis.begin(); ui != uis.end(); ++ui) {
- qDebug() << "\tCopying associated user interface" << *ui << "into the meta package...";
- userinterfaces.push_back(*ui);
- if (!QFile::copy(QString::fromLatin1("%1/meta/%2").arg(it->directory, *ui),
- QString::fromLatin1("%1/%2/%3").arg(metapath, it->name, *ui))) {
- qDebug() << "failed!";
- throw QInstaller::Error(QString::fromLatin1("Could not copy the UI file '%1' to its target "
- "location '%2'.").arg(*ui, it->name));
- } else {
- qDebug() << "done";
+ // write DownloadableArchives tag if that is missed by the user
+ if (!foundDownloadableArchives && !info.copiedFiles.isEmpty()) {
+ QStringList realContentFiles;
+ foreach (const QString &filePath, info.copiedFiles) {
+ if (!filePath.endsWith(QLatin1String(".sha1"), Qt::CaseInsensitive)) {
+ const QString fileName = QFileInfo(filePath).fileName();
+ // remove unnecessary version string from filename and add it to the list
+ realContentFiles.append(fileName.mid(info.version.count()));
}
}
+
+ update.appendChild(doc.createElement(QLatin1String("DownloadableArchives"))).appendChild(doc
+ .createTextNode(realContentFiles.join(QChar::fromLatin1(','))));
}
- if (!userinterfaces.isEmpty()) {
- update.appendChild(doc.createElement(QLatin1String("UserInterfaces")))
- .appendChild(doc.createTextNode(userinterfaces.join(QChar::fromLatin1(','))));
+ // copy user interfaces
+ const QStringList uiFiles = copyFilesFromNode(QLatin1String("UserInterfaces"),
+ QLatin1String("UserInterface"), QString(), QLatin1String("user interface"), package, info,
+ targetDir);
+ if (!uiFiles.isEmpty()) {
+ update.appendChild(doc.createElement(QLatin1String("UserInterfaces"))).appendChild(doc
+ .createTextNode(uiFiles.join(QChar::fromLatin1(','))));
}
// copy translations
- const QDomNodeList qmNodes = package.firstChildElement(QLatin1String("Translations")).childNodes();
- QStringList translations;
+ QStringList trFiles;
if (!qApp->arguments().contains(QString::fromLatin1("--ignore-translations"))) {
- for (int i = 0; i < qmNodes.count(); ++i) {
- const QDomNode node = qmNodes.at(i);
- if (node.nodeName() != QLatin1String("Translation"))
- continue;
-
- const QDir dir(QString::fromLatin1("%1/meta").arg(it->directory));
- const QStringList qms = dir.entryList(QStringList(node.toElement().text()), QDir::Files);
- if (qms.isEmpty()) {
- throw QInstaller::Error(QString::fromLatin1("Could not find any translation file matching '%1' "
- "while copying translations of '%2'.").arg(node.toElement().text(), it->name));
- }
-
- for (QStringList::const_iterator qm = qms.begin(); qm != qms.end(); ++qm) {
- qDebug() << "\tCopying associated translation" << *qm << "into the meta package...";
- translations.push_back(*qm);
- if (!QFile::copy(QString::fromLatin1("%1/meta/%2").arg(it->directory, *qm),
- QString::fromLatin1("%1/%2/%3").arg(metapath, it->name, *qm))) {
- qDebug() << "failed!";
- throw QInstaller::Error(QString::fromLatin1("Could not copy the translation '%1' to its "
- "target location '%2'.").arg(*qm, it->name));
- } else {
- qDebug() << "done";
- }
- }
+ trFiles = copyFilesFromNode(QLatin1String("Translations"), QLatin1String("Translation"),
+ QString(), QLatin1String("translation"), package, info, targetDir);
+ if (!trFiles.isEmpty()) {
+ update.appendChild(doc.createElement(QLatin1String("Translations"))).appendChild(doc
+ .createTextNode(trFiles.join(QChar::fromLatin1(','))));
}
-
- if (!translations.isEmpty()) {
- update.appendChild(doc.createElement(QLatin1String("Translations")))
- .appendChild(doc.createTextNode(translations.join(QChar::fromLatin1(','))));
- }
-
}
// copy license files
- const QDomNodeList licenseNodes = package.firstChildElement(QLatin1String("Licenses")).childNodes();
- for (int i = 0; i < licenseNodes.count(); ++i) {
- const QDomNode licenseNode = licenseNodes.at(i);
- if (licenseNode.nodeName() == QLatin1String("License")) {
- const QString &licenseFile =
- licenseNode.toElement().attributeNode(QLatin1String("file")).value();
- const QString &sourceFile =
- QString::fromLatin1("%1/meta/%2").arg(it->directory).arg(licenseFile);
- if (!QFile::exists(sourceFile)) {
- throw QInstaller::Error(QString::fromLatin1("Could not find any license matching '%1' while "
- "copying license files of '%2'.").arg(licenseFile, it->name));
- }
-
- qDebug() << "\tCopying associated license file" << licenseFile << "into the meta package...";
- if (!QFile::copy(sourceFile, QString::fromLatin1("%1/%2/%3")
- .arg(metapath, it->name, licenseFile))) {
- qDebug() << "failed!";
- throw QInstaller::Error(QString::fromLatin1("Could not copy the license file '%1' to its "
- "target location '%2'.").arg(licenseFile, it->name));
- } else {
- qDebug() << "done.";
- }
-
- // Translated License files
- for (int j = 0; j < translations.size(); ++j) {
- QFileInfo translationFile(translations.at(j));
- QFileInfo untranslated(licenseFile);
- const QString &translatedLicenseFile =
- QString::fromLatin1("%2_%3.%4").arg(untranslated.baseName(),
- translationFile.baseName(), untranslated.completeSuffix());
- const QString &translatedSourceFile =
- QString::fromLatin1("%1/meta/%2").arg(it->directory).arg(translatedLicenseFile);
- if (!QFile::exists(translatedSourceFile)) {
- qDebug() << "Could not find translated license file" << translatedSourceFile;
- continue;
- }
-
- qDebug() << "\tCopying associated license file" << translatedLicenseFile
- << "into the meta package...";
-
- if (!QFile::copy(translatedSourceFile, QString::fromLatin1("%1/%2/%3")
- .arg(metapath, it->name, translatedLicenseFile))) {
- qDebug() << "\tfailed!";
- } else {
- qDebug() << "\tdone.";
- }
+ const QStringList licenses = copyFilesFromNode(QLatin1String("Licenses"), QLatin1String("License"),
+ QLatin1String("file"), QLatin1String("license"), package, info, targetDir);
+ if (!licenses.isEmpty()) {
+ foreach (const QString &trFile, trFiles) {
+ // Copy translated license file based on the assumption that it will have the same base name
+ // as the original license plus the file name of an existing translation file without suffix.
+ foreach (const QString &license, licenses) {
+ const QFileInfo untranslated(license);
+ const QString translatedLicense = QString::fromLatin1("%2_%3.%4").arg(untranslated
+ .baseName(), QFileInfo(trFile).baseName(), untranslated.completeSuffix());
+ // ignore copy failure, that's just about the translations
+ QFile::copy(QString::fromLatin1("%1/meta/%2").arg(info.directory).arg(translatedLicense),
+ QString::fromLatin1("%1/%2/%3").arg(targetDir, info.name, translatedLicense));
}
}
- }
-
- if (licenseNodes.count() > 0)
update.appendChild(package.firstChildElement(QLatin1String("Licenses")).cloneNode());
+ }
}
-
doc.appendChild(root);
- const QString updatesXmlFile = QFileInfo(metapath, QLatin1String("Updates.xml")).absoluteFilePath();
- QFile updatesXml(updatesXmlFile);
-
- QInstaller::openForWrite(&updatesXml, updatesXmlFile);
- QInstaller::blockingWrite(&updatesXml, doc.toByteArray());
+ QFile targetUpdatesXml(targetDir + QLatin1String("/Updates.xml"));
+ QInstaller::openForWrite(&targetUpdatesXml, targetUpdatesXml.fileName());
+ QInstaller::blockingWrite(&targetUpdatesXml, doc.toByteArray());
}
PackageInfoVector QInstallerTools::createListOfPackages(const QString &packagesDirectory,
- const QStringList &filteredPackages, FilterType filterType)
+ QStringList *packagesToFilter, FilterType filterType)
{
- qDebug() << "Collecting information about available packages...";
+ qDebug() << "\nCollecting information about available packages...";
bool ignoreInvalidPackages = qApp->arguments().contains(QString::fromLatin1("--ignore-invalid-packages"));
PackageInfoVector dict;
- const QFileInfoList entries = QDir(packagesDirectory)
- .entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+ const QFileInfoList entries = QDir(packagesDirectory).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
for (QFileInfoList::const_iterator it = entries.begin(); it != entries.end(); ++it) {
if (filterType == Exclude) {
- if (filteredPackages.contains(it->fileName()))
+ // Check for current file in exclude list, if found, skip it and remove it from exclude list
+ if (packagesToFilter->contains(it->fileName())) {
+ packagesToFilter->removeAll(it->fileName());
continue;
+ }
} else {
- if (!filteredPackages.contains(it->fileName()))
+ // Check for current file in include list, if not found, skip it; if found, remove it from include list
+ if (!packagesToFilter->contains(it->fileName()))
continue;
+ packagesToFilter->removeAll(it->fileName());
}
- qDebug() << QString::fromLatin1("\tfound subdirectory '%1'").arg(it->fileName());
+ qDebug() << QString::fromLatin1("found subdirectory '%1'").arg(it->fileName());
// because the filter is QDir::Dirs - filename means the name of the subdirectory
if (it->fileName().contains(QLatin1Char('-'))) {
if (ignoreInvalidPackages)
continue;
- throw QInstaller::Error(QString::fromLatin1("Component '%1' mustn't contain '-'. This is not allowed, because "
- "dashes are used as the separator between the component name and the version number internally.")
- .arg(it->fileName()));
+ throw QInstaller::Error(QString::fromLatin1("Component '%1' mustn't contain '-'. This is not "
+ "allowed, because dashes are used as the separator between the component name and the "
+ "version number internally.").arg(it->fileName()));
}
QFile file(QString::fromLatin1("%1/meta/package.xml").arg(it->filePath()));
@@ -509,11 +462,16 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QString &packagesD
.arg(fileInfo.absoluteFilePath(), info.version));
}
info.dependencies = packageElement.firstChildElement(QLatin1String("Dependencies")).text()
- .split(QInstaller::scCommaRegExp, QString::SkipEmptyParts);
+ .split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
info.directory = it->filePath();
dict.push_back(info);
- qDebug() << QString::fromLatin1("\t- it provides the package %1 - %2").arg(name, info.version);
+ qDebug() << QString::fromLatin1("- it provides the package %1 - %2").arg(info.name, info.version);
+ }
+
+ if (!packagesToFilter->isEmpty() && packagesToFilter->at(0) != QString::fromLatin1(
+ "X_fake_filter_component_for_online_only_installer_X")) {
+ qWarning() << "The following explicitly given packages could not be found\n in package directory:" << *packagesToFilter;
}
if (dict.isEmpty())
@@ -582,8 +540,10 @@ void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QStr
const QByteArray sha1Sum = QInstaller::calculateHash(&tmp, QCryptographicHash::Sha1);
writeSHA1ToNodeWithName(doc, elements, sha1Sum, path);
const QString finalTarget = absPath + QLatin1String("/") + fn;
- if (!tmp.rename(finalTarget))
- throw QInstaller::Error(QString::fromLatin1("Could not move '%1' to '%2'").arg(tmpTarget, finalTarget));
+ if (!tmp.rename(finalTarget)) {
+ throw QInstaller::Error(QString::fromLatin1("Could not move '%1' to '%2'").arg(tmpTarget,
+ finalTarget));
+ }
}
QInstaller::openForWrite(&existingUpdatesXml, existingUpdatesXml.fileName());
@@ -592,10 +552,10 @@ void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QStr
}
void QInstallerTools::copyComponentData(const QString &packageDir, const QString &repoDir,
- PackageInfoVector &infos)
+ PackageInfoVector *const infos)
{
- for (int i = 0; i < infos.count(); ++i) {
- const PackageInfo info = infos.at(i);
+ for (int i = 0; i < infos->count(); ++i) {
+ const PackageInfo info = infos->at(i);
const QString name = info.name;
qDebug() << "Copying component data for" << name;
@@ -618,8 +578,8 @@ void QInstallerTools::copyComponentData(const QString &packageDir, const QString
qDebug() << QString::fromLatin1("Copying archive from '%1' to '%2'").arg(tmp.fileName(),
target);
if (!tmp.copy(target)) {
- throw QInstaller::Error(QString::fromLatin1("Could not copy '%1' to '%2': %3").arg(tmp.fileName(),
- target, tmp.errorString()));
+ throw QInstaller::Error(QString::fromLatin1("Could not copy '%1' to '%2': %3")
+ .arg(tmp.fileName(), target, tmp.errorString()));
}
compressedFiles.append(target);
} else {
@@ -644,7 +604,7 @@ void QInstallerTools::copyComponentData(const QString &packageDir, const QString
}
foreach (const QString &target, compressedFiles) {
- infos[i].copiedArchives.append(target);
+ (*infos)[i].copiedFiles.append(target);
QFile archiveFile(target);
QFile archiveHashFile(archiveFile.fileName() + QLatin1String(".sha1"));
@@ -661,7 +621,7 @@ void QInstallerTools::copyComponentData(const QString &packageDir, const QString
QInstaller::openForWrite(&archiveHashFile, archiveHashFile.fileName());
archiveHashFile.write(hashOfArchiveData);
qDebug() << "Generated sha1 hash:" << hashOfArchiveData;
- infos[i].copiedArchives.append(archiveHashFile.fileName());
+ (*infos)[i].copiedFiles.append(archiveHashFile.fileName());
archiveHashFile.close();
} catch (const QInstaller::Error &/*e*/) {
archiveFile.close();
diff --git a/tools/common/repositorygen.h b/tools/common/repositorygen.h
index 50349c8b6..b415bd561 100644
--- a/tools/common/repositorygen.h
+++ b/tools/common/repositorygen.h
@@ -48,7 +48,6 @@
namespace QInstallerTools {
-void printRepositoryGenOptions();
struct PackageInfo
{
@@ -56,7 +55,7 @@ struct PackageInfo
QString version;
QString directory;
QStringList dependencies;
- QStringList copiedArchives;
+ QStringList copiedFiles;
};
typedef QVector<PackageInfo> PackageInfoVector;
@@ -65,21 +64,22 @@ enum FilterType {
Exclude
};
+void printRepositoryGenOptions();
+QString makePathAbsolute(const QString &path);
+void copyWithException(const QString &source, const QString &target, const QString &kind = QString());
+
+PackageInfoVector createListOfPackages(const QString &packagesDirectory, QStringList *packagesToFilter,
+ FilterType ftype);
QHash<QString, QString> buildPathToVersionMapping(const PackageInfoVector &info);
-void compressMetaDirectories(const QString &repoDir);
void compressPaths(const QStringList &paths, const QString &archivePath);
void compressMetaDirectories(const QString &repoDir, const QString &baseDir,
const QHash<QString, QString> &versionMapping);
-void copyComponentData(const QString &packageDir, const QString &repoDir, PackageInfoVector &infos);
-
-void generateMetaDataDirectory(const QString &outDir, const QString &dataDir,
- const PackageInfoVector &packages, const QString &appName,
- const QString& appVersion, const QString &redirectUpdateUrl = QString());
+void copyMetaData(const QString &outDir, const QString &dataDir, const PackageInfoVector &packages,
+ const QString &appName, const QString& appVersion);
+void copyComponentData(const QString &packageDir, const QString &repoDir, PackageInfoVector *const infos);
-PackageInfoVector createListOfPackages(const QString &packagesDirectory, const QStringList &filteredPackages,
- FilterType ftype);
} // namespace QInstallerTools
diff --git a/tools/extractbinarydata/extractbinarydata.pro b/tools/extractbinarydata/extractbinarydata.pro
index c22ff41c4..8df54e9d6 100644
--- a/tools/extractbinarydata/extractbinarydata.pro
+++ b/tools/extractbinarydata/extractbinarydata.pro
@@ -8,7 +8,8 @@ QT -= gui
LIBS += -linstaller -l7z
CONFIG += console
-CONFIG -= app_bundle
DESTDIR = $$IFW_APP_PATH
SOURCES += main.cpp
+
+macx:include(../../no_app_bundle.pri)
diff --git a/tools/getrepositorycontent/domnodedebugstreamoperator.cpp b/tools/getrepositorycontent/domnodedebugstreamoperator.cpp
new file mode 100644
index 000000000..511b4a224
--- /dev/null
+++ b/tools/getrepositorycontent/domnodedebugstreamoperator.cpp
@@ -0,0 +1,53 @@
+/**************************************************************************
+**
+** Copyright (C) 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 "domnodedebugstreamoperator.h"
+
+QDebug operator<<(QDebug dbg, const QDomNode &domNode)
+{
+ if (domNode.isNull())
+ return dbg << "domNode is Null";
+ QString debugOutput;
+ QTextStream stream(&debugOutput);
+ domNode.save(stream, 4);
+
+ return dbg << debugOutput;
+}
diff --git a/tools/getrepositorycontent/domnodedebugstreamoperator.h b/tools/getrepositorycontent/domnodedebugstreamoperator.h
new file mode 100644
index 000000000..f48918f77
--- /dev/null
+++ b/tools/getrepositorycontent/domnodedebugstreamoperator.h
@@ -0,0 +1,51 @@
+/**************************************************************************
+**
+** Copyright (C) 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$
+**
+**************************************************************************/
+
+#ifndef DEBUGDOMNODE_H
+#define DEBUGDOMNODE_H
+
+#include <QDebug>
+#include <QDomNode>
+
+QDebug operator<<(QDebug dbg, const QDomNode &domNode);
+
+
+#endif // DEBUGDOMNODE_H
diff --git a/tools/getrepositorycontent/downloader.cpp b/tools/getrepositorycontent/downloader.cpp
new file mode 100644
index 000000000..0fd18fbe0
--- /dev/null
+++ b/tools/getrepositorycontent/downloader.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "downloader.h"
+
+#include <fileutils.h>
+
+#include <QtNetwork/QNetworkProxy>
+
+class ProxyFactory : public KDUpdater::FileDownloaderProxyFactory
+{
+public:
+ ProxyFactory() {}
+
+ ProxyFactory *clone() const
+ {
+ return new ProxyFactory();
+ }
+
+ QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery())
+ {
+ return QNetworkProxyFactory::systemProxyForQuery(query);
+ }
+};
+
+Downloader::Downloader(const QUrl &source, const QString &target)
+ : QObject()
+ , m_source(source)
+ , m_target(target)
+ , m_fileDownloader(0)
+{
+ m_fileDownloader = KDUpdater::FileDownloaderFactory::instance().create(m_source.scheme(), this);
+ if (!m_fileDownloader) {
+ qWarning() << "No downloader registered for scheme: " << m_source.scheme();
+ return;
+ }
+ m_fileDownloader->setDownloadedFileName(target);
+
+ if (m_fileDownloader) {
+ m_fileDownloader->setUrl(m_source);
+ m_fileDownloader->setProxyFactory(new ProxyFactory());
+
+ connect(m_fileDownloader, SIGNAL(downloadCanceled()), this, SLOT(downloadFinished()));
+ connect(m_fileDownloader, SIGNAL(downloadCompleted()), this, SLOT(downloadFinished()));
+ connect(m_fileDownloader, SIGNAL(downloadAborted(QString)), this, SLOT(downloadFinished(QString)));
+
+ connect(m_fileDownloader, SIGNAL(downloadSpeed(qint64)), this, SLOT(downloadSpeed(qint64)));
+ connect(m_fileDownloader, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
+
+ m_fileDownloader->setAutoRemoveDownloadedFile(false);
+ }
+
+}
+
+void Downloader::downloadFinished(const QString &message)
+{
+ if (!message.isEmpty())
+ qDebug() << "Error:" << message;
+ progressBar.setStatus(100, 100);
+ progressBar.update();
+ printf("\n");
+ emit finished();
+}
+
+void Downloader::downloadSpeed(qint64 speed)
+{
+ progressBar.setMessage(QString::fromLatin1("%1 /sec").arg(QInstaller::humanReadableSize(speed)));
+}
+
+void Downloader::downloadProgress(qint64 bytesReceived, qint64 bytesToReceive)
+{
+ if (bytesReceived == 0 || bytesToReceive == 0)
+ return;
+ progressBar.setStatus(bytesReceived, bytesToReceive);
+ progressBar.update();
+}
+
+void Downloader::run()
+{
+ m_fileDownloader->download();
+}
diff --git a/tools/repogenfromonlinerepo/downloadmanager.h b/tools/getrepositorycontent/downloader.h
index 13cce7163..bb4631bb9 100644
--- a/tools/repogenfromonlinerepo/downloadmanager.h
+++ b/tools/getrepositorycontent/downloader.h
@@ -38,8 +38,13 @@
**
****************************************************************************/
-#ifndef DOWNLOADMANAGER_H
-#define DOWNLOADMANAGER_H
+#ifndef DOWNLOADER_H
+#define DOWNLOADER_H
+
+#include "textprogressbar.h"
+
+#include <kdupdaterfiledownloader.h>
+#include <kdupdaterfiledownloaderfactory.h>
#include <QFile>
#include <QObject>
@@ -48,37 +53,24 @@
#include <QUrl>
#include <QNetworkAccessManager>
-#include "textprogressbar.h"
-
-class DownloadManager: public QObject
+class Downloader : public QObject
{
Q_OBJECT
public:
- DownloadManager(QObject *parent = 0);
-
- void append(const QUrl &url);
- void append(const QStringList &urlList);
- QString saveFileName(const QUrl &url);
-
+ explicit Downloader(const QUrl &source, const QString &target);
+ void run();
signals:
void finished();
-
private slots:
- void startNextDownload();
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- void downloadFinished();
- void downloadReadyRead();
+ void downloadFinished(const QString &message = QString());
+ void downloadSpeed(qint64 speed);
+ void downloadProgress(qint64 bytesReceived, qint64 bytesToReceive);
private:
- QNetworkAccessManager manager;
- QQueue<QUrl> downloadQueue;
- QNetworkReply *currentDownload;
- QFile output;
- QTime downloadTime;
TextProgressBar progressBar;
-
- int downloadedCount;
- int totalCount;
+ QUrl m_source;
+ QString m_target;
+ KDUpdater::FileDownloader *m_fileDownloader;
};
-#endif
+#endif // DOWNLOADER_H
diff --git a/tools/getrepositorycontent/getrepositorycontent.pro b/tools/getrepositorycontent/getrepositorycontent.pro
new file mode 100644
index 000000000..46a6efd13
--- /dev/null
+++ b/tools/getrepositorycontent/getrepositorycontent.pro
@@ -0,0 +1,23 @@
+TEMPLATE = app
+INCLUDEPATH += . ..
+TARGET = getrepositorycontent
+
+include(../../installerfw.pri)
+
+QT -= gui
+QT += network
+
+CONFIG += console
+DESTDIR = $$IFW_APP_PATH
+
+SOURCES += main.cpp \
+ textprogressbar.cpp \
+ downloader.cpp \
+ domnodedebugstreamoperator.cpp
+
+HEADERS += \
+ textprogressbar.h \
+ downloader.h \
+ domnodedebugstreamoperator.h
+
+macx:include(../../no_app_bundle.pri)
diff --git a/tools/getrepositorycontent/main.cpp b/tools/getrepositorycontent/main.cpp
new file mode 100644
index 000000000..66a2ec43f
--- /dev/null
+++ b/tools/getrepositorycontent/main.cpp
@@ -0,0 +1,450 @@
+/**************************************************************************
+**
+** Copyright (C) 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 "downloader.h"
+#include "domnodedebugstreamoperator.h"
+
+#include <globals.h>
+#include <init.h>
+#include <fileutils.h>
+#include <lib7z_facade.h>
+#include <utils.h>
+
+#include <QCoreApplication>
+#include <QFile>
+#include <QUrl>
+#include <QString>
+#include <QDomDocument>
+#include <QDomElement>
+#include <QDomNodeList>
+#include <QStringList>
+#include <QDebug>
+#include <QFileInfo>
+#include <QDir>
+#include <QDirIterator>
+#include <QDebug>
+
+#include <iostream>
+
+static void printUsage()
+{
+ const QString appName = QFileInfo( QCoreApplication::applicationFilePath() ).fileName();
+ std::cout << "Usage: " << qPrintable(appName)
+ << " --url <repository_url> --repository <empty_repository_dir> --packages <empty_packages_dir>" << std::endl;
+ std::cout << " --url URL to fetch all the content from." << std::endl;
+ std::cout << " --repository Target directory for the repository content." << std::endl;
+ std::cout << " --packages The packages target directory where it creates the needed content to create new installers or repositories." << std::endl;
+ std::cout << " --clean Removes all the content if there is an existing repository or packages dir" << std::endl;
+
+ std::cout << "Example:" << std::endl;
+ std::cout << " " << qPrintable(appName) << " --url http://www.example.com/repository/" <<
+ " --repository repository --packages packages" << std::endl;
+}
+
+// this should be a new class which uses XmlStreamReader instead of DomDocument
+// should be implicit shared, see repository class
+// maybe we can use some code from persistentdata in qtcreator
+class ComponentData {
+ public:
+ ComponentData() {}
+ ComponentData(const QString &/*xmlData*/) {}
+
+ QVariant attributeValue(const QString &key, const QString &attribute, const QVariant &defaultValue = QVariant()) {
+ Q_UNUSED(key)
+ Q_UNUSED(attribute)
+ return defaultValue;
+ }
+
+ QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) {
+ Q_UNUSED(defaultValue)
+ // just use the quick dirty hack added members
+ if (key == QLatin1String("Script"))
+ return m_script;
+ if (key == QLatin1String("Version"))
+ return m_version;
+ return QVariant();
+ }
+ QString textValue(const QString &key, const QString &defaultValue = QString()) {
+ return value(key, defaultValue).toString();
+ }
+
+ // quick dirty hack added public members
+ public:
+ QDomDocument m_packageXml;
+ QStringList m_downloadDownloadableArchives;
+ QString m_script;
+ QString m_version;
+};
+
+static void downloadFile(const QUrl &source, const QString &target)
+{
+ QEventLoop downloadEventLoop;
+ Downloader downloader(source, target);
+ QObject::connect(&downloader, SIGNAL(finished()), &downloadEventLoop, SLOT(quit()));
+ downloader.run();
+ downloadEventLoop.exec();
+}
+
+QHash<QString, ComponentData> downLoadRepository(const QString &repositoryUrl, const QString &repositoryTarget)
+{
+ const QString updatesXmlFileName = QLatin1String("Updates.xml");
+ QHash<QString, ComponentData> componentDataHash;
+
+ const QUrl updatesXmlUrl(QString::fromLatin1("%1/%2").arg(repositoryUrl, updatesXmlFileName));
+
+ downloadFile(updatesXmlUrl, QDir(repositoryTarget).filePath(updatesXmlFileName));
+
+ QFile updatesFile(QDir(repositoryTarget).filePath(updatesXmlFileName));
+ if (!updatesFile.exists()) {
+ qDebug() << "could not download the file:" << updatesXmlUrl.toString();
+ return componentDataHash;
+ } else
+ qDebug() << "file downloaded to location:" << QDir(repositoryTarget).filePath(updatesXmlFileName);
+ if (!updatesFile.open(QIODevice::ReadOnly)) {
+ qDebug() << QString::fromLatin1("Could not open Updates.xml for reading: %1").arg(updatesFile
+ .errorString()) ;
+ return componentDataHash;
+ }
+
+ QStringList ignoreTagList;
+ ignoreTagList << QLatin1String("Name");
+ ignoreTagList << QLatin1String("ReleaseDate");
+ ignoreTagList << QLatin1String("SHA1");
+ ignoreTagList << QLatin1String("UpdateFile");
+ QStringList fileTagList;
+ fileTagList << QLatin1String("DownloadableArchives");
+
+
+ QDomDocument updatesXml;
+ QString error;
+ int line = 0;
+ int column = 0;
+ if (!updatesXml.setContent( &updatesFile, &error, &line, &column)) {
+ qWarning() << QString::fromLatin1("Could not parse component index: %1:%2: %3")
+ .arg(QString::number(line), QString::number(column), error);
+ return componentDataHash;
+ }
+
+ QDomNode packageUpdateDomNode = updatesXml.firstChildElement(QLatin1String("Updates")).firstChildElement(
+ QLatin1String("PackageUpdate"));
+ while (!packageUpdateDomNode.isNull()) {
+
+ if (packageUpdateDomNode.nodeName() == QLatin1String("PackageUpdate")) {
+ QDomNode packageUpdateEntry = packageUpdateDomNode.firstChild();
+ QString currentPackageName;
+ ComponentData currentComponentData;
+ // creating the package.xml for later use
+ QDomElement currentNewPackageElement = currentComponentData.m_packageXml.createElement(
+ QLatin1String("Package"));
+ while (!packageUpdateEntry.isNull()) {
+ // do name first before ignore filters the name out
+ if (packageUpdateEntry.nodeName() == QLatin1String("Name")) {
+ currentPackageName = packageUpdateEntry.toElement().text();
+ }
+ if (ignoreTagList.contains(packageUpdateEntry.nodeName())) {
+ packageUpdateEntry = packageUpdateEntry.nextSibling();
+ continue;
+ }
+ if (packageUpdateEntry.nodeName() == QLatin1String("Script")) {
+ currentComponentData.m_script = packageUpdateEntry.toElement().text();
+ }
+ if (packageUpdateEntry.nodeName() == QLatin1String("Version")) {
+ currentComponentData.m_version = packageUpdateEntry.toElement().text();
+ currentComponentData.m_downloadDownloadableArchives.append(
+ currentComponentData.m_version + QLatin1String("meta.7z"));
+ }
+
+ if (packageUpdateEntry.nodeName() == QLatin1String("DownloadableArchives")) {
+ QStringList tDownloadList = packageUpdateEntry.toElement().text().split(
+ QInstaller::commaRegExp(), QString::SkipEmptyParts);
+ foreach (const QString &download, tDownloadList) {
+ currentComponentData.m_downloadDownloadableArchives.append(
+ currentComponentData.m_version + download);
+ currentComponentData.m_downloadDownloadableArchives.append(
+ currentComponentData.m_version + download + QLatin1String(".sha1"));
+ }
+ }
+
+ currentNewPackageElement.appendChild(packageUpdateEntry.cloneNode(true));
+ packageUpdateEntry = packageUpdateEntry.nextSibling();
+ }
+ currentComponentData.m_packageXml.appendChild(currentNewPackageElement);
+ Q_ASSERT(!currentComponentData.m_packageXml.toString().isEmpty());
+ componentDataHash.insert(currentPackageName, currentComponentData);
+ } else {
+ qWarning() << QString::fromLatin1("Unknown elment '%1'").arg(packageUpdateDomNode.nodeName(),
+ QFileInfo(updatesXmlFileName).absoluteFilePath());
+ }
+ packageUpdateDomNode = packageUpdateDomNode.nextSibling();
+ }
+
+ QHashIterator<QString, ComponentData> itComponentData(componentDataHash);
+ while (itComponentData.hasNext()) {
+ itComponentData.next();
+ QString componentDirectory = QDir(repositoryTarget).filePath(itComponentData.key());
+ if (!QDir().mkpath(componentDirectory))
+ qWarning() << "couldn't create:" << componentDirectory;
+
+ foreach (const QString &download, itComponentData.value().m_downloadDownloadableArchives) {
+ const QString fileTarget(componentDirectory + QDir::separator() + download);
+ const QUrl downloadUrl(repositoryUrl + QLatin1String("/") + itComponentData.key() + QLatin1String("/") + download);
+ downloadFile(downloadUrl, fileTarget);
+ }
+ }
+ return componentDataHash;
+}
+
+bool extractFile(const QString &source, const QString &target)
+{
+ if (!Lib7z::isSupportedArchive(source)) {
+ qWarning() << source << "is not a supported archive";
+ }
+
+ QFile archive(source);
+ if (archive.open(QIODevice::ReadOnly)) {
+ try {
+ Lib7z::extractArchive(&archive, target);
+ } catch (const Lib7z::SevenZipException& e) {
+ qWarning() << QString::fromLatin1("Error while extracting %1: %2.").arg(source, e.message());
+ return false;
+ } catch (...) {
+ qWarning() << QString::fromLatin1("Unknown exception caught while extracting %1.").arg(source);
+ return false;
+ }
+ } else {
+ qWarning() << QString::fromLatin1("Could not open %1 for reading: %2.").arg(
+ target, archive.errorString());
+ return false;
+ }
+ return true;
+}
+
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ // init installer to have the 7z lib initialized
+ QInstaller::init();
+ // with the installer messagehandler we need to enable verbose to see QDebugs
+ QInstaller::setVerbose(true);
+
+ QString repositoryUrl;
+ QString repositoryTarget;
+ QString packageDirectoryTarget;
+ bool clean = false;
+ QStringList args = app.arguments();
+ QStringList::const_iterator itArgument = args.constBegin();
+ itArgument++; // ignore the first one
+ if (itArgument == args.constEnd()) {
+ printUsage();
+ return 0;
+ }
+
+ for (; itArgument != args.constEnd(); ++itArgument) {
+ if (*itArgument == QString::fromLatin1("-h") || *itArgument == QString::fromLatin1("--help")) {
+ printUsage();
+ return 0;
+ } else if (*itArgument == QString::fromLatin1("--clean")) {
+ clean = true;
+ } else if (*itArgument == QString::fromLatin1("-u") || *itArgument == QString::fromLatin1("--url")) {
+ ++itArgument;
+ if (itArgument == args.end()) {
+ printUsage();
+ return -1;
+ } else {
+ repositoryUrl = *itArgument;
+ }
+ } else if (*itArgument == QString::fromLatin1("-r") || *itArgument == QString::fromLatin1("--repository")) {
+ ++itArgument;
+ if (itArgument == args.end()) {
+ printUsage();
+ return -1;
+ } else {
+ repositoryTarget = *itArgument;
+ }
+ } else if (*itArgument == QString::fromLatin1("-p") || *itArgument == QString::fromLatin1("--packages")) {
+ ++itArgument;
+ if (itArgument == args.end()) {
+ printUsage();
+ return -1;
+ } else {
+ packageDirectoryTarget = *itArgument;
+ }
+ } else {
+ qWarning() << QString::fromLatin1("Argument '%1' is unknown").arg(*itArgument);
+ printUsage();
+ return 0;
+ }
+ }
+ if (repositoryTarget.isEmpty() || packageDirectoryTarget.isEmpty()) {
+ printUsage();
+ return 0;
+ } else {
+ // resolve pathes
+ repositoryTarget = QFileInfo(repositoryTarget).absoluteFilePath();
+ packageDirectoryTarget = QFileInfo(packageDirectoryTarget).absoluteFilePath();
+ }
+
+ foreach (const QString &target, QStringList() << repositoryTarget << packageDirectoryTarget) {
+ if (QFileInfo(target).exists()) {
+ if (clean) {
+ qDebug() << "removing directory:" << target;
+ QInstaller::removeDirectory(target, true);
+ } else if (!QDir(target).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()){
+ qWarning() << QString::fromLatin1("The directory '%1' needs to be empty or just "
+ "add the --clean argument.").arg(target);
+ return EXIT_FAILURE;
+ }
+ }
+
+ while (!QDir().mkpath(target)) {
+ qWarning() << QString::fromLatin1("Could not create %1").arg(target);
+ }
+ }
+
+ QHash<QString, ComponentData> componentDataHash;
+ componentDataHash = downLoadRepository(repositoryUrl, repositoryTarget);
+
+ // maybe in that case we should download the meta data to temp and
+ // get the downdloadable archives information from there later
+ if (packageDirectoryTarget.isEmpty())
+ return EXIT_SUCCESS;
+
+ QDirIterator itRepositoryFile(repositoryTarget, QDir::Files, QDirIterator::Subdirectories);
+ while (itRepositoryFile.hasNext()) {
+ QString currentFile = itRepositoryFile.next();
+
+ QString componentSubdirectoryName = itRepositoryFile.filePath();
+
+ QString normalizedRepositoryTarget = repositoryTarget;
+ normalizedRepositoryTarget.replace(QLatin1Char('\\'), QLatin1Char('/'));
+
+ componentSubdirectoryName.remove(repositoryTarget);
+ componentSubdirectoryName.remove(normalizedRepositoryTarget);
+
+ QString componentPackageDir = QFileInfo(packageDirectoryTarget + QDir::separator() + componentSubdirectoryName).absolutePath();
+ QString absoluteSourceFilePath = itRepositoryFile.filePath();
+
+ if (currentFile.endsWith(QLatin1String("meta.7z"))) {
+ QString absolutTargetPath = QFileInfo(
+ packageDirectoryTarget + QDir::separator()).absolutePath();
+
+ extractFile(absoluteSourceFilePath, absolutTargetPath);
+ QInstaller::moveDirectoryContents(componentPackageDir,
+ componentPackageDir + QDir::separator() + QLatin1String("meta"));
+ } else if (!currentFile.endsWith(QLatin1String("Updates.xml")) && !currentFile.endsWith(QLatin1String(".sha1"))){
+ QString pathToTarget = componentPackageDir + QDir::separator() + QLatin1String("data");
+ QString target = QDir(pathToTarget).absoluteFilePath(itRepositoryFile.fileName());
+ QDir().mkpath(pathToTarget);
+ QFile file;
+ if (!file.copy(absoluteSourceFilePath, target)) {
+ qWarning() << QString::fromLatin1("copy file %1 to %2 wasn't working %3").arg(
+ absoluteSourceFilePath, target, file.errorString());
+ }
+ }
+ }
+
+
+ QHashIterator<QString, ComponentData> itComponentData(componentDataHash);
+ while (itComponentData.hasNext()) {
+ itComponentData.next();
+ if (itComponentData.value().m_script.isEmpty())
+ continue;
+
+ QString componentScript = QFileInfo(QString::fromLatin1("%1/%2/meta/%3").arg(
+ packageDirectoryTarget, itComponentData.key(), itComponentData.value().m_script)).absoluteFilePath();
+
+ QString packagesXml = QFileInfo(QString::fromLatin1("%1/%2/meta/packages.xml").arg(
+ packageDirectoryTarget, itComponentData.key())).absoluteFilePath();
+
+ QFile packagesXmlFile(packagesXml);
+
+ if (!packagesXmlFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ qWarning() << QString::fromLatin1("Failed to open '%1' for writing. %2").arg(
+ packagesXml, packagesXmlFile.errorString());
+ return EXIT_FAILURE;
+ }
+
+ if (itComponentData.value().m_packageXml.toString().isEmpty()) {
+ qWarning() << "No xml data found in component:" << itComponentData.key();
+ return EXIT_FAILURE;
+ }
+
+ QTextStream stream(&packagesXmlFile);
+ stream << itComponentData.value().m_packageXml.toString(4);
+ packagesXmlFile.close();
+
+ QString dataPackagesPath = QFileInfo(QString::fromLatin1("%1/%2/data").arg(
+ packageDirectoryTarget, itComponentData.key())).absoluteFilePath();
+ QDir().mkpath(dataPackagesPath);
+
+ QString dataRepositoryPath = QFileInfo(repositoryTarget + QDir::separator() + itComponentData.key()).absoluteFilePath();
+ QDir().mkpath(dataRepositoryPath);
+
+ QFile componentScriptFile(componentScript);
+ if (!componentScriptFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qDebug() << QString::fromLatin1("Can not read %1 %2").arg(componentScript, componentScriptFile.errorString());
+ continue;
+ }
+
+ QString sevenZString;
+ QTextStream in(&componentScriptFile);
+ in.setCodec("UTF-8");
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ if (line.contains(QLatin1String(".7z"))) {
+ int firstPosition = line.indexOf(QLatin1String("\""));
+ QString subString = line.right(line.count() - firstPosition - 1); //-1 means "
+ //qDebug() << subString;
+ int secondPosition = subString.indexOf(QLatin1String("\""));
+ sevenZString = subString.left(secondPosition);
+ QUrl downloadUrl((QStringList() << repositoryUrl << itComponentData.key() << itComponentData.value().m_version + sevenZString).join(QLatin1String("/")));
+ QString localRepositoryTarget = dataRepositoryPath + QLatin1Char('/') + itComponentData.value().m_version + sevenZString;
+ downloadFile(downloadUrl, localRepositoryTarget);
+ downloadFile(downloadUrl.toString() + QLatin1String(".sha1"), localRepositoryTarget + QLatin1String(".sha1"));
+ QFile::copy(localRepositoryTarget, dataPackagesPath + QLatin1Char('/') + sevenZString);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/tools/repogenfromonlinerepo/textprogressbar.cpp b/tools/getrepositorycontent/textprogressbar.cpp
index 14faefd5e..14faefd5e 100644
--- a/tools/repogenfromonlinerepo/textprogressbar.cpp
+++ b/tools/getrepositorycontent/textprogressbar.cpp
diff --git a/tools/repogenfromonlinerepo/textprogressbar.h b/tools/getrepositorycontent/textprogressbar.h
index 6f01f0c84..6f01f0c84 100644
--- a/tools/repogenfromonlinerepo/textprogressbar.h
+++ b/tools/getrepositorycontent/textprogressbar.h
diff --git a/tools/repocompare/repocompare.pro b/tools/repocompare/repocompare.pro
index 8bdb83516..04f50dc5a 100644
--- a/tools/repocompare/repocompare.pro
+++ b/tools/repocompare/repocompare.pro
@@ -5,7 +5,6 @@ TARGET = repocompare
include(../../installerfw.pri)
QT += network
-CONFIG -= app_bundle
DESTDIR = $$IFW_APP_PATH
SOURCES += main.cpp\
@@ -16,3 +15,5 @@ HEADERS += mainwindow.h \
repositorymanager.h
FORMS += mainwindow.ui
+
+macx:include(../../no_app_bundle.pri)
diff --git a/tools/repogen/repogen.cpp b/tools/repogen/repogen.cpp
index 1380e4ebf..e0e0a88c0 100644
--- a/tools/repogen/repogen.cpp
+++ b/tools/repogen/repogen.cpp
@@ -43,10 +43,12 @@
#include <errors.h>
#include <fileutils.h>
#include <init.h>
+#include <kdupdater.h>
#include <settings.h>
#include <utils.h>
#include <lib7z_facade.h>
+#include <QDomDocument>
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
#include <QtCore/QFileInfo>
@@ -69,18 +71,20 @@ static void printUsage()
QInstallerTools::printRepositoryGenOptions();
std::cout << " -r|--remove Force removing target directory if existent." << std::endl;
- std::cout << " -u|--updateurl URL instructs clients to receive updates from a " << std::endl;
- std::cout << " different location" << std::endl;
std::cout << " --update Update a set of existing components (defined by " << std::endl;
std::cout << " --include or --exclude) in the repository" << std::endl;
+ std::cout << " --update-new-components Update a set of existing components (defined by " << std::endl;
+ std::cout << " --include or --exclude) in the repository with all new components"
+ << std::endl;
+
std::cout << " -v|--verbose Verbose output" << std::endl;
std::cout << std::endl;
std::cout << "Example:" << std::endl;
- std::cout << " " << appName << " -p ../examples/packages -u "
- "http://www.some-server.com:8080 repository/" << std::endl;
+ std::cout << " " << appName << " -p ../examples/packages -u http://www.example.com:8080 repository/"
+ << std::endl;
}
static int printErrorAndUsageAndExit(const QString &err)
@@ -90,16 +94,10 @@ static int printErrorAndUsageAndExit(const QString &err)
return 1;
}
-static QString makeAbsolute(const QString &path)
-{
- QFileInfo fi(path);
- if (fi.isAbsolute())
- return path;
- return QDir::current().absoluteFilePath(path);
-}
-
int main(int argc, char** argv)
{
+ QString tmpMetaDir;
+ int exitCode = EXIT_FAILURE;
try {
QCoreApplication app(argc, argv);
@@ -110,9 +108,9 @@ int main(int argc, char** argv)
QStringList filteredPackages;
bool updateExistingRepository = false;
QString packagesDir;
- QString redirectUpdateUrl;
QInstallerTools::FilterType filterType = QInstallerTools::Exclude;
bool remove = false;
+ bool updateExistingRepositoryWithNewComponents = false;
//TODO: use a for loop without removing values from args like it is in binarycreator.cpp
//for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) {
@@ -139,9 +137,12 @@ int main(int argc, char** argv)
filteredPackages = args.first().split(QLatin1Char(','));
args.removeFirst();
filterType = QInstallerTools::Include;
- } else if (args.first() == QLatin1String("--single") || args.first() == QLatin1String("--update")) {
+ } else if (args.first() == QLatin1String("--update")) {
args.removeFirst();
updateExistingRepository = true;
+ } else if (args.first() == QLatin1String("--update-new-components")) {
+ args.removeFirst();
+ updateExistingRepositoryWithNewComponents = true;
} else if (args.first() == QLatin1String("-p") || args.first() == QLatin1String("--packages")) {
args.removeFirst();
if (args.isEmpty()) {
@@ -160,12 +161,6 @@ int main(int argc, char** argv)
return printErrorAndUsageAndExit(QObject::tr("Error: Config parameter missing argument"));
args.removeFirst();
std::cout << "Config file parameter is deprecated and ignored." << std::endl;
- } else if (args.first() == QLatin1String("-u") || args.first() == QLatin1String("--updateurl")) {
- args.removeFirst();
- if (args.isEmpty())
- return printErrorAndUsageAndExit(QObject::tr("Error: Config parameter missing argument"));
- redirectUpdateUrl = args.first();
- args.removeFirst();
} else if (args.first() == QLatin1String("--ignore-translations")
|| args.first() == QLatin1String("--ignore-invalid-packages")) {
args.removeFirst();
@@ -183,23 +178,72 @@ int main(int argc, char** argv)
return 1;
}
- if (remove && updateExistingRepository) {
- throw QInstaller::Error(QObject::tr("Argument -r|--remove and --single|--update are mutually "
- "exclusive!"));
+ const bool update = updateExistingRepository || updateExistingRepositoryWithNewComponents;
+ if (remove && update) {
+ throw QInstaller::Error(QObject::tr("Argument -r|--remove and --update|--update-new-components "
+ "are mutually exclusive!"));
}
- const QString repositoryDir = makeAbsolute(args.first());
+ const QString repositoryDir = QInstallerTools::makePathAbsolute(args.first());
if (remove)
QInstaller::removeDirectory(repositoryDir);
- if (!updateExistingRepository && QFile::exists(repositoryDir)) {
+ if (!update && QFile::exists(repositoryDir) && !QDir(repositoryDir).entryList(
+ QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) {
+
throw QInstaller::Error(QObject::tr("Repository target folder %1 already exists!")
.arg(repositoryDir));
}
QInstallerTools::PackageInfoVector packages = QInstallerTools::createListOfPackages(packagesDir,
- filteredPackages, filterType);
- QHash<QString, QString> pathToVersionMapping = buildPathToVersionMapping(packages);
+ &filteredPackages, filterType);
+
+ if (updateExistingRepositoryWithNewComponents) {
+ QDomDocument doc;
+ QFile file(repositoryDir + QLatin1String("/Updates.xml"));
+ if (file.open(QFile::ReadOnly) && doc.setContent(&file)) {
+ const QDomElement root = doc.documentElement();
+ if (root.tagName() != QLatin1String("Updates"))
+ throw QInstaller::Error(QObject::tr("Invalid content in '%1'.").arg(file.fileName()));
+ file.close(); // close the file, we read the content already
+
+ // read the already existing updates xml content
+ const QDomNodeList children = root.childNodes();
+ QHash <QString, QInstallerTools::PackageInfo> hash;
+ for (int i = 0; i < children.count(); ++i) {
+ const QDomElement el = children.at(i).toElement();
+ if ((!el.isNull()) && (el.tagName() == QLatin1String("PackageUpdate"))) {
+ QInstallerTools::PackageInfo info;
+ const QDomNodeList c2 = el.childNodes();
+ for (int j = 0; j < c2.count(); ++j) {
+ if (c2.at(j).toElement().tagName() == scName)
+ info.name = c2.at(j).toElement().text();
+ else if (c2.at(j).toElement().tagName() == scRemoteVersion)
+ info.version = c2.at(j).toElement().text();
+ }
+ hash.insert(info.name, info);
+ }
+ }
+
+ // remove all components that have no update (decision based on the version tag)
+ for (int i = packages.count() - 1; i >= 0; --i) {
+ const QInstallerTools::PackageInfo info = packages.at(i);
+ if (!hash.contains(info.name))
+ continue; // the component is not there, keep it
+
+ if (KDUpdater::compareVersion(info.version, hash.value(info.name).version) < 1)
+ packages.remove(i); // the version did not change, no need to update the component
+ }
+
+ if (packages.isEmpty()) {
+ std::cout << QString::fromLatin1("Could not find new components to update '%1'.")
+ .arg(repositoryDir);
+ return EXIT_SUCCESS;
+ }
+ }
+ }
+
+ QHash<QString, QString> pathToVersionMapping = QInstallerTools::buildPathToVersionMapping(packages);
foreach (const QInstallerTools::PackageInfo &package, packages) {
const QFileInfo fi(repositoryDir, package.name);
@@ -207,27 +251,27 @@ int main(int argc, char** argv)
removeDirectory(fi.absoluteFilePath());
}
- copyComponentData(packagesDir, repositoryDir, packages);
-
- TempDirDeleter tmpDeleter;
- const QString metaTmp = createTemporaryDirectory();
- tmpDeleter.add(metaTmp);
-
- generateMetaDataDirectory(metaTmp, repositoryDir, packages, QLatin1String("{AnyApplication}"),
- QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)), redirectUpdateUrl);
- QInstallerTools::compressMetaDirectories(metaTmp, metaTmp, pathToVersionMapping);
+ tmpMetaDir = QInstaller::createTemporaryDirectory();
+ QInstallerTools::copyComponentData(packagesDir, repositoryDir, &packages);
+ QInstallerTools::copyMetaData(tmpMetaDir, repositoryDir, packages, QLatin1String("{AnyApplication}"),
+ QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
+ QInstallerTools::compressMetaDirectories(tmpMetaDir, tmpMetaDir, pathToVersionMapping);
QDirIterator it(repositoryDir, QStringList(QLatin1String("Updates*.xml")), QDir::Files | QDir::CaseSensitive);
while (it.hasNext()) {
it.next();
QFile::remove(it.fileInfo().absoluteFilePath());
}
- moveDirectoryContents(metaTmp, repositoryDir);
- return 0;
+ QInstaller::moveDirectoryContents(tmpMetaDir, repositoryDir);
+ exitCode = EXIT_SUCCESS;
} catch (const Lib7z::SevenZipException &e) {
- std::cerr << "caught 7zip exception: " << e.message() << std::endl;
+ std::cerr << "Caught 7zip exception: " << e.message() << std::endl;
} catch (const QInstaller::Error &e) {
- std::cerr << "caught exception: " << e.message() << std::endl;
+ std::cerr << "Caught exception: " << e.message() << std::endl;
+ } catch (...) {
+ std::cerr << "Unknown exception caught" << std::endl;
}
- return 1;
+
+ QInstaller::removeDirectory(tmpMetaDir, true);
+ return exitCode;
}
diff --git a/tools/repogen/repogen.pro b/tools/repogen/repogen.pro
index 20566d600..7fad2ad96 100644
--- a/tools/repogen/repogen.pro
+++ b/tools/repogen/repogen.pro
@@ -13,3 +13,5 @@ DESTDIR = $$IFW_APP_PATH
SOURCES += repogen.cpp \
../common/repositorygen.cpp
HEADERS += ../common/repositorygen.h
+
+macx:include(../../no_app_bundle.pri)
diff --git a/tools/repogenfromonlinerepo/downloadmanager.cpp b/tools/repogenfromonlinerepo/downloadmanager.cpp
deleted file mode 100644
index ee4e9864f..000000000
--- a/tools/repogenfromonlinerepo/downloadmanager.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "downloadmanager.h"
-
-#include <QFileInfo>
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#include <QString>
-#include <QStringList>
-#include <QTimer>
-#include <stdio.h>
-
-DownloadManager::DownloadManager(QObject *parent)
- : QObject(parent), downloadedCount(0), totalCount(0)
-{
-}
-
-void DownloadManager::append(const QStringList &urlList)
-{
- foreach (QString url, urlList)
- append(QUrl::fromEncoded(url.toLocal8Bit()));
-
- if (downloadQueue.isEmpty())
- QTimer::singleShot(0, this, SIGNAL(finished()));
-}
-
-void DownloadManager::append(const QUrl &url)
-{
- if (downloadQueue.isEmpty())
- QTimer::singleShot(0, this, SLOT(startNextDownload()));
-
- downloadQueue.enqueue(url);
- ++totalCount;
-}
-
-QString DownloadManager::saveFileName(const QUrl &url)
-{
- QString path = url.path();
- QString basename = QFileInfo(path).fileName();
-
- if (basename.isEmpty())
- basename = QLatin1String("download");
-
- if (QFile::exists(basename)) {
- // already exists, rename the old one
- int i = 0;
- while (QFile::exists(basename + QLatin1String(".old_") + QString::number(i)))
- ++i;
-
- QFile::rename(basename, basename + QLatin1String(".old_") + QString::number(i));
- //basename += QString::number(i);
- }
-
- return basename;
-}
-
-void DownloadManager::startNextDownload()
-{
- if (downloadQueue.isEmpty()) {
- printf("%d/%d files downloaded successfully\n", downloadedCount, totalCount);
- emit finished();
- return;
- }
-
- QUrl url = downloadQueue.dequeue();
-
- QString filename = saveFileName(url);
- output.setFileName(filename);
- if (!output.open(QIODevice::WriteOnly)) {
- fprintf(stderr, "Problem opening save file '%s' for download '%s': %s\n",
- qPrintable(filename), url.toEncoded().constData(),
- qPrintable(output.errorString()));
-
- startNextDownload();
- return; // skip this download
- }
-
- QNetworkRequest request(url);
- currentDownload = manager.get(request);
- connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)),
- SLOT(downloadProgress(qint64,qint64)));
- connect(currentDownload, SIGNAL(finished()),
- SLOT(downloadFinished()));
- connect(currentDownload, SIGNAL(readyRead()),
- SLOT(downloadReadyRead()));
-
- // prepare the output
- printf("Downloading %s...\n", url.toEncoded().constData());
- downloadTime.start();
-}
-
-void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- progressBar.setStatus(bytesReceived, bytesTotal);
-
- // calculate the download speed
- double speed = bytesReceived * 1000.0 / downloadTime.elapsed();
- QString unit;
- if (speed < 1024) {
- unit = QLatin1String("bytes/sec");
- } else if (speed < 1024*1024) {
- speed /= 1024;
- unit = QLatin1String("kB/s");
- } else {
- speed /= 1024*1024;
- unit = QLatin1String("MB/s");
- }
-
- progressBar.setMessage(QString::fromLatin1("%1 %2").arg(speed, 3, 'f', 1).arg(unit));
- progressBar.update();
-}
-
-void DownloadManager::downloadFinished()
-{
- progressBar.clear();
- output.close();
-
- if (currentDownload->error()) {
- // download failed
- fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString()));
- } else {
- printf("Succeeded.\n");
- ++downloadedCount;
- }
-
- currentDownload->deleteLater();
- startNextDownload();
-}
-
-void DownloadManager::downloadReadyRead()
-{
- output.write(currentDownload->readAll());
-}
diff --git a/tools/repogenfromonlinerepo/main.cpp b/tools/repogenfromonlinerepo/main.cpp
deleted file mode 100644
index 12023d495..000000000
--- a/tools/repogenfromonlinerepo/main.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-/**************************************************************************
-**
-** Copyright (C) 2012 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 "downloadmanager.h"
-
-#include <QtCore/QCoreApplication>
-#include <QFile>
-#include <QString>
-#include <QDomDocument>
-#include <QDomElement>
-#include <QDomNodeList>
-#include <QStringList>
-#include <QDebug>
-#include <QFileInfo>
-#include <QDir>
-#include <iostream>
-
-static void printUsage()
-{
- const QString appName = QFileInfo( QCoreApplication::applicationFilePath() ).fileName();
- std::cout << "Usage: " << qPrintable(appName) << "--url <repository_url>" << std::endl;
- std::cout << std::endl;
- std::cout << "Example:" << std::endl;
- std::cout << " " << qPrintable(appName) << " someDirectory foobar.7z" << std::endl;
-}
-
-
-int main(int argc, char *argv[])
-{
- QCoreApplication app(argc, argv);
-
- QString repoUrl = QLatin1String("http://www.forum.nokia.com/nokiaqtsdkrepository/oppdatering/windows/"
- "online_ndk_repo");
-
- QStringList args = app.arguments();
- for( QStringList::const_iterator it = args.constBegin(); it != args.constEnd(); ++it )
- {
- if( *it == QString::fromLatin1( "-h" ) || *it == QString::fromLatin1( "--help" ) )
- {
- printUsage();
- return 0;
- }
- else if( *it == QString::fromLatin1( "-u" ) || *it == QString::fromLatin1( "--url" ) )
- {
- ++it;
- if( it == args.end() ) {
-// printUsage();
-// return -1;
- } else {
- repoUrl = *it;
- }
- }
- }
-
- QEventLoop downloadEventLoop;
-
- DownloadManager downloadManager;
-
-// get Updates.xml to get to know what we can download
- downloadManager.append(QUrl(repoUrl + QLatin1String("/Updates.xml")));
- QObject::connect( &downloadManager, SIGNAL( finished() ), &downloadEventLoop, SLOT( quit() ) );
- downloadEventLoop.exec();
-// END - get Updates.xml to get to know what we can download
-
- QFile batchFile(QLatin1String("download.bat"));
- if (!batchFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qDebug() << "can not open " << QFileInfo(batchFile).absoluteFilePath();
- return app.exec();
- }
-
- QTextStream batchFileOut(&batchFile);
-
- const QString updatesXmlPath = QLatin1String("Updates.xml");
-
- Q_ASSERT( !updatesXmlPath.isEmpty() );
- Q_ASSERT( QFile::exists( updatesXmlPath ) );
-
- QFile updatesFile( updatesXmlPath );
- if ( !updatesFile.open( QIODevice::ReadOnly ) ) {
- //qDebug() << QString::fromLatin1("Could not open Updates.xml for reading: %1").arg( updatesFile
- // .errorString() ) ;
- return app.exec();
- }
-
- QDomDocument doc;
- QString err;
- int line = 0;
- int col = 0;
- if ( !doc.setContent( &updatesFile, &err, &line, &col ) ) {
- //qDebug() << QString::fromLatin1("Could not parse component index: %1:%2: %3")
- // .arg(QString::number(line), QString::number( col ), err );
- return app.exec();
- }
-
- const QDomElement root = doc.documentElement();
- const QDomNodeList children = root.childNodes();
- for ( int i = 0; i < children.count(); ++i ) {
- //qDebug() << children.count();
- QString packageName;
- QString packageDisplayName;
- QString packageDescription;
- QString packageUpdateText;
- QString packageVersion;
- QString packageReleaseDate;
- QString packageHash;
- QString packageUserinterfacesAsString;
- QString packageInstallPriority;
- QString packageScript;
- QString packageDependencies;
- QString packageForcedInstallation;
- bool packageIsVirtual = false;
- QString sevenZString;
- const QDomElement el = children.at( i ).toElement();
- if ( el.isNull() )
- continue;
- if ( el.tagName() == QLatin1String("PackageUpdate") ) {
- const QDomNodeList c2 = el.childNodes();
-
- for ( int j = 0; j < c2.count(); ++j ) {
- if ( c2.at( j ).toElement().tagName() == QLatin1String("Name") )
- packageName = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("DisplayName") )
- packageDisplayName = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("Description") )
- packageDescription = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("UpdateText") )
- packageUpdateText = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("Version") )
- packageVersion = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("ReleaseDate") )
- packageReleaseDate = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("SHA1") )
- packageHash = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("UserInterfaces") )
- packageUserinterfacesAsString = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("Script") )
- packageScript = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("Dependencies") )
- packageDependencies = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("ForcedInstallation") )
- packageForcedInstallation = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("InstallPriority") )
- packageInstallPriority = c2.at( j ).toElement().text();
- else if ( c2.at( j ).toElement().tagName() == QLatin1String("Virtual") && c2.at( j )
- .toElement().text() == QLatin1String("true")) {
- packageIsVirtual = true;
- }
- }
- }
- if (packageName.isEmpty()) {
- continue;
- }
-
- if ( !packageScript.isEmpty() ) {
- // get Updates.xml to get to know what we can download
- downloadManager.append(QUrl(repoUrl + QLatin1String("/") + packageName + QLatin1String("/")
- + packageScript));
- QObject::connect( &downloadManager, SIGNAL( finished() ), &downloadEventLoop, SLOT( quit() ) );
- downloadEventLoop.exec();
- // END - get Updates.xml to get to know what we can download
-
- QString localScriptFileName = packageScript;
- Q_ASSERT( QFile::exists( localScriptFileName ) );
-
- QFile file(localScriptFileName);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- //qDebug() << localScriptFileName << " was not readable";
- continue;
- }
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
- if (line.contains(QLatin1String(".7z"))) {
- int firstPosition = line.indexOf(QLatin1String("\""));
- QString subString = line.right(line.count() - firstPosition - 1); //-1 means "
- //qDebug() << subString;
- int secondPosition = subString.indexOf(QLatin1String("\""));
- sevenZString = subString.left(secondPosition);
- //qDebug() << sevenZString;
- break;
- }
- }
- file.remove();
- }
- QStringList packageUserinterfaces = packageUserinterfacesAsString.split(QLatin1String(","));
- packageUserinterfaces.removeAll(QString());
- packageUserinterfaces.removeAll(QLatin1String(""));
-
- QStringList fileList;
-
- //fileList << packageVersion + sevenZString;
- foreach(const QString file, packageUserinterfaces) {
- if(!file.isEmpty()) {
- fileList << file;
- }/* else {
- qDebug() << "There is something wrong with the userinterface string list.";
- return a.exec();
- }*/
- }
- if(!packageScript.isEmpty()) {
- fileList << packageScript;
- }
-
- QFile packagesXml( QString( QCoreApplication::applicationDirPath() + QLatin1String("/")
- + packageName + QLatin1String(".xml")));
- packagesXml.open( QIODevice::WriteOnly );
- QTextStream packageAsXmlStream( &packagesXml );
- packageAsXmlStream << QLatin1String("<?xml version=\"1.0\"?>" ) << endl;
- packageAsXmlStream << QLatin1String("<Package>" ) << endl;
- packageAsXmlStream << QString::fromLatin1(" <DisplayName>%1</DisplayName>").arg(packageDisplayName)
- << endl;
-
- if (!packageDescription.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <Description>%1</Description>" )
- .arg(packageDescription) << endl;
- }
-
- if (!packageUpdateText.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <UpdateText>%1</UpdateText>" )
- .arg(packageUpdateText) << endl;
- }
-
- if (!packageVersion.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <Version>%1</Version>" )
- .arg(packageVersion) << endl;
- }
-
- if (!packageReleaseDate.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <ReleaseDate>%1</ReleaseDate>" )
- .arg(packageReleaseDate) << endl;
- }
- packageAsXmlStream << QString::fromLatin1(" <Name>%1</Name>" ).arg(packageName) << endl;
-
- if (!packageScript.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <Script>%1</Script>" ).arg(packageScript) << endl;
- }
-
- if (packageIsVirtual) {
- packageAsXmlStream << QString::fromLatin1(" <Virtual>true</Virtual>" ) << endl;
- }
-
- if (!packageInstallPriority.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <InstallPriority>%1</InstallPriority>" )
- .arg(packageInstallPriority) << endl;
- }
- if (!packageDependencies.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <Dependencies>%1</Dependencies>" )
- .arg(packageDependencies) << endl;
- }
-
- if (!packageForcedInstallation.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <ForcedInstallation>%1</ForcedInstallation>" )
- .arg(packageForcedInstallation) << endl;
- }
-
- if (!packageUserinterfaces.isEmpty()) {
- packageAsXmlStream << QString::fromLatin1(" <UserInterfaces>" ) << endl;
- foreach(const QString userInterfaceFile, packageUserinterfaces) {
- packageAsXmlStream << QString::fromLatin1(" <UserInterface>%1</UserInterface>" )
- .arg(userInterfaceFile) << endl;
- }
- packageAsXmlStream << QString::fromLatin1(" </UserInterfaces>" ) << endl;
- }
- packageAsXmlStream << QString::fromLatin1("</Package>" ) << endl;
-
- batchFileOut << "rem download line BEGIN =============================================\n";
-
- batchFileOut << "mkdir " << packageName << "\\meta\n";
- batchFileOut << "move " << QDir::toNativeSeparators(QFileInfo(packagesXml).absoluteFilePath()) << " " << packageName << "\\meta\\package.xml\n";
- if (!sevenZString.isEmpty()) {
- batchFileOut << "mkdir " << packageName << "\\data\n";
- batchFileOut << "cd " << packageName << "\\data\n";
- batchFileOut << "wget " << repoUrl << "/" << packageName << "/" << QString(packageVersion + sevenZString) << " -O " << sevenZString << "\n";
- batchFileOut << "cd ..\\..\n";
- }
- batchFileOut << "cd " << packageName << "\\meta\n";
- foreach(const QString file, fileList) {
- batchFileOut << "wget " << repoUrl << "/" << packageName << "/" << file << "\n";
- }
- batchFileOut << "cd ..\\..\n";
-
- batchFileOut << "rem download line END =============================================\n";
- } //for ( int i = 0; i < children.count(); ++i ) {
-
- if ( children.count() == 0 ) {
- qDebug() << "no packages found";
- return app.exec();
- } else {
- qDebug() << "found packages and wrote batch file";
- }
-
-
- return 0;
-}
diff --git a/tools/repogenfromonlinerepo/repogenfromonlinerepo.pro b/tools/repogenfromonlinerepo/repogenfromonlinerepo.pro
deleted file mode 100644
index 0c11efa36..000000000
--- a/tools/repogenfromonlinerepo/repogenfromonlinerepo.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TEMPLATE = app
-INCLUDEPATH += . ..
-TARGET = repogenfromonlinerepo
-
-include(../../installerfw.pri)
-
-QT -= gui
-QT += network
-
-CONFIG += console
-CONFIG -= app_bundle
-DESTDIR = $$IFW_APP_PATH
-
-SOURCES += main.cpp \
- downloadmanager.cpp \
- textprogressbar.cpp
-
-HEADERS += downloadmanager.h \
- textprogressbar.h
diff --git a/tools/tools.pro b/tools/tools.pro
index 51cc5eae6..34b980f92 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -9,7 +9,7 @@ SUBDIRS += \
EXTRASUBDIRS = \
extractbinarydata \
repocompare \
- repogenfromonlinerepo
+ getrepositorycontent
include(../installerfw.pri)