[education/rkward] rkward: Move appimage detection logic to RKSessionVars
Thomas Friedrichsmeier
null at kde.org
Sat Jun 8 23:21:01 BST 2024
Git commit ab82673c4b4f9a701d0fefe1082882f45831e40e by Thomas Friedrichsmeier.
Committed on 08/06/2024 at 22:10.
Pushed by tfry into branch 'master'.
Move appimage detection logic to RKSessionVars
M +7 -1 rkward/dialogs/rksetupwizard.cpp
M +1 -0 rkward/main.cpp
M +8 -7 rkward/rbackend/rkfrontendtransmitter.cpp
M +9 -0 rkward/rbackend/rksessionvars.cpp
M +3 -0 rkward/rbackend/rksessionvars.h
https://invent.kde.org/education/rkward/-/commit/ab82673c4b4f9a701d0fefe1082882f45831e40e
diff --git a/rkward/dialogs/rksetupwizard.cpp b/rkward/dialogs/rksetupwizard.cpp
index 044a5eb24..b220a97ff 100644
--- a/rkward/dialogs/rksetupwizard.cpp
+++ b/rkward/dialogs/rksetupwizard.cpp
@@ -202,6 +202,7 @@ void RKSetupWizard::setupWizardPhase2() {
// Wait for R Interface, then enable dialog
if (!RInterface::instance()->backendIsIdle()) {
if (RInterface::instance()->backendIsDead()) {
+ // TODO
waiting_to_start_label->setText(i18n("<b>R backend has crashed. Click \"Cancel\" to exit setup assistant.</b>"));
} else {
QTimer::singleShot(100, this, &RKSetupWizard::setupWizardPhase2);
@@ -213,9 +214,14 @@ void RKSetupWizard::setupWizardPhase2() {
waiting_to_start_label->setText(i18n("<b>R backend has started. Click \"Next\" to continue.</b>"));
setValid(firstpageref, true);
- // R packages page
+ // R backend page
// This must be created _after_ the backend has started, for obvious reasons.
createStandardPage();
+ current_layout->addWidget(new QLabel(i18n("R backend info, here")));
+ addPage(current_page, i18n("R Backend"));
+
+ // R packages page
+ createStandardPage();
appendItem(makeRPackageCheck("R2HTML", i18n("The R2HTML package is used by nearly all RKWard output functions, and thus required."), RKSetupWizardItem::Error));
appendItem(makeRPackageCheck("rmarkdown", i18n("The rmarkdown package is required for rendering .Rmd files (including preview rendering), which is an optional but recommended feature."), RKSetupWizardItem::Warning));
diff --git a/rkward/main.cpp b/rkward/main.cpp
index 8029ccbb3..5f1ecb07d 100644
--- a/rkward/main.cpp
+++ b/rkward/main.cpp
@@ -391,6 +391,7 @@ int main (int argc, char *argv[]) {
stream >> urls;
stream >> nowarn;
if (call == QStringLiteral("openAnyUrl")) {
+ // We must not block while the frontend may potentially show a warning message (causing long delay)
QTimer::singleShot(0, main, [nowarn, urls, main]() {
main->openUrlsFromCommandLineOrExternal(nowarn.toBool(), urls.toStringList());
});
diff --git a/rkward/rbackend/rkfrontendtransmitter.cpp b/rkward/rbackend/rkfrontendtransmitter.cpp
index 8b4307e7c..43210b006 100644
--- a/rkward/rbackend/rkfrontendtransmitter.cpp
+++ b/rkward/rbackend/rkfrontendtransmitter.cpp
@@ -64,7 +64,7 @@ bool pathIsChildOf(const QString &parent, const QString &child) {
return QFileInfo(child).canonicalFilePath().startsWith(QFileInfo(parent).canonicalFilePath());
}
-void removeFromPathList (const char* varname, const QString &path) {
+void removeFromPathList (const char* varname, bool (*shouldRemove)(const QString &path)) {
#ifdef Q_OS_WIN
# define PATH_VAR_SEP ';'
#else
@@ -76,7 +76,9 @@ void removeFromPathList (const char* varname, const QString &path) {
const auto list = QString::fromLocal8Bit(var).split(PATH_VAR_SEP);
QStringList newlist;
for(const auto &str : list) {
- if (!pathIsChildOf(path, str)) {
+ if (shouldRemove(str)) {
+ RK_DEBUG(RBACKEND, DL_DEBUG, "Removing path %s from $%s", qPrintable(str), varname);
+ } else {
newlist.append(str);
}
}
@@ -127,11 +129,10 @@ void RKFrontendTransmitter::run () {
if (index >= 0) env.removeAt (index);
env.append ("LANGUAGE=" + QLocale ().name ().section ('_', 0, 0));
- const auto appdir = QString::fromLocal8Bit(qgetenv("APPDIR"));
- if (!appdir.isEmpty() && pathIsChildOf(appdir, RKSessionVars::RBinary())) {
- RK_DEBUG(RBACKEND, DL_DEBUG, "Detected running from AppImage with external R. Removing paths in %s from (LD_LIBRARY_)PATH", qPrintable(appdir));
- removeFromPathList("LD_LIBRARY_PATH", appdir);
- removeFromPathList("PATH", appdir);
+ if (RKSessionVars::runningInAppImage() && RKSessionVars::isPathInAppImage(RKSessionVars::RBinary())) {
+ RK_DEBUG(RBACKEND, DL_DEBUG, "Detected running from AppImage with external R.");
+ removeFromPathList("LD_LIBRARY_PATH", RKSessionVars::isPathInAppImage);
+ removeFromPathList("PATH", RKSessionVars::isPathInAppImage);
}
QStringList args;
diff --git a/rkward/rbackend/rksessionvars.cpp b/rkward/rbackend/rksessionvars.cpp
index dd8fe89fc..b89c683ba 100644
--- a/rkward/rbackend/rksessionvars.cpp
+++ b/rkward/rbackend/rksessionvars.cpp
@@ -18,6 +18,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
#include <QTemporaryFile>
#include <QStandardPaths>
#include <QSysInfo>
+#include <QFileInfo>
#include "../debug.h"
@@ -26,12 +27,15 @@ RKParsedVersion RKSessionVars::rkward_version(RKWARD_VERSION);
RKParsedVersion RKSessionVars::r_version;
QString RKSessionVars::r_version_string;
QString RKSessionVars::r_binary;
+QString RKSessionVars::appimagedir;
RKSessionVars::RKSessionVars (RInterface *parent) : QObject (parent) {
RK_TRACE (RBACKEND);
RK_ASSERT (!_instance);
_instance = this;
+ auto appdir = qgetenv("APPDIR");
+ if (!appdir.isEmpty()) appimagedir = QFileInfo(QString::fromLocal8Bit(appdir)).canonicalFilePath();
}
RKSessionVars::~RKSessionVars () {
@@ -40,6 +44,11 @@ RKSessionVars::~RKSessionVars () {
_instance = nullptr;
}
+bool RKSessionVars::isPathInAppImage(const QString &path) {
+ if (!runningInAppImage()) return false;
+ return QFileInfo(path).canonicalFilePath().startsWith(appimagedir);
+}
+
void RKSessionVars::setInstalledPackages (const QStringList &new_list) {
RK_TRACE (RBACKEND);
diff --git a/rkward/rbackend/rksessionvars.h b/rkward/rbackend/rksessionvars.h
index c60ba3809..e88832d85 100644
--- a/rkward/rbackend/rksessionvars.h
+++ b/rkward/rbackend/rksessionvars.h
@@ -35,6 +35,8 @@ Anything else (everything after the fourth dot, or after the first character tha
is returned as suffix (via the suffix pointer; if that is 0, an error is reported, instead). */
static QStringList frontendSessionInfo ();
static QString RBinary() { return r_binary; }
+ static bool runningInAppImage() { return !appimagedir.isNull(); }
+ static bool isPathInAppImage(const QString &path);
Q_SIGNALS:
void installedPackagesChanged ();
protected:
@@ -48,6 +50,7 @@ private:
static RKParsedVersion rkward_version;
static RKParsedVersion r_version;
static QString r_version_string;
+ static QString appimagedir;
friend int main(int, char**);
friend class RKWardCoreTest;
static QString r_binary;
More information about the rkward-tracker
mailing list