From 3bd91a6c202c356eca7364282d9213aba3bf9924 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 16 Oct 2024 10:21:26 -0700 Subject: [PATCH] add 'getMode' --- NAMESPACE | 1 + NEWS.md | 3 ++ R/code.R | 107 +++++++++++++++++++++++++--------------------- man/getMode.Rd | 16 +++++++ man/getVersion.Rd | 18 +++----- 5 files changed, 83 insertions(+), 62 deletions(-) create mode 100644 man/getMode.Rd diff --git a/NAMESPACE b/NAMESPACE index 2d584aa..5934340 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -42,6 +42,7 @@ export(getActiveDocumentContext) export(getActiveProject) export(getConsoleEditorContext) export(getDelegatedAzureToken) +export(getMode) export(getPersistentValue) export(getRStudioPackageDependencies) export(getSourceEditorContext) diff --git a/NEWS.md b/NEWS.md index 77d8d4b..0cb57d2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,9 @@ # rstudioapi (under development) +* Added `getMode()`, which can be used to differentiate between Desktop + and Server installations of RStudio. (#280) + # rstudioapi 0.16.0 * `restartSession()` gains the `clean` argument, for RStudio 2024.04 diff --git a/R/code.R b/R/code.R index d1c59dd..ec1f7e7 100644 --- a/R/code.R +++ b/R/code.R @@ -1,25 +1,25 @@ #' Check if RStudio is running -#' +#' #' Check if RStudio is running. -#' +#' #' @aliases isAvailable verifyAvailable -#' +#' #' @param version_needed An optional version specification. If supplied, ensures #' that RStudio is at least that version. -#' +#' #' @param child_ok Boolean; check if the current R process is a child process of #' the main RStudio session? This can be useful for e.g. RStudio Jobs, where #' you'd like to communicate back with the main R session from a child process #' through \code{rstudioapi}. -#' +#' #' @return \code{isAvailable} a boolean; \code{verifyAvailable} an error message #' if RStudio is not running -#' +#' #' @examples -#' +#' #' rstudioapi::isAvailable() #' \dontrun{rstudioapi::verifyAvailable()} -#' +#' #' @export isAvailable <- function(version_needed = NULL, child_ok = FALSE) { @@ -27,12 +27,12 @@ isAvailable <- function(version_needed = NULL, child_ok = FALSE) { return(callRemote(sys.call(), parent.frame())) identical(.Platform$GUI, "RStudio") && version_ok(version_needed) - + } version_ok <- function(version = NULL) { if (is.null(version)) return(TRUE) - + getVersion() >= version } @@ -41,87 +41,96 @@ version_ok <- function(version = NULL) { verifyAvailable <- function(version_needed = NULL) { if (!isAvailable()) stop("RStudio not running", call. = FALSE) if (!version_ok(version_needed)) { - stop("Need at least version ", version_needed, " of RStudio. ", + stop("Need at least version ", version_needed, " of RStudio. ", "Currently running ", getVersion(), call. = FALSE) } - invisible(TRUE) + invisible(TRUE) } -#' Return the current version of the RStudio API +#' Determine the version of RStudio +#' +#' Use `getVersion()` to determine the current version of RStudio. +#' This can be useful for \R packages which need to gate certain functionality +#' based on the version of RStudio currently available. +#' +#' @returns A `"numeric_version"` object, giving the version of RStudio in use. #' -#' Return the current version of the RStudio API -#' -#' -#' @return A \code{\link{numeric_version}} which you can compare to a string -#' and get correct results. -#' @examples -#' -#' \dontrun{ -#' if (rstudioapi::getVersion() < "0.98.100") { -#' message("Your version of RStudio is quite old") -#' } -#' } -#' -#' @export getVersion +#' @export getVersion <- function() { verifyAvailable() - callFun("versionInfo")$version + + base <- .BaseNamespaceEnv + version <- base$.Call("rs_rstudioVersion", PACKAGE = "(embedding)") + package_version(version) } - +#' Report whether RStudio Desktop or RStudio Server is in use +#' +#' Use `getMode()` if you need to differentiate between server +#' and desktop installations of RStudio. +#' +#' @returns "desktop" for RStudio Desktop installations, and +#' "server" for RStudio Server / RStudio Workbench installations. +#' +#' @export +getMode <- function() { + verifyAvailable() + rstudio <- as.environment("tools:rstudio") + if (rstudio$.rs.isDesktop()) "desktop" else "server" +} #' Call an RStudio API function -#' +#' #' This function will return an error if RStudio is not running, or the #' function is not available. If you want to fall back to different behavior, #' use \code{\link{hasFun}}. -#' -#' +#' +#' #' @param fname name of the RStudio function to call. #' @param ... Other arguments passed on to the function #' @examples -#' +#' #' if (rstudioapi::isAvailable()) { #' rstudioapi::callFun("versionInfo") #' } -#' +#' #' @export callFun callFun <- function(fname, ...) { - + if (isJob()) return(callRemote(sys.call(), parent.frame())) - + verifyAvailable() - + # get reference to RStudio function f <- tryCatch(findFun(fname, mode = "function"), error = identity) if (inherits(f, "error")) stop("Function ", fname, " not found in RStudio", call. = FALSE) - + # drop arguments that aren't accepted by RStudio # (ensure backwards-compatibility with older versions of RStudio) args <- list(...) if (!"..." %in% names(formals(f))) if (length(args) > length(formals(f))) length(args) <- length(formals(f)) - + # invoke the function do.call(f, args) - + } #' Exists/get for RStudio functions -#' +#' #' These are specialized versions of \code{\link[base]{get}} and #' \code{\link[base]{exists}} that look in the rstudio package namespace. If #' RStudio is not running, \code{hasFun} will return \code{FALSE}. -#' -#' +#' +#' #' @aliases hasFun findFun #' @param name name of object to look for #' @param version_needed An optional version specification. If supplied, @@ -130,20 +139,20 @@ callFun <- function(fname, ...) { #' @param ... other arguments passed on to \code{\link[base]{exists}} and #' \code{\link[base]{get}} #' @examples -#' +#' #' rstudioapi::hasFun("viewer") -#' +#' #' @export hasFun hasFun <- function(name, version_needed = NULL, ...) { - + if (!isAvailable(version_needed)) return(FALSE) - + if (usingTools()) return(exists(toolsName(name), toolsEnv(), ...)) - + exists(name, envir = asNamespace("rstudio"), ...) - + } #' @export diff --git a/man/getMode.Rd b/man/getMode.Rd new file mode 100644 index 0000000..f04dc30 --- /dev/null +++ b/man/getMode.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/code.R +\name{getMode} +\alias{getMode} +\title{Report whether RStudio Desktop or RStudio Server is in use} +\usage{ +getMode() +} +\value{ +"desktop" for RStudio Desktop installations, and +"server" for RStudio Server / RStudio Workbench installations. +} +\description{ +Use \code{getMode()} if you need to differentiate between server +and desktop installations of RStudio. +} diff --git a/man/getVersion.Rd b/man/getVersion.Rd index cb01efe..fcbd88c 100644 --- a/man/getVersion.Rd +++ b/man/getVersion.Rd @@ -2,23 +2,15 @@ % Please edit documentation in R/code.R \name{getVersion} \alias{getVersion} -\title{Return the current version of the RStudio API} +\title{Determine the version of RStudio} \usage{ getVersion() } \value{ -A \code{\link{numeric_version}} which you can compare to a string -and get correct results. +A \code{"numeric_version"} object, giving the version of RStudio in use. } \description{ -Return the current version of the RStudio API -} -\examples{ - -\dontrun{ -if (rstudioapi::getVersion() < "0.98.100") { - message("Your version of RStudio is quite old") -} -} - +Use \code{getVersion()} to determine the current version of RStudio. +This can be useful for \R packages which need to gate certain functionality +based on the version of RStudio currently available. }