diff options
Diffstat (limited to 'tools/repogen/repogen.cpp')
-rw-r--r-- | tools/repogen/repogen.cpp | 126 |
1 files changed, 85 insertions, 41 deletions
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; } |