1 /* 2 * RVersionSettings.hpp 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 16 #ifndef SESSION_SESSION_RVERSION_SETTINGS_HPP 17 #define SESSION_SESSION_RVERSION_SETTINGS_HPP 18 19 // header-only file for access to r version settings from many contexts 20 21 #include <core/SharedSettings.hpp> 22 23 #include <session/SessionScopes.hpp> 24 25 #define kRVersionSettings "rversion-settings" 26 #define kSettingDefaultRVersion "defaultRVersion" 27 #define kSettingDefaultRVersionHome "defaultRVersionHome" 28 #define kSettingDefaultRVersionLabel "defaultRVersionLabel" 29 #define kRestoreProjectRVersionFlag "restoreProjectRVersion" 30 #define kRVersionSuffix "-RVersion" 31 #define kRVersionHomeSuffix "-RVersionHome" 32 #define kRVersionLabelSuffix "-RVersionLabel" 33 #define kRVersionProjectFile "RVersion" 34 35 namespace rstudio { 36 namespace session { 37 38 class RVersionSettings : public core::SharedSettings 39 { 40 public: RVersionSettings(const core::FilePath & userScratchPath,const core::FilePath & sharedStoragePath)41 explicit RVersionSettings(const core::FilePath& userScratchPath, 42 const core::FilePath& sharedStoragePath) 43 : core::SharedSettings(rVersionSettingsPath(userScratchPath)), 44 userScratchPath_(userScratchPath), 45 sharedStoragePath_(sharedStoragePath) 46 { 47 } 48 defaultRVersion()49 std::string defaultRVersion() 50 { 51 return readSetting(kSettingDefaultRVersion); 52 } 53 defaultRVersionHome()54 std::string defaultRVersionHome() 55 { 56 return readSetting(kSettingDefaultRVersionHome); 57 } 58 defaultRVersionLabel()59 std::string defaultRVersionLabel() 60 { 61 return readSetting(kSettingDefaultRVersionLabel); 62 } 63 setDefaultRVersion(const std::string & version,const std::string & versionHome,const std::string & versionLabel)64 void setDefaultRVersion(const std::string& version, 65 const std::string& versionHome, 66 const std::string& versionLabel) 67 { 68 writeSetting(kSettingDefaultRVersion, version); 69 writeSetting(kSettingDefaultRVersionHome, versionHome); 70 writeSetting(kSettingDefaultRVersionLabel, versionLabel); 71 } 72 restoreProjectRVersion()73 bool restoreProjectRVersion() 74 { 75 return readSetting(kRestoreProjectRVersionFlag) != "0"; 76 } 77 setRestoreProjectRVersion(bool restoreProjectRVersion)78 void setRestoreProjectRVersion(bool restoreProjectRVersion) 79 { 80 writeSetting(kRestoreProjectRVersionFlag, restoreProjectRVersion ? "1" : "0"); 81 } 82 setProjectLastRVersion(const std::string & projectDir,const core::FilePath & sharedProjectScratchPath,const std::string & version,const std::string & versionHome,const std::string & versionLabel)83 void setProjectLastRVersion(const std::string& projectDir, 84 const core::FilePath& sharedProjectScratchPath, 85 const std::string& version, 86 const std::string& versionHome, 87 const std::string& versionLabel) 88 { 89 // get a project id 90 core::r_util::FilePathToProjectId filePathToProjectId = 91 session::filePathToProjectId(userScratchPath_, 92 sharedStoragePath_); 93 core::r_util::ProjectId projectId = filePathToProjectId(projectDir); 94 95 // save the version 96 writeProjectSetting(projectId.asString(), kRVersionSuffix, version); 97 writeProjectSetting(projectId.asString(), kRVersionHomeSuffix, versionHome); 98 writeProjectSetting(projectId.asString(), kRVersionLabelSuffix, versionLabel); 99 100 // save R version in the project itself; used as a hint on preferred R version 101 // when opening a project for the first time on a different machine/container 102 if (!sharedProjectScratchPath.isEmpty()) 103 { 104 writeSettingToPath(sharedProjectScratchPath, kRVersionProjectFile, version); 105 } 106 } 107 readProjectLastRVersion(const std::string & projectDir,const core::FilePath & sharedProjectScratchPath,std::string * pVersion,std::string * pVersionHome,std::string * pVersionLabel)108 void readProjectLastRVersion(const std::string& projectDir, 109 const core::FilePath& sharedProjectScratchPath, 110 std::string* pVersion, 111 std::string* pVersionHome, 112 std::string* pVersionLabel) 113 { 114 // get a project id 115 core::r_util::FilePathToProjectId filePathToProjectId = 116 session::filePathToProjectId(userScratchPath_, 117 sharedStoragePath_); 118 core::r_util::ProjectId projectId = filePathToProjectId(projectDir); 119 120 *pVersion = readProjectSetting(projectId.asString(), 121 kRVersionSuffix); 122 *pVersionHome = readProjectSetting(projectId.asString(), 123 kRVersionHomeSuffix); 124 *pVersionLabel = readProjectSetting(projectId.asString(), 125 kRVersionLabelSuffix); 126 127 // if no local setting for R version, check for hint in .Rproj.user 128 if ((pVersion->empty() || pVersionHome->empty()) && !sharedProjectScratchPath.isEmpty()) 129 { 130 *pVersion = readSettingFromPath(sharedProjectScratchPath, kRVersionProjectFile); 131 pVersionHome->clear(); 132 } 133 } 134 135 private: writeProjectSetting(const std::string & projectId,const char * name,const std::string & value)136 void writeProjectSetting(const std::string& projectId, 137 const char* name, 138 const std::string& value) 139 { 140 writeSetting((projectId + name).c_str(), value); 141 } 142 readProjectSetting(const std::string & projectId,const char * name)143 std::string readProjectSetting(const std::string& projectId, 144 const char* name) 145 146 { 147 return readSetting((projectId + name).c_str()); 148 } 149 150 private: 151 rVersionSettingsPath(const core::FilePath & userScratchPath)152 static core::FilePath rVersionSettingsPath( 153 const core::FilePath& userScratchPath) 154 { 155 using namespace rstudio::core; 156 FilePath settingsPath = userScratchPath.completePath(kRVersionSettings); 157 Error error = settingsPath.ensureDirectory(); 158 if (error) 159 LOG_ERROR(error); 160 161 return settingsPath; 162 } 163 164 core::FilePath userScratchPath_; 165 core::FilePath sharedStoragePath_; 166 }; 167 168 169 } // namespace session 170 } // namespace rstudio 171 172 #endif // SESSION_SESSION_RVERSION_SETTINGS_HPP 173