allow multi package nodejs install

This commit is contained in:
Martin Rotter 2022-02-11 13:21:39 +01:00
parent d21520f28a
commit 1389a86083
7 changed files with 90 additions and 52 deletions

View file

@ -847,20 +847,19 @@ void Application::parseCmdArgumentsFromMyInstance() {
}
}
void Application::onNodeJsPackageUpdateError(const NodeJs::PackageMetadata& pkg, const QString& error) {
void Application::onNodeJsPackageUpdateError(const QList<NodeJs::PackageMetadata>& 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,
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<NodeJs::PackageMetadata>& 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 });
}
}

View file

@ -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<NodeJs::PackageMetadata>& pkgs, const QString& error);
void onNodeJsPackageInstalled(const QList<NodeJs::PackageMetadata>& pkgs, bool already_up_to_date);
void onCommitData(QSessionManager& manager);
void onSaveState(QSessionManager& manager);
void onAboutToQuit();

View file

@ -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<PackageMetadata>& pkgs) {
QList<PackageMetadata> to_install;
QStringList desc;
for (const PackageMetadata& mt : pkgs) {
auto pkg_status = packageStatus(mt);
switch (pkg_status) {
case PackageStatus::NotInstalled:
case PackageStatus::OutOfDate:
installPackage(pkg);
to_install.append(mt);
break;
case PackageStatus::UpToDate:
qDebugNN << LOGSEC_NODEJS << "Package" << QUOTE_W_SPACE(pkg.m_name) << "is up-to-date.";
emit packageInstalledUpdated(pkg, true);
default:
desc << QSL("%1@%2").arg(mt.m_name, mt.m_version);
break;
}
}
void NodeJs::installPackage(const PackageMetadata& pkg) {
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);
}
}
QString NodeJs::packagesToString(const QList<PackageMetadata>& 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<PackageMetadata>& 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<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [pkg, this](int exit_code,
connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, [pkgs, this](int exit_code,
QProcess::ExitStatus status) {
QProcess* sndr = qobject_cast<QProcess*>(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<QProcess*>(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());
}
}

View file

@ -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<PackageMetadata>& pkgs);
static QString packagesToString(const QList<PackageMetadata>& pkgs);
signals:
void packageError(const PackageMetadata& pkg, const QString& error);
void packageInstalledUpdated(const PackageMetadata& pkg, bool already_up_to_date);
void packageError(const QList<PackageMetadata>& pkgs, const QString& error);
void packageInstalledUpdated(const QList<PackageMetadata>& pkgs, bool already_up_to_date);
private:
void installPackage(const PackageMetadata& pkg);
void installPackages(const QList<PackageMetadata>& pkgs);
Settings* m_settings;
};

View file

@ -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");

View file

@ -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<NodeJs::PackageMetadata>& 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<NodeJs::PackageMetadata>& 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;

View file

@ -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<NodeJs::PackageMetadata>& pkgs, bool already_up_to_date);
void onPackageError(const QList<NodeJs::PackageMetadata>& pkgs, const QString& error);
void onServerProcessFinished(int exit_code, QProcess::ExitStatus exit_status);
private: