diff --git a/R/install.R b/R/install.R index 6a827a4c4..0cc0f5b45 100644 --- a/R/install.R +++ b/R/install.R @@ -38,9 +38,13 @@ #' installation. #' @param timeout Timeout (in seconds) for the CmdStan build stage of the #' installation process. -#' @param release_url Specifies the URL to a specific Cmdstan release to be +#' @param version Specifies the Cmdstan release version to be #' installed. By default set to `NULL`, which downloads the latest stable #' release from [GitHub](https://github.com/stan-dev/cmdstan/releases). +#' @param release_url Specifies the URL to a specific Cmdstan release to be +#' installed. By default set to `NULL`, which downloads the latest stable +#' release from [GitHub](https://github.com/stan-dev/cmdstan/releases). If +#' `version` and `release_url` are set, `version` is used. #' @param cpp_options A list specifying any makefile flags/variables to be #' written to the `make/local` file. For example, `list("CXX" = "clang++")` #' will force the use of clang for compilation. @@ -53,6 +57,7 @@ install_cmdstan <- function(dir = NULL, quiet = FALSE, overwrite = FALSE, timeout = 1200, + version = NULL, release_url = NULL, cpp_options = list()) { if (is.null(dir)) { @@ -64,7 +69,12 @@ install_cmdstan <- function(dir = NULL, dir <- repair_path(dir) checkmate::assert_directory_exists(dir, access = "rwx") } - + if (!is.null(version)) { + if (!is.null(release_url)) { + warning("version and release_url are supplied to install_cmdstan()!\nrelease_url will be ignored.") + } + release_url <- paste0("https://github.com/stan-dev/cmdstan/releases/download/v",version, "/cmdstan-", version, ".tar.gz") + } if (!is.null(release_url)) { if (!endsWith(release_url, ".tar.gz")) { stop(release_url, " is not a .tar.gz archive!", @@ -94,7 +104,13 @@ install_cmdstan <- function(dir = NULL, } tar_downloaded <- download_with_retries(download_url, dest_file) if (!tar_downloaded) { - stop("GitHub download of Cmdstan failed.", call. = FALSE) + if (!is.null(version)) { + stop("Download of Cmdstan failed. Please check if the supplied version number is valid.", call. = FALSE) + } + if (!is.null(release_url)) { + stop("Download of Cmdstan failed. Please check if the supplied release URL is valid.", call. = FALSE) + } + stop("Download of Cmdstan failed. Please try again.", call. = FALSE) } message("* Download complete") @@ -268,9 +284,14 @@ download_with_retries <- function(download_url, quiet = TRUE) { download_rc <- 1 while (retries > 0 && download_rc != 0) { - download_rc <- utils::download.file(url = download_url, - destfile = destination_file, - quiet = quiet) + try( + suppressWarnings( + download_rc <- utils::download.file(url = download_url, + destfile = destination_file, + quiet = quiet) + ), + silent = TRUE + ) if (download_rc != 0) { Sys.sleep(pause_sec) } diff --git a/man/install_cmdstan.Rd b/man/install_cmdstan.Rd index d7a7b966d..ab006ff38 100644 --- a/man/install_cmdstan.Rd +++ b/man/install_cmdstan.Rd @@ -12,6 +12,7 @@ install_cmdstan( quiet = FALSE, overwrite = FALSE, timeout = 1200, + version = NULL, release_url = NULL, cpp_options = list() ) @@ -47,10 +48,15 @@ installation.} \item{timeout}{Timeout (in seconds) for the CmdStan build stage of the installation process.} -\item{release_url}{Specifies the URL to a specific Cmdstan release to be +\item{version}{Specifies the Cmdstan release version to be installed. By default set to \code{NULL}, which downloads the latest stable release from \href{https://github.com/stan-dev/cmdstan/releases}{GitHub}.} +\item{release_url}{Specifies the URL to a specific Cmdstan release to be +installed. By default set to \code{NULL}, which downloads the latest stable +release from \href{https://github.com/stan-dev/cmdstan/releases}{GitHub}. If +\code{version} and \code{release_url} are set, \code{version} is used.} + \item{cpp_options}{A list specifying any makefile flags/variables to be written to the \code{make/local} file. For example, \code{list("CXX" = "clang++")} will force the use of clang for compilation.} diff --git a/tests/testthat/test-install.R b/tests/testthat/test-install.R index 6ea720643..fe0130d94 100644 --- a/tests/testthat/test-install.R +++ b/tests/testthat/test-install.R @@ -74,5 +74,47 @@ test_that("install_cmdstan() errors if it times out", { ) }) +test_that("install_cmdstan() errors if invalid version or URL", { + skip_if_offline() + expect_error( + install_cmdstan(version = "2.23.2"), + "Download of Cmdstan failed. Please check if the supplied version number is valid." + ) + expect_error( + install_cmdstan(release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.23.2/cmdstan-2.23.2.tar.gz"), + "Download of Cmdstan failed. Please check if the supplied release URL is valid." + ) +}) - +test_that("install_cmdstan() works with version and release_url", { + skip_if_offline() + if (getRversion() < '3.5.0') { + dir <- tempdir() + } else { + dir <- tempdir(check = TRUE) + } + expect_message( + expect_output( + install_cmdstan(dir = dir, overwrite = TRUE, cores = 4, + release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.24.0/cmdstan-2.24.0.tar.gz"), + "Compiling, linking C++ code", + fixed = TRUE + ), + "Finished installing CmdStan" + ) + expect_warning( + expect_message( + expect_output( + install_cmdstan(dir = dir, overwrite = TRUE, cores = 4, + version = "2.23.0", + # the URL is intentionally invalid to test that the version has higher priority + release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.23.2/cmdstan-2.23.2.tar.gz"), + "Compiling, linking C++ code", + fixed = TRUE + ), + "Finished installing CmdStan" + ), + "version and release_url are supplied to install_cmdstan()" + ) + expect_true(dir.exists(file.path(dir, "cmdstan-2.23.0"))) +})