Mercurial > hg > vamp-plugin-pack
diff installer.cpp @ 97:b5230bda1f1f
The RDF versions are too unreliable, nobody ever remembers to update them. Pull the bundled versions from the actual bundled libraries instead
author | Chris Cannam |
---|---|
date | Fri, 28 Feb 2020 10:41:54 +0000 |
parents | 24d64a983fc8 |
children | fb4ca43863b5 |
line wrap: on
line diff
--- a/installer.cpp Fri Feb 28 08:57:15 2020 +0000 +++ b/installer.cpp Fri Feb 28 10:41:54 2020 +0000 @@ -145,7 +145,6 @@ QString description; QString page; QStringList pluginTitles; - map<QString, int> pluginVersions; // id -> version QString licence; }; @@ -284,21 +283,6 @@ if (ptitle.type == Node::Literal) { info.pluginTitles.push_back(ptitle.value); } - - Node pident = store.complete(Triple(p.object(), - store.expand("vamp:identifier"), - Node())); - Node pversion = store.complete(Triple(p.object(), - store.expand("owl:versionInfo"), - Node())); - if (pident.type == Node::Literal && - pversion.type == Node::Literal) { - bool ok = false; - int version = pversion.value.toInt(&ok); - if (ok) { - info.pluginVersions[pident.value] = version; - } - } } info.licence = identifyLicence(libId.value); @@ -325,6 +309,57 @@ QString tempFile; }; +bool +unbundleFile(QString filePath, QString targetPath, bool isExecutable) +{ + SVCERR << "Copying " << filePath.toStdString() << " to " + << targetPath.toStdString() << "..." << endl; + + // This has to be able to work even if the destination exists, and + // to do so without deleting it first - e.g. when copying to a + // temporary file. So we open the file and copy to it ourselves + // rather than use QFile::copy + + QFile source(filePath); + if (!source.open(QFile::ReadOnly)) { + SVCERR << "ERROR: Failed to read bundled file " << filePath << endl; + return {}; + } + QByteArray content = source.readAll(); + source.close(); + + QFile target(targetPath); + if (!target.open(QFile::WriteOnly)) { + SVCERR << "ERROR: Failed to read target file " << targetPath << endl; + return {}; + } + if (target.write(content) != content.size()) { + SVCERR << "ERROR: Incomplete write to target file" << endl; + return {}; + } + target.close(); + + auto permissions = + QFile::ReadOwner | QFile::WriteOwner | + QFile::ReadGroup | + QFile::ReadOther; + + if (isExecutable) { + permissions |= + QFile::ExeOwner | + QFile::ExeGroup | + QFile::ExeOther; + }; + + if (!QFile::setPermissions(targetPath, permissions)) { + SVCERR << "Failed to set permissions on " + << targetPath.toStdString() << endl; + return false; + } + + return true; +} + map<QString, int> getLibraryPluginVersions(QString libraryFilePath) { @@ -356,29 +391,14 @@ QString helperPath = ":out/get-version.exe"; #else QString helperPath = ":out/get-version"; -#endif - QFile helper(helperPath); - if (!helper.open(QFile::ReadOnly)) { - SVCERR << "ERROR: Failed to read helper code" << endl; +#endif + + tempFile.close(); + if (!unbundleFile(helperPath, tempFileName, true)) { + SVCERR << "ERROR: Failed to unbundle helper code" << endl; return {}; } - QByteArray content = helper.readAll(); - helper.close(); - if (tempFile.write(content) != content.size()) { - SVCERR << "ERROR: Incomplete write to temporary file" << endl; - return {}; - } - tempFile.close(); - - if (!QFile::setPermissions - (tempFileName, - QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner)) { - SVCERR << "ERROR: Failed to set execute permission on helper " - << tempFileName << endl; - return {}; - } - initSucceeded = true; } @@ -435,6 +455,36 @@ return versions; } +map<QString, int> +getBundledLibraryPluginVersions(QString libraryFileName) +{ + QString tempFileName; + TempFileDeleter deleter; + + { + QTemporaryFile tempFile; + tempFile.setAutoRemove(false); + if (!tempFile.open()) { + SVCERR << "ERROR: Failed to open a temporary file" << endl; + return {}; + } + + // We can't use QTemporaryFile's auto-remove, as it will hold + // the file open and that prevents us from executing it. Hence + // the separate deleter. + + tempFileName = tempFile.fileName(); + deleter.tempFile = tempFileName; + tempFile.close(); + } + + if (!unbundleFile(":out/" + libraryFileName, tempFileName, true)) { + return {}; + } + + return getLibraryPluginVersions(tempFileName); +} + bool isLibraryNewer(map<QString, int> a, map<QString, int> b) { // a and b are maps from plugin id to plugin version for libraries @@ -522,31 +572,32 @@ { QString destination = targetDir + "/" + info.fileName; - RelativeStatus status = RelativeStatus::New; - SVCERR << "\ngetRelativeStatus: " << info.fileName << ":\n"; - if (QFileInfo(destination).exists()) { + if (!QFileInfo(destination).exists()) { + SVCERR << " - relative status: " << relativeStatusLabel(RelativeStatus::New) << endl; + return RelativeStatus::New; + } - auto installed = getLibraryPluginVersions(destination); + RelativeStatus status = RelativeStatus::Same; - SVCERR << " * installed: " << versionsString(installed) - << "\n * packaged: " << versionsString(info.pluginVersions) - << endl; + auto packaged = getBundledLibraryPluginVersions(info.fileName); + auto installed = getLibraryPluginVersions(destination); - status = RelativeStatus::Same; + SVCERR << " * installed: " << versionsString(installed) + << "\n * packaged: " << versionsString(packaged) + << endl; - if (installed.empty()) { - status = RelativeStatus::TargetNotLoadable; - } + if (installed.empty()) { + status = RelativeStatus::TargetNotLoadable; + } - if (isLibraryNewer(installed, info.pluginVersions)) { - status = RelativeStatus::Downgrade; - } + if (isLibraryNewer(installed, packaged)) { + status = RelativeStatus::Downgrade; + } - if (isLibraryNewer(info.pluginVersions, installed)) { - status = RelativeStatus::Upgrade; - } + if (isLibraryNewer(packaged, installed)) { + status = RelativeStatus::Upgrade; } SVCERR << " - relative status: " << relativeStatusLabel(status) << endl; @@ -584,7 +635,6 @@ { QString library = info.fileName; QString source = ":out"; - QFile f(source + "/" + library); QString destination = targetDir + "/" + library; static QString backupDirName; @@ -605,24 +655,11 @@ if (!backup(destination, backupDir)) { return QObject::tr("Failed to move aside existing library"); } + + if (!unbundleFile(source + "/" + library, destination, true)) { + return QObject::tr("Failed to copy library file to target directory"); + } - SVCERR << "Copying " << library.toStdString() << " to " - << destination.toStdString() << "..." << endl; - if (!f.copy(destination)) { - SVCERR << "Failed to copy " << library.toStdString() - << " to target " << destination.toStdString() << endl; - return QObject::tr("Failed to copy library to destination directory"); - } - if (!QFile::setPermissions - (destination, - QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | - QFile::ReadGroup | QFile::ExeGroup | - QFile::ReadOther | QFile::ExeOther)) { - SVCERR << "Failed to set permissions on " - << library.toStdString() << endl; - return QObject::tr("Failed to set correct permissions on installed library"); - } - QString base = QFileInfo(library).baseName(); QDir dir(source); auto entries = dir.entryList({ base + "*" }); @@ -632,22 +669,7 @@ if (!backup(destination, backupDir)) { continue; } - SVCERR << "Copying " << e.toStdString() << " to " - << destination.toStdString() << "..." << endl; - if (!QFile(source + "/" + e).copy(destination)) { - SVCERR << "Failed to copy " << e.toStdString() - << " to target " << destination.toStdString() - << " (ignoring)" << endl; - continue; - } - if (!QFile::setPermissions - (destination, - QFile::ReadOwner | QFile::WriteOwner | - QFile::ReadGroup | - QFile::ReadOther)) { - SVCERR << "Failed to set permissions on " - << destination.toStdString() - << " (ignoring)" << endl; + if (!unbundleFile(source + "/" + e, destination, false)) { continue; } }