[education/rkward] rkward: Fix failure to restart backend, while inside R tempdir()
Thomas Friedrichsmeier
null at kde.org
Fri Jul 5 16:33:16 BST 2024
Git commit 3a7924b9ff6b61a7f46023c651afd9ea46c19ed5 by Thomas Friedrichsmeier.
Committed on 05/07/2024 at 15:32.
Pushed by tfry into branch 'master'.
Fix failure to restart backend, while inside R tempdir()
M +1 -0 rkward/autotests/core_test.cpp
M +7 -4 rkward/rbackend/rkfrontendtransmitter.cpp
M +9 -5 rkward/rbackend/rkrinterface.cpp
M +1 -7 rkward/rkward.cpp
https://invent.kde.org/education/rkward/-/commit/3a7924b9ff6b61a7f46023c651afd9ea46c19ed5
diff --git a/rkward/autotests/core_test.cpp b/rkward/autotests/core_test.cpp
index 664a9bfc4..5a22b6f28 100644
--- a/rkward/autotests/core_test.cpp
+++ b/rkward/autotests/core_test.cpp
@@ -464,6 +464,7 @@ private Q_SLOTS:
}
void restartRBackend() {
+ RInterface::issueCommand(new RCommand("setwd(tempdir())", RCommand::User)); // retart used to fail, if in non-existant directory
RInterface::issueCommand(new RCommand("x <- 1", RCommand::User));
waitForAllFinished();
QVERIFY(RObjectList::getGlobalEnv()->findObject("x"));
diff --git a/rkward/rbackend/rkfrontendtransmitter.cpp b/rkward/rbackend/rkfrontendtransmitter.cpp
index 13cb721fd..019386352 100644
--- a/rkward/rbackend/rkfrontendtransmitter.cpp
+++ b/rkward/rbackend/rkfrontendtransmitter.cpp
@@ -234,7 +234,7 @@ void RKFrontendTransmitter::run () {
env.append(QStringLiteral("RK_BACKEND_LIB=") + backend_lib);
# else
env.append(QStringLiteral("RK_BACKEND_LIB=") + QFileInfo(backend_lib).fileName());
- QTemporaryDir rkward_only_dir("rkward_only");
+ QTemporaryDir rkward_only_dir(QDir::tempPath() + "/rkward_only");
QFile(QFileInfo(backend_lib).absolutePath()).link(rkward_only_dir.filePath("_rkward_only_dlpath"));
env.append(QStringLiteral("RK_ADD_LDPATH=./_rkward_only_dlpath"));
env.append(QStringLiteral("RK_LD_CWD=") + rkward_only_dir.path());
@@ -242,9 +242,12 @@ void RKFrontendTransmitter::run () {
#endif
backend->setEnvironment(env);
-#ifdef Q_OS_WIN
- // Needed for paths with spaces. R CMD is too simple to deal with those, even if we provide proper quoting.
- // So rather we need to work from a relative path with all spaces eliminated
+#ifndef Q_OS_MACOS
+ // Needed on for paths with spaces. R CMD is too simple to deal with those, even if we provide proper quoting.
+ // So rather we need to work from a relative path with all spaces eliminated.
+ // However, also, we might start in directory that no longer exists, or will cease to exist, in a second
+ // (e.g. the tempdir() of the previous R session). So we set something known to exist, here.
+ // On MacOS, we cd to R_HOME, instead, below
QFileInfo bfi(backend_executable);
backend->setWorkingDirectory(bfi.absolutePath());
args.append(bfi.fileName());
diff --git a/rkward/rbackend/rkrinterface.cpp b/rkward/rbackend/rkrinterface.cpp
index c20b91f1c..0503ba8c5 100644
--- a/rkward/rbackend/rkrinterface.cpp
+++ b/rkward/rbackend/rkrinterface.cpp
@@ -437,10 +437,6 @@ void RInterface::handleRequest (RBackendRequest* request) {
// initialize output file
RKOutputDirectory::getCurrentOutput(chain);
-#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
- // On MacOS and Windows, the backend is started with different working directories set, for hackish reasons (see rkfrontendtransmitter.cpp). Fix that, here.
- runStartupCommand(new RCommand("setwd (" + RKRSharedFunctionality::quote(QDir::currentPath()) + ")\n", RCommand::App | RCommand::Sync), chain, runtimeopt_callback);
-#endif
// Workaround for https://bugs.kde.org/show_bug.cgi?id=421958
if (RKSessionVars::compareRVersion("4.0.0") < 1 && RKSessionVars::compareRVersion("4.0.1") > 0) {
runStartupCommand(new RCommand("if(compiler::enableJIT(-1) > 2) compiler::enableJIT(2)\n", RCommand::App | RCommand::Sync), chain, runtimeopt_callback);
@@ -456,6 +452,14 @@ void RInterface::handleRequest (RBackendRequest* request) {
RK_ASSERT (command->getDataLength () == 1);
RKSettingsModuleR::help_base_url = command->stringVector ().value (0);
});
+
+ QString cd_to = RKSettingsModuleGeneral::initialWorkingDirectory();
+ cd_to = QDir::currentPath();
+ if (cd_to.isEmpty()) { // we must be in a non-existent dir. The backend will know better...
+ RInterface::issueCommand(new RCommand("setwd(\".\")\n", RCommand::App | RCommand::Sync), chain);
+ } else {
+ RInterface::issueCommand(new RCommand("setwd(" + RObject::rQuote(cd_to) + ")\n", RCommand::App | RCommand::Sync), chain);
+ }
} else {
processRBackendRequest (request);
}
@@ -666,7 +670,7 @@ GenericRRequestResult RInterface::processRCallRequest (const QString &call, cons
RK_ASSERT(arglist.count () == 1);
RKOutputWindowManager::self()->setCurrentOutputPath(arglist.value(0));
} else if (call == "wdChange") {
- // in case of separate processes, apply new working directory in frontend, too.
+ // apply new working directory in frontend, too.
QDir::setCurrent(arglist.value(0));
Q_EMIT backendWorkdirChanged();
} else if (call == "highlightRCode") {
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index d6f911a20..77efc710a 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -255,12 +255,6 @@ void RKWardMainWindow::doPostInit () {
open_urls[i] = url.url ();
}
- QString cd_to = RKSettingsModuleGeneral::initialWorkingDirectory ();
- if (!cd_to.isEmpty ()) {
- RInterface::issueCommand ("setwd (" + RObject::rQuote (cd_to) + ")\n", RCommand::App);
- QDir::setCurrent (cd_to);
- }
-
if (!open_urls.isEmpty()) {
// this is also done when there are no urls specified on the command line. But in that case _after_ loading any workspace, so
// the help window will be on top
@@ -288,7 +282,6 @@ void RKWardMainWindow::doPostInit () {
if (!evaluate_code.isEmpty ()) RKConsole::pipeUserCommand (evaluate_code);
updateCWD ();
- connect (RInterface::instance(), &RInterface::backendWorkdirChanged, this, &RKWardMainWindow::updateCWD);
setCaption (QString ()); // our version of setCaption takes care of creating a correct caption, so we do not need to provide it here
}
@@ -400,6 +393,7 @@ void RKWardMainWindow::startR () {
RInterface::create();
Q_EMIT backendCreated();
connect(RInterface::instance(), &RInterface::backendStatusChanged, this, &RKWardMainWindow::setRStatus);
+ connect(RInterface::instance(), &RInterface::backendWorkdirChanged, this, &RKWardMainWindow::updateCWD);
RObjectList::init();
RObjectBrowser::mainBrowser ()->unlock ();
More information about the rkward-tracker
mailing list