|
2 | 2 | local({ |
3 | 3 |
|
4 | 4 | # the requested version of renv |
5 | | - version <- "0.15.2" |
| 5 | + version <- "0.12.5" |
6 | 6 |
|
7 | 7 | # the project directory |
8 | 8 | project <- getwd() |
@@ -94,8 +94,11 @@ local({ |
94 | 94 | return(repos) |
95 | 95 |
|
96 | 96 | # if we're testing, re-use the test repositories |
97 | | - if (renv_bootstrap_tests_running()) |
98 | | - return(getOption("renv.tests.repos")) |
| 97 | + if (renv_bootstrap_tests_running()) { |
| 98 | + repos <- getOption("renv.tests.repos") |
| 99 | + if (!is.null(repos)) |
| 100 | + return(repos) |
| 101 | + } |
99 | 102 |
|
100 | 103 | # retrieve current repos |
101 | 104 | repos <- getOption("repos") |
@@ -185,43 +188,80 @@ local({ |
185 | 188 | if (fixup) |
186 | 189 | mode <- "w+b" |
187 | 190 |
|
188 | | - utils::download.file( |
| 191 | + args <- list( |
189 | 192 | url = url, |
190 | 193 | destfile = destfile, |
191 | 194 | mode = mode, |
192 | 195 | quiet = TRUE |
193 | 196 | ) |
194 | 197 |
|
| 198 | + if ("headers" %in% names(formals(utils::download.file))) |
| 199 | + args$headers <- renv_bootstrap_download_custom_headers(url) |
| 200 | + |
| 201 | + do.call(utils::download.file, args) |
| 202 | + |
| 203 | + } |
| 204 | + |
| 205 | + renv_bootstrap_download_custom_headers <- function(url) { |
| 206 | + |
| 207 | + headers <- getOption("renv.download.headers") |
| 208 | + if (is.null(headers)) |
| 209 | + return(character()) |
| 210 | + |
| 211 | + if (!is.function(headers)) |
| 212 | + stopf("'renv.download.headers' is not a function") |
| 213 | + |
| 214 | + headers <- headers(url) |
| 215 | + if (length(headers) == 0L) |
| 216 | + return(character()) |
| 217 | + |
| 218 | + if (is.list(headers)) |
| 219 | + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) |
| 220 | + |
| 221 | + ok <- |
| 222 | + is.character(headers) && |
| 223 | + is.character(names(headers)) && |
| 224 | + all(nzchar(names(headers))) |
| 225 | + |
| 226 | + if (!ok) |
| 227 | + stop("invocation of 'renv.download.headers' did not return a named character vector") |
| 228 | + |
| 229 | + headers |
| 230 | + |
195 | 231 | } |
196 | 232 |
|
197 | 233 | renv_bootstrap_download_cran_latest <- function(version) { |
198 | 234 |
|
199 | 235 | spec <- renv_bootstrap_download_cran_latest_find(version) |
| 236 | + type <- spec$type |
| 237 | + repos <- spec$repos |
200 | 238 |
|
201 | 239 | message("* Downloading renv ", version, " ... ", appendLF = FALSE) |
202 | 240 |
|
203 | | - type <- spec$type |
204 | | - repos <- spec$repos |
| 241 | + baseurl <- utils::contrib.url(repos = repos, type = type) |
| 242 | + ext <- if (identical(type, "source")) |
| 243 | + ".tar.gz" |
| 244 | + else if (Sys.info()[["sysname"]] == "Windows") |
| 245 | + ".zip" |
| 246 | + else |
| 247 | + ".tgz" |
| 248 | + name <- sprintf("renv_%s%s", version, ext) |
| 249 | + url <- paste(baseurl, name, sep = "/") |
205 | 250 |
|
206 | | - info <- tryCatch( |
207 | | - utils::download.packages( |
208 | | - pkgs = "renv", |
209 | | - destdir = tempdir(), |
210 | | - repos = repos, |
211 | | - type = type, |
212 | | - quiet = TRUE |
213 | | - ), |
| 251 | + destfile <- file.path(tempdir(), name) |
| 252 | + status <- tryCatch( |
| 253 | + renv_bootstrap_download_impl(url, destfile), |
214 | 254 | condition = identity |
215 | 255 | ) |
216 | 256 |
|
217 | | - if (inherits(info, "condition")) { |
| 257 | + if (inherits(status, "condition")) { |
218 | 258 | message("FAILED") |
219 | 259 | return(FALSE) |
220 | 260 | } |
221 | 261 |
|
222 | 262 | # report success and return |
223 | 263 | message("OK (downloaded ", type, ")") |
224 | | - info[1, 2] |
| 264 | + destfile |
225 | 265 |
|
226 | 266 | } |
227 | 267 |
|
@@ -622,8 +662,8 @@ local({ |
622 | 662 | if (version == loadedversion) |
623 | 663 | return(TRUE) |
624 | 664 |
|
625 | | - # assume four-component versions are from GitHub; three-component |
626 | | - # versions are from CRAN |
| 665 | + # assume four-component versions are from GitHub; |
| 666 | + # three-component versions are from CRAN |
627 | 667 | components <- strsplit(loadedversion, "[.-]")[[1]] |
628 | 668 | remote <- if (length(components) == 4L) |
629 | 669 | paste("rstudio/renv", loadedversion, sep = "@") |
@@ -678,7 +718,7 @@ local({ |
678 | 718 | return(profile) |
679 | 719 |
|
680 | 720 | # check for a profile file (nothing to do if it doesn't exist) |
681 | | - path <- renv_bootstrap_paths_renv("profile", profile = FALSE) |
| 721 | + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) |
682 | 722 | if (!file.exists(path)) |
683 | 723 | return(NULL) |
684 | 724 |
|
@@ -805,9 +845,41 @@ local({ |
805 | 845 |
|
806 | 846 | renv_json_read <- function(file = NULL, text = NULL) { |
807 | 847 |
|
| 848 | + jlerr <- NULL |
| 849 | + |
| 850 | + # if jsonlite is loaded, use that instead |
| 851 | + if ("jsonlite" %in% loadedNamespaces()) { |
| 852 | + |
| 853 | + json <- catch(renv_json_read_jsonlite(file, text)) |
| 854 | + if (!inherits(json, "error")) |
| 855 | + return(json) |
| 856 | + |
| 857 | + jlerr <- json |
| 858 | + |
| 859 | + } |
| 860 | + |
| 861 | + # otherwise, fall back to the default JSON reader |
| 862 | + json <- catch(renv_json_read_default(file, text)) |
| 863 | + if (!inherits(json, "error")) |
| 864 | + return(json) |
| 865 | + |
| 866 | + # report an error |
| 867 | + if (!is.null(jlerr)) |
| 868 | + stop(jlerr) |
| 869 | + else |
| 870 | + stop(json) |
| 871 | + |
| 872 | + } |
| 873 | + |
| 874 | + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { |
808 | 875 | text <- paste(text %||% read(file), collapse = "\n") |
| 876 | + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) |
| 877 | + } |
| 878 | + |
| 879 | + renv_json_read_default <- function(file = NULL, text = NULL) { |
809 | 880 |
|
810 | 881 | # find strings in the JSON |
| 882 | + text <- paste(text %||% read(file), collapse = "\n") |
811 | 883 | pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' |
812 | 884 | locs <- gregexpr(pattern, text, perl = TRUE)[[1]] |
813 | 885 |
|
@@ -838,8 +910,9 @@ local({ |
838 | 910 |
|
839 | 911 | # transform the JSON into something the R parser understands |
840 | 912 | transformed <- replaced |
841 | | - transformed <- gsub("[[{]", "list(", transformed) |
842 | | - transformed <- gsub("[]}]", ")", transformed) |
| 913 | + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) |
| 914 | + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) |
| 915 | + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) |
843 | 916 | transformed <- gsub(":", "=", transformed, fixed = TRUE) |
844 | 917 | text <- paste(transformed, collapse = "\n") |
845 | 918 |
|
|
0 commit comments