1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
From ccc0dac68ed530e563662a3a5d72b8f05daadf00 Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <rekado@elephly.net>
Date: Sun, 20 Dec 2020 00:25:42 +0100
Subject: [PATCH 6/7] Look at ~/.local/share/rstudio/r-versions for custom R
versions.
---
src/cpp/server_core/RVersionsScanner.cpp | 20 +++++++++++++++++++
.../include/server_core/RVersionsScanner.hpp | 1 +
src/cpp/session/SessionClientInit.cpp | 8 +++++++-
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/src/cpp/server_core/RVersionsScanner.cpp b/src/cpp/server_core/RVersionsScanner.cpp
index 5006ba83af..478e4d7006 100644
--- a/src/cpp/server_core/RVersionsScanner.cpp
+++ b/src/cpp/server_core/RVersionsScanner.cpp
@@ -2,6 +2,7 @@
* RVersionsScanner.cpp
*
* Copyright (C) 2022 by Posit Software, PBC
+ * Copyright (C) 2020-2025 Ricardo Wurmus
*
* Unless you have received this program directly from Posit Software pursuant
* to the terms of a commercial license agreement with Posit Software, then
@@ -138,6 +139,11 @@ void RVersionsScanner::setFallbackVersion()
}
std::vector<r_util::RVersion> RVersionsScanner::getRVersions()
+{
+ return RVersionsScanner::getRVersions(FilePath(""));
+}
+
+std::vector<r_util::RVersion> RVersionsScanner::getRVersions(FilePath userFile)
{
if (!cachedVersions_.empty())
return cachedVersions_;
@@ -174,6 +180,20 @@ std::vector<r_util::RVersion> RVersionsScanner::getRVersions()
}
}
+ if (!userFile.isEmpty() && (userFile.exists()))
+ {
+ std::string contents;
+ Error error = core::readStringFromFile(userFile, &contents, string_utils::LineEndingPosix);
+ if (!error)
+ {
+ parseRVersionsFile(userFile, contents, &rHomeDirs, &rEntries);
+ }
+ else
+ {
+ LOG_ERROR(error);
+ }
+ }
+
// scan for available R versions
using namespace r_util;
std::vector<r_util::RVersion> versions = r_util::enumerateRVersions(
diff --git a/src/cpp/server_core/include/server_core/RVersionsScanner.hpp b/src/cpp/server_core/include/server_core/RVersionsScanner.hpp
index ee06a3d536..1bb653b065 100644
--- a/src/cpp/server_core/include/server_core/RVersionsScanner.hpp
+++ b/src/cpp/server_core/include/server_core/RVersionsScanner.hpp
@@ -45,6 +45,7 @@ public:
// scans for r versions and returns any that were found
// subsequent calls return cached versions found in initial scan
std::vector<r_util::RVersion> getRVersions();
+ std::vector<r_util::RVersion> getRVersions(core::FilePath userFile);
bool detectRVersion(const core::FilePath& rScriptPath,
core::r_util::RVersion* pVersion,
diff --git a/src/cpp/session/SessionClientInit.cpp b/src/cpp/session/SessionClientInit.cpp
index 649f648e25..a63f0942c7 100644
--- a/src/cpp/session/SessionClientInit.cpp
+++ b/src/cpp/session/SessionClientInit.cpp
@@ -577,8 +577,14 @@ void handleClientInit(const boost::function<void()>& initFunction,
sessionInfo["multi_session"] = options.multiSession();
// Read versions from /etc/rstudio/r-versions
+ // ...and read from a user-controlled file
+ FilePath userRDirsPath =
+ options.userScratchPath().completePath("r-versions");
+
json::Array availableRVersionsJson;
- std::vector<r_util::RVersion> versions = RVersionsScanner().getRVersions();
+ std::vector<r_util::RVersion> versions =
+ RVersionsScanner().getRVersions(userRDirsPath);
+
for (r_util::RVersion& rEntry : versions)
{
json::Object rVersionJson;
--
2.52.0
|