From 1389a860834376d6bdad5bce8ad472c9dfe2cefa Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 11 Feb 2022 13:21:39 +0100 Subject: [PATCH] allow multi package nodejs install --- src/librssguard/miscellaneous/application.cpp | 11 ++- src/librssguard/miscellaneous/application.h | 4 +- src/librssguard/miscellaneous/nodejs.cpp | 90 ++++++++++++------- src/librssguard/miscellaneous/nodejs.h | 10 ++- .../miscellaneous/notification.cpp | 4 +- .../network-web/adblock/adblockmanager.cpp | 19 ++-- .../network-web/adblock/adblockmanager.h | 4 +- 7 files changed, 90 insertions(+), 52 deletions(-) diff --git a/src/librssguard/miscellaneous/application.cpp b/src/librssguard/miscellaneous/application.cpp index 50cc741b9..1c3bd334c 100644 --- a/src/librssguard/miscellaneous/application.cpp +++ b/src/librssguard/miscellaneous/application.cpp @@ -847,20 +847,19 @@ void Application::parseCmdArgumentsFromMyInstance() { } } -void Application::onNodeJsPackageUpdateError(const NodeJs::PackageMetadata& pkg, const QString& error) { +void Application::onNodeJsPackageUpdateError(const QList& pkgs, const QString& error) { qApp->showGuiMessage(Notification::Event::NodePackageUpdated, { {}, - tr("Package %1 was NOT updated to version %2 because of error: %3.").arg(pkg.m_name, - pkg.m_version, - error), + tr("Packages %1 were NOT updated because of error: %3.").arg(NodeJs::packagesToString(pkgs), + error), QSystemTrayIcon::MessageIcon::Critical }); } -void Application::onNodeJsPackageInstalled(const NodeJs::PackageMetadata& pkg, bool already_up_to_date) { +void Application::onNodeJsPackageInstalled(const QList& pkgs, bool already_up_to_date) { if (!already_up_to_date) { qApp->showGuiMessage(Notification::Event::NodePackageUpdated, { {}, - tr("Package %1 was updated to version %2.").arg(pkg.m_name, pkg.m_version), + tr("Packages %1 were updated.").arg(NodeJs::packagesToString(pkgs)), QSystemTrayIcon::MessageIcon::Information }); } } diff --git a/src/librssguard/miscellaneous/application.h b/src/librssguard/miscellaneous/application.h index 0508f421d..78ebb02d0 100644 --- a/src/librssguard/miscellaneous/application.h +++ b/src/librssguard/miscellaneous/application.h @@ -172,8 +172,8 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication { void parseCmdArgumentsFromMyInstance(); private slots: - void onNodeJsPackageUpdateError(const NodeJs::PackageMetadata& pkg, const QString& error); - void onNodeJsPackageInstalled(const NodeJs::PackageMetadata& pkg, bool already_up_to_date); + void onNodeJsPackageUpdateError(const QList& pkgs, const QString& error); + void onNodeJsPackageInstalled(const QList& pkgs, bool already_up_to_date); void onCommitData(QSessionManager& manager); void onSaveState(QSessionManager& manager); void onAboutToQuit(); diff --git a/src/librssguard/miscellaneous/nodejs.cpp b/src/librssguard/miscellaneous/nodejs.cpp index 9fbd1f41c..871b692d8 100644 --- a/src/librssguard/miscellaneous/nodejs.cpp +++ b/src/librssguard/miscellaneous/nodejs.cpp @@ -94,66 +94,94 @@ NodeJs::PackageStatus NodeJs::packageStatus(const PackageMetadata& pkg) const { } } -void NodeJs::installUpdatePackage(const PackageMetadata& pkg) { - auto pkg_status = packageStatus(pkg); +void NodeJs::installUpdatePackages(const QList& pkgs) { + QList to_install; + QStringList desc; - switch (pkg_status) { - case PackageStatus::NotInstalled: - case PackageStatus::OutOfDate: - installPackage(pkg); - break; + for (const PackageMetadata& mt : pkgs) { + auto pkg_status = packageStatus(mt); - case PackageStatus::UpToDate: - qDebugNN << LOGSEC_NODEJS << "Package" << QUOTE_W_SPACE(pkg.m_name) << "is up-to-date."; + switch (pkg_status) { + case PackageStatus::NotInstalled: + case PackageStatus::OutOfDate: + to_install.append(mt); + break; - emit packageInstalledUpdated(pkg, true); + default: + desc << QSL("%1@%2").arg(mt.m_name, mt.m_version); + break; + } + } - break; + if (to_install.isEmpty()) { + qDebugNN << LOGSEC_NODEJS << "Packages" << QUOTE_W_SPACE(desc.join(QL1S(", "))) << "are up-to-date."; + + emit packageInstalledUpdated(pkgs, true); + } + else { + installPackages(pkgs); } } -void NodeJs::installPackage(const PackageMetadata& pkg) { +QString NodeJs::packagesToString(const QList& pkgs) { + QStringList desc; + + for (const PackageMetadata& mt : pkgs) { + desc << QSL("%1@%2").arg(mt.m_name, mt.m_version); + } + + return desc.join(QL1S(", ")); +} + +void NodeJs::installPackages(const QList& pkgs) { + QStringList to_install; + try { + for (const PackageMetadata& mt : pkgs) { + to_install.append(QSL("%1@%2").arg(mt.m_name, mt.m_version)); + } + QProcess* proc = new QProcess(); - connect(proc, QOverload::of(&QProcess::finished), this, [pkg, this](int exit_code, - QProcess::ExitStatus status) { + connect(proc, QOverload::of(&QProcess::finished), + this, [pkgs, this](int exit_code, + QProcess::ExitStatus status) { QProcess* sndr = qobject_cast(sender()); if (exit_code != EXIT_SUCCESS || status == QProcess::ExitStatus::CrashExit) { - qCriticalNN << LOGSEC_NODEJS << "Error when installing package" << QUOTE_W_SPACE_DOT(pkg.m_name) + qCriticalNN << LOGSEC_NODEJS << "Error when installing packages" << QUOTE_W_SPACE_DOT(packagesToString(pkgs)) << " Exit code:" << QUOTE_W_SPACE_DOT(exit_code) << " Message:" << QUOTE_W_SPACE_DOT(sndr->readAllStandardError()); - emit packageError(pkg, sndr->errorString()); + emit packageError(pkgs, sndr->errorString()); } else { - qDebugNN << LOGSEC_NODEJS << "Installed/updated package" << QUOTE_W_SPACE(pkg.m_name) - << "with version" << QUOTE_W_SPACE_DOT(pkg.m_version); - emit packageInstalledUpdated(pkg, false); + qDebugNN << LOGSEC_NODEJS << "Installed/updated packages" << QUOTE_W_SPACE(packagesToString(pkgs)); + emit packageInstalledUpdated(pkgs, false); } }); - connect(proc, &QProcess::errorOccurred, this, [pkg, this](QProcess::ProcessError error) { + connect(proc, &QProcess::errorOccurred, this, [pkgs, this](QProcess::ProcessError error) { QProcess* sndr = qobject_cast(sender()); - qCriticalNN << LOGSEC_NODEJS << "Error when installing package" << QUOTE_W_SPACE_DOT(pkg.m_name) + qCriticalNN << LOGSEC_NODEJS << "Error when installing packages" << QUOTE_W_SPACE_DOT(packagesToString(pkgs)) << " Message:" << QUOTE_W_SPACE_DOT(error); - emit packageError(pkg, sndr->errorString()); + emit packageError(pkgs, sndr->errorString()); }); - qDebugNN << LOGSEC_NODEJS << "Installing package" << QUOTE_W_SPACE_DOT(pkg.m_name); + qDebugNN << LOGSEC_NODEJS << "Installing packages" << QUOTE_W_SPACE_DOT(packagesToString(pkgs)); - IOFactory::startProcess(proc, - npmExecutable(), - { QSL("install"), QSL("--production"), - QSL("%1@%2").arg(pkg.m_name, pkg.m_version), - QSL("--prefix"), processedPackageFolder() }); + to_install.prepend(QSL("--production")); + to_install.prepend(QSL("install")); + to_install.append(QSL("--prefix")); + to_install.append(processedPackageFolder()); + + IOFactory::startProcess(proc, npmExecutable(), to_install); } catch (const ProcessException& ex) { - qCriticalNN << LOGSEC_NODEJS << "Package" << QUOTE_W_SPACE(pkg.m_name) - "was not installed, error:" << QUOTE_W_SPACE_DOT(ex.message()); + qCriticalNN << LOGSEC_NODEJS << "Packages" << QUOTE_W_SPACE(to_install) + << "were not installed, error:" << QUOTE_W_SPACE_DOT(ex.message()); - emit packageError(pkg, ex.message()); + emit packageError(pkgs, ex.message()); } } diff --git a/src/librssguard/miscellaneous/nodejs.h b/src/librssguard/miscellaneous/nodejs.h index b1116744e..cbfa885c5 100644 --- a/src/librssguard/miscellaneous/nodejs.h +++ b/src/librssguard/miscellaneous/nodejs.h @@ -62,14 +62,16 @@ class NodeJs : public QObject { // If package IS installed but out-of-date, it is updated to desired versions. // // NOTE: https://docs.npmjs.com/cli/v8/commands/npm-install - void installUpdatePackage(const PackageMetadata& pkg); + void installUpdatePackages(const QList& pkgs); + + static QString packagesToString(const QList& pkgs); signals: - void packageError(const PackageMetadata& pkg, const QString& error); - void packageInstalledUpdated(const PackageMetadata& pkg, bool already_up_to_date); + void packageError(const QList& pkgs, const QString& error); + void packageInstalledUpdated(const QList& pkgs, bool already_up_to_date); private: - void installPackage(const PackageMetadata& pkg); + void installPackages(const QList& pkgs); Settings* m_settings; }; diff --git a/src/librssguard/miscellaneous/notification.cpp b/src/librssguard/miscellaneous/notification.cpp index 564ec8603..235a54778 100644 --- a/src/librssguard/miscellaneous/notification.cpp +++ b/src/librssguard/miscellaneous/notification.cpp @@ -146,10 +146,10 @@ QString Notification::nameForEvent(Notification::Event event) { return QObject::tr("Miscellaneous events"); case Notification::Event::NodePackageUpdated: - return QObject::tr("Node.js - package updated"); + return QObject::tr("Node.js - package(s) updated"); case Notification::Event::NodePackageFailedToUpdate: - return QObject::tr("Node.js - package failed to updated"); + return QObject::tr("Node.js - package(s) failed to updated"); default: return QObject::tr("Unknown event"); diff --git a/src/librssguard/network-web/adblock/adblockmanager.cpp b/src/librssguard/network-web/adblock/adblockmanager.cpp index 5171c199d..9c56f6c26 100644 --- a/src/librssguard/network-web/adblock/adblockmanager.cpp +++ b/src/librssguard/network-web/adblock/adblockmanager.cpp @@ -2,6 +2,7 @@ #include "network-web/adblock/adblockmanager.h" +#include "3rd-party/boolinq/boolinq.h" #include "exceptions/applicationexception.h" #include "exceptions/networkexception.h" #include "miscellaneous/application.h" @@ -103,7 +104,7 @@ void AdBlockManager::setEnabled(bool enabled) { if (m_enabled) { if (!m_installing) { m_installing = true; - qApp->nodejs()->installUpdatePackage({ QSL(CLIQZ_ADBLOCKED_PACKAGE), QSL(CLIQZ_ADBLOCKED_VERSION) }); + qApp->nodejs()->installUpdatePackages({ { QSL(CLIQZ_ADBLOCKED_PACKAGE), QSL(CLIQZ_ADBLOCKED_VERSION) } }); } } else { @@ -175,10 +176,14 @@ void AdBlockManager::showDialog() { AdBlockDialog(qApp->mainFormWidget()).exec(); } -void AdBlockManager::onPackageReady(const NodeJs::PackageMetadata& pkg, bool already_up_to_date) { +void AdBlockManager::onPackageReady(const QList& pkgs, bool already_up_to_date) { Q_UNUSED(already_up_to_date) - if (pkg.m_name == QSL(CLIQZ_ADBLOCKED_PACKAGE)) { + bool concerns_adblock = boolinq::from(pkgs).any([](const NodeJs::PackageMetadata& pkg) { + return pkg.m_name == QSL(CLIQZ_ADBLOCKED_PACKAGE); + }); + + if (concerns_adblock) { m_installing = false; if (m_enabled) { @@ -197,8 +202,12 @@ void AdBlockManager::onPackageReady(const NodeJs::PackageMetadata& pkg, bool alr } } -void AdBlockManager::onPackageError(const NodeJs::PackageMetadata& pkg, const QString& error) { - if (pkg.m_name == QSL(CLIQZ_ADBLOCKED_PACKAGE)) { +void AdBlockManager::onPackageError(const QList& pkgs, const QString& error) { + bool concerns_adblock = boolinq::from(pkgs).any([](const NodeJs::PackageMetadata& pkg) { + return pkg.m_name == QSL(CLIQZ_ADBLOCKED_PACKAGE); + }); + + if (concerns_adblock) { m_installing = false; m_enabled = false; diff --git a/src/librssguard/network-web/adblock/adblockmanager.h b/src/librssguard/network-web/adblock/adblockmanager.h index 5eaac48d0..f1e185a87 100644 --- a/src/librssguard/network-web/adblock/adblockmanager.h +++ b/src/librssguard/network-web/adblock/adblockmanager.h @@ -71,8 +71,8 @@ class AdBlockManager : public QObject { void processTerminated(); private slots: - void onPackageReady(const NodeJs::PackageMetadata& pkg, bool already_up_to_date); - void onPackageError(const NodeJs::PackageMetadata& pkg, const QString& error); + void onPackageReady(const QList& pkgs, bool already_up_to_date); + void onPackageError(const QList& pkgs, const QString& error); void onServerProcessFinished(int exit_code, QProcess::ExitStatus exit_status); private: