bebray03 commited on
Commit
cc44cbe
·
1 Parent(s): 2493267

updating Dockerfile

Browse files
Files changed (6) hide show
  1. .Rprofile +1 -0
  2. Dockerfile +28 -4
  3. renv.lock +0 -0
  4. renv/.gitignore +7 -0
  5. renv/activate.R +1438 -0
  6. renv/settings.json +20 -0
.Rprofile ADDED
@@ -0,0 +1 @@
 
 
1
+ source("renv/activate.R")
Dockerfile CHANGED
@@ -1,9 +1,33 @@
1
  FROM rocker/shiny:latest
2
 
3
- RUN R -e "install.packages(c('leaflet', 'sf', 'dplyr', 'ggplot2', 'arrow', 'scales', 'viridisLite', 'bslib'), repos='https://cran.rstudio.com/')"
 
 
 
 
 
 
 
 
4
 
5
- COPY . /srv/shiny-server/
 
 
 
 
 
6
 
7
- EXPOSE 3838
 
 
 
8
 
9
- CMD ["/usr/bin/shiny-server"]
 
 
 
 
 
 
 
 
 
1
  FROM rocker/shiny:latest
2
 
3
+ # system dependencies
4
+ RUN apt-get update && apt-get install -y \
5
+ libgdal-dev \
6
+ libgeos-dev \
7
+ libproj-dev \
8
+ libssl-dev \
9
+ libcurl4-openssl-dev \
10
+ libxml2-dev \
11
+ && rm -rf /var/lib/apt/lists/*
12
 
13
+ # R packages — add everything your app uses
14
+ RUN R -e "install.packages(c(
15
+ 'shiny', 'dplyr', 'readr', 'ggplot2',
16
+ 'leaflet', 'sf', 'viridisLite', 'scales',
17
+ 'zoo', 'shinydashboard'
18
+ ), repos='https://cran.rstudio.com/')"
19
 
20
+ # copy app files
21
+ COPY app.R /srv/shiny-server/
22
+ COPY brt_projections_by_rock/ /srv/shiny-server/brt_projections_by_rock/
23
+ COPY shp/ /srv/shiny-server/shp/
24
 
25
+ # Hugging Face runs as non-root user 1000 — needs write permission
26
+ RUN chown -R 1000:1000 /srv/shiny-server/ \
27
+ && chmod -R 755 /srv/shiny-server/
28
+
29
+ # Hugging Face expects port 7860
30
+ EXPOSE 7860
31
+
32
+ # override default shiny port to 7860
33
+ CMD ["R", "-e", "shiny::runApp('/srv/shiny-server/app.R', host='0.0.0.0', port=7860)"]
renv.lock ADDED
The diff for this file is too large to render. See raw diff
 
renv/.gitignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ library/
2
+ local/
3
+ cellar/
4
+ lock/
5
+ python/
6
+ sandbox/
7
+ staging/
renv/activate.R ADDED
@@ -0,0 +1,1438 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ local({
3
+
4
+ # the requested version of renv
5
+ version <- "1.2.0"
6
+ attr(version, "md5") <- "b7d230b07507f361d3bcf794d157a188"
7
+ attr(version, "sha") <- NULL
8
+
9
+ # the project directory
10
+ project <- Sys.getenv("RENV_PROJECT")
11
+ if (!nzchar(project))
12
+ project <- getwd()
13
+
14
+ # use start-up diagnostics if enabled
15
+ diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE")
16
+ if (diagnostics) {
17
+ start <- Sys.time()
18
+ profile <- tempfile("renv-startup-", fileext = ".Rprof")
19
+ utils::Rprof(profile)
20
+ on.exit({
21
+ utils::Rprof(NULL)
22
+ elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L)
23
+ writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed)))
24
+ writeLines(sprintf("- Profile: %s", profile))
25
+ print(utils::summaryRprof(profile))
26
+ }, add = TRUE)
27
+ }
28
+
29
+ # figure out whether the autoloader is enabled
30
+ enabled <- local({
31
+
32
+ # first, check config option
33
+ override <- getOption("renv.config.autoloader.enabled")
34
+ if (!is.null(override))
35
+ return(override)
36
+
37
+ # if we're being run in a context where R_LIBS is already set,
38
+ # don't load -- presumably we're being run as a sub-process and
39
+ # the parent process has already set up library paths for us
40
+ rcmd <- Sys.getenv("R_CMD", unset = NA)
41
+ rlibs <- Sys.getenv("R_LIBS", unset = NA)
42
+ if (!is.na(rlibs) && !is.na(rcmd))
43
+ return(FALSE)
44
+
45
+ # next, check environment variables
46
+ # prefer using the configuration one in the future
47
+ envvars <- c(
48
+ "RENV_CONFIG_AUTOLOADER_ENABLED",
49
+ "RENV_AUTOLOADER_ENABLED",
50
+ "RENV_ACTIVATE_PROJECT"
51
+ )
52
+
53
+ for (envvar in envvars) {
54
+ envval <- Sys.getenv(envvar, unset = NA)
55
+ if (!is.na(envval))
56
+ return(tolower(envval) %in% c("true", "t", "1"))
57
+ }
58
+
59
+ # enable by default
60
+ TRUE
61
+
62
+ })
63
+
64
+ # bail if we're not enabled
65
+ if (!enabled) {
66
+
67
+ # if we're not enabled, we might still need to manually load
68
+ # the user profile here
69
+ profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile")
70
+ if (file.exists(profile)) {
71
+ cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE")
72
+ if (tolower(cfg) %in% c("true", "t", "1"))
73
+ sys.source(profile, envir = globalenv())
74
+ }
75
+
76
+ return(FALSE)
77
+
78
+ }
79
+
80
+ # avoid recursion
81
+ if (identical(getOption("renv.autoloader.running"), TRUE)) {
82
+ warning("ignoring recursive attempt to run renv autoloader")
83
+ return(invisible(TRUE))
84
+ }
85
+
86
+ # signal that we're loading renv during R startup
87
+ options(renv.autoloader.running = TRUE)
88
+ on.exit(options(renv.autoloader.running = NULL), add = TRUE)
89
+
90
+ # signal that we've consented to use renv
91
+ options(renv.consent = TRUE)
92
+
93
+ # load the 'utils' package eagerly -- this ensures that renv shims, which
94
+ # mask 'utils' packages, will come first on the search path
95
+ library(utils, lib.loc = .Library)
96
+
97
+ # unload renv if it's already been loaded
98
+ if ("renv" %in% loadedNamespaces())
99
+ unloadNamespace("renv")
100
+
101
+ # load bootstrap tools
102
+ ansify <- function(text) {
103
+ if (renv_ansify_enabled())
104
+ renv_ansify_enhanced(text)
105
+ else
106
+ renv_ansify_default(text)
107
+ }
108
+
109
+ renv_ansify_enabled <- function() {
110
+
111
+ override <- Sys.getenv("RENV_ANSIFY_ENABLED", unset = NA)
112
+ if (!is.na(override))
113
+ return(as.logical(override))
114
+
115
+ pane <- Sys.getenv("RSTUDIO_CHILD_PROCESS_PANE", unset = NA)
116
+ if (identical(pane, "build"))
117
+ return(FALSE)
118
+
119
+ testthat <- Sys.getenv("TESTTHAT", unset = "false")
120
+ if (tolower(testthat) %in% "true")
121
+ return(FALSE)
122
+
123
+ iderun <- Sys.getenv("R_CLI_HAS_HYPERLINK_IDE_RUN", unset = "false")
124
+ if (tolower(iderun) %in% "false")
125
+ return(FALSE)
126
+
127
+ TRUE
128
+
129
+ }
130
+
131
+ renv_ansify_default <- function(text) {
132
+ text
133
+ }
134
+
135
+ renv_ansify_enhanced <- function(text) {
136
+
137
+ # R help links
138
+ pattern <- "`\\?(renv::(?:[^`])+)`"
139
+ replacement <- "`\033]8;;x-r-help:\\1\a?\\1\033]8;;\a`"
140
+ text <- gsub(pattern, replacement, text, perl = TRUE)
141
+
142
+ # runnable code
143
+ pattern <- "`(renv::(?:[^`])+)`"
144
+ replacement <- "`\033]8;;x-r-run:\\1\a\\1\033]8;;\a`"
145
+ text <- gsub(pattern, replacement, text, perl = TRUE)
146
+
147
+ # return ansified text
148
+ text
149
+
150
+ }
151
+
152
+ renv_ansify_init <- function() {
153
+
154
+ envir <- renv_envir_self()
155
+ if (renv_ansify_enabled())
156
+ assign("ansify", renv_ansify_enhanced, envir = envir)
157
+ else
158
+ assign("ansify", renv_ansify_default, envir = envir)
159
+
160
+ }
161
+
162
+ `%||%` <- function(x, y) {
163
+ if (is.null(x)) y else x
164
+ }
165
+
166
+ catf <- function(fmt, ..., appendLF = TRUE) {
167
+
168
+ quiet <- getOption("renv.bootstrap.quiet", default = FALSE)
169
+ if (quiet)
170
+ return(invisible())
171
+
172
+ # also check for config environment variables that should suppress messages
173
+ # https://github.com/rstudio/renv/issues/2214
174
+ enabled <- Sys.getenv("RENV_CONFIG_STARTUP_QUIET", unset = NA)
175
+ if (!is.na(enabled) && tolower(enabled) %in% c("true", "1"))
176
+ return(invisible())
177
+
178
+ enabled <- Sys.getenv("RENV_CONFIG_SYNCHRONIZED_CHECK", unset = NA)
179
+ if (!is.na(enabled) && tolower(enabled) %in% c("false", "0"))
180
+ return(invisible())
181
+
182
+ msg <- sprintf(fmt, ...)
183
+ cat(msg, file = stdout(), sep = if (appendLF) "\n" else "")
184
+
185
+ invisible(msg)
186
+
187
+ }
188
+
189
+ header <- function(label,
190
+ ...,
191
+ prefix = "#",
192
+ suffix = "-",
193
+ n = min(getOption("width"), 78))
194
+ {
195
+ label <- sprintf(label, ...)
196
+ n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L)
197
+ if (n <= 0)
198
+ return(paste(prefix, label))
199
+
200
+ tail <- paste(rep.int(suffix, n), collapse = "")
201
+ paste0(prefix, " ", label, " ", tail)
202
+
203
+ }
204
+
205
+ heredoc <- function(text, leave = 0) {
206
+
207
+ # remove leading, trailing whitespace
208
+ trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text)
209
+
210
+ # split into lines
211
+ lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]]
212
+
213
+ # compute common indent
214
+ indent <- regexpr("[^[:space:]]", lines)
215
+ common <- min(setdiff(indent, -1L)) - leave
216
+ text <- paste(substring(lines, common), collapse = "\n")
217
+
218
+ # substitute in ANSI links for executable renv code
219
+ ansify(text)
220
+
221
+ }
222
+
223
+ bootstrap <- function(version, library) {
224
+
225
+ friendly <- renv_bootstrap_version_friendly(version)
226
+ section <- header(sprintf("Bootstrapping renv %s", friendly))
227
+ catf(section)
228
+
229
+ # ensure the target library path exists; required for file.copy(..., recursive = TRUE)
230
+ dir.create(library, showWarnings = FALSE, recursive = TRUE)
231
+
232
+ # try to install renv from cache
233
+ md5 <- attr(version, "md5", exact = TRUE)
234
+ if (length(md5)) {
235
+ pkgpath <- renv_bootstrap_find(version)
236
+ if (length(pkgpath) && file.exists(pkgpath)) {
237
+ ok <- file.copy(pkgpath, library, recursive = TRUE)
238
+ if (isTRUE(ok))
239
+ return(invisible())
240
+ }
241
+ }
242
+
243
+ # attempt to download renv
244
+ catf("- Downloading renv ... ", appendLF = FALSE)
245
+ withCallingHandlers(
246
+ tarball <- renv_bootstrap_download(version),
247
+ error = function(err) {
248
+ catf("FAILED")
249
+ stop("failed to download:\n", conditionMessage(err))
250
+ }
251
+ )
252
+ catf("OK")
253
+ on.exit(unlink(tarball), add = TRUE)
254
+
255
+ # now attempt to install
256
+ catf("- Installing renv ... ", appendLF = FALSE)
257
+ withCallingHandlers(
258
+ status <- renv_bootstrap_install(version, tarball, library),
259
+ error = function(err) {
260
+ catf("FAILED")
261
+ stop("failed to install:\n", conditionMessage(err))
262
+ }
263
+ )
264
+ catf("OK")
265
+
266
+ # add empty line to break up bootstrapping from normal output
267
+ catf("")
268
+ return(invisible())
269
+ }
270
+
271
+ renv_bootstrap_tests_running <- function() {
272
+ getOption("renv.tests.running", default = FALSE)
273
+ }
274
+
275
+ renv_bootstrap_repos <- function() {
276
+
277
+ # get CRAN repository
278
+ cran <- getOption("renv.repos.cran", "https://cloud.r-project.org")
279
+
280
+ # check for repos override
281
+ repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA)
282
+ if (!is.na(repos)) {
283
+
284
+ # split on ';' if present
285
+ parts <- strsplit(repos, ";", fixed = TRUE)[[1L]]
286
+
287
+ # split into named repositories if present
288
+ idx <- regexpr("=", parts, fixed = TRUE)
289
+ keys <- substring(parts, 1L, idx - 1L)
290
+ vals <- substring(parts, idx + 1L)
291
+ names(vals) <- keys
292
+
293
+ # if we have a single unnamed repository, call it CRAN
294
+ if (length(vals) == 1L && identical(keys, ""))
295
+ names(vals) <- "CRAN"
296
+
297
+ return(vals)
298
+
299
+ }
300
+
301
+ # check for lockfile repositories
302
+ repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity)
303
+ if (!inherits(repos, "error") && length(repos))
304
+ return(repos)
305
+
306
+ # retrieve current repos
307
+ repos <- getOption("repos")
308
+
309
+ # ensure @CRAN@ entries are resolved
310
+ repos[repos == "@CRAN@"] <- cran
311
+
312
+ # add in renv.bootstrap.repos if set
313
+ default <- c(FALLBACK = "https://cloud.r-project.org")
314
+ extra <- getOption("renv.bootstrap.repos", default = default)
315
+ repos <- c(repos, extra)
316
+
317
+ # remove duplicates that might've snuck in
318
+ dupes <- duplicated(repos) | duplicated(names(repos))
319
+ repos[!dupes]
320
+
321
+ }
322
+
323
+ renv_bootstrap_repos_lockfile <- function() {
324
+
325
+ lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock")
326
+ if (!file.exists(lockpath))
327
+ return(NULL)
328
+
329
+ lockfile <- tryCatch(renv_json_read(lockpath), error = identity)
330
+ if (inherits(lockfile, "error")) {
331
+ warning(lockfile)
332
+ return(NULL)
333
+ }
334
+
335
+ repos <- lockfile$R$Repositories
336
+ if (length(repos) == 0)
337
+ return(NULL)
338
+
339
+ keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1))
340
+ vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1))
341
+ names(vals) <- keys
342
+
343
+ return(vals)
344
+
345
+ }
346
+
347
+ renv_bootstrap_download <- function(version) {
348
+
349
+ sha <- attr(version, "sha", exact = TRUE)
350
+
351
+ methods <- if (!is.null(sha)) {
352
+
353
+ # attempting to bootstrap a development version of renv
354
+ c(
355
+ function() renv_bootstrap_download_tarball(sha),
356
+ function() renv_bootstrap_download_github(sha)
357
+ )
358
+
359
+ } else {
360
+
361
+ # attempting to bootstrap a release version of renv
362
+ c(
363
+ function() renv_bootstrap_download_tarball(version),
364
+ function() renv_bootstrap_download_cran_latest(version),
365
+ function() renv_bootstrap_download_cran_archive(version)
366
+ )
367
+
368
+ }
369
+
370
+ for (method in methods) {
371
+ path <- tryCatch(method(), error = identity)
372
+ if (is.character(path) && file.exists(path))
373
+ return(path)
374
+ }
375
+
376
+ stop("All download methods failed")
377
+
378
+ }
379
+
380
+ renv_bootstrap_download_impl <- function(url, destfile) {
381
+
382
+ mode <- "wb"
383
+
384
+ # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715
385
+ fixup <-
386
+ Sys.info()[["sysname"]] == "Windows" &&
387
+ substring(url, 1L, 5L) == "file:"
388
+
389
+ if (fixup)
390
+ mode <- "w+b"
391
+
392
+ args <- list(
393
+ url = url,
394
+ destfile = destfile,
395
+ mode = mode,
396
+ quiet = TRUE
397
+ )
398
+
399
+ if ("headers" %in% names(formals(utils::download.file))) {
400
+ headers <- renv_bootstrap_download_custom_headers(url)
401
+ if (length(headers) && is.character(headers))
402
+ args$headers <- headers
403
+ }
404
+
405
+ do.call(utils::download.file, args)
406
+
407
+ }
408
+
409
+ renv_bootstrap_download_custom_headers <- function(url) {
410
+
411
+ headers <- getOption("renv.download.headers")
412
+ if (is.null(headers))
413
+ return(character())
414
+
415
+ if (!is.function(headers))
416
+ stopf("'renv.download.headers' is not a function")
417
+
418
+ headers <- headers(url)
419
+ if (length(headers) == 0L)
420
+ return(character())
421
+
422
+ if (is.list(headers))
423
+ headers <- unlist(headers, recursive = FALSE, use.names = TRUE)
424
+
425
+ ok <-
426
+ is.character(headers) &&
427
+ is.character(names(headers)) &&
428
+ all(nzchar(names(headers)))
429
+
430
+ if (!ok)
431
+ stop("invocation of 'renv.download.headers' did not return a named character vector")
432
+
433
+ headers
434
+
435
+ }
436
+
437
+ renv_bootstrap_download_cran_latest <- function(version) {
438
+
439
+ spec <- renv_bootstrap_download_cran_latest_find(version)
440
+ type <- spec$type
441
+ repos <- spec$repos
442
+
443
+ baseurl <- utils::contrib.url(repos = repos, type = type)
444
+ ext <- if (identical(type, "source"))
445
+ ".tar.gz"
446
+ else if (Sys.info()[["sysname"]] == "Windows")
447
+ ".zip"
448
+ else
449
+ ".tgz"
450
+ name <- sprintf("renv_%s%s", version, ext)
451
+ url <- paste(baseurl, name, sep = "/")
452
+
453
+ destfile <- file.path(tempdir(), name)
454
+ status <- tryCatch(
455
+ renv_bootstrap_download_impl(url, destfile),
456
+ condition = identity
457
+ )
458
+
459
+ if (inherits(status, "condition"))
460
+ return(FALSE)
461
+
462
+ # report success and return
463
+ destfile
464
+
465
+ }
466
+
467
+ renv_bootstrap_download_cran_latest_find <- function(version) {
468
+
469
+ # check whether binaries are supported on this system
470
+ binary <-
471
+ getOption("renv.bootstrap.binary", default = TRUE) &&
472
+ !identical(.Platform$pkgType, "source") &&
473
+ !identical(getOption("pkgType"), "source") &&
474
+ Sys.info()[["sysname"]] %in% c("Darwin", "Windows")
475
+
476
+ types <- c(if (binary) "binary", "source")
477
+
478
+ # iterate over types + repositories
479
+ for (type in types) {
480
+ for (repos in renv_bootstrap_repos()) {
481
+
482
+ # build arguments for utils::available.packages() call
483
+ args <- list(type = type, repos = repos)
484
+
485
+ # add custom headers if available -- note that
486
+ # utils::available.packages() will pass this to download.file()
487
+ if ("headers" %in% names(formals(utils::download.file))) {
488
+ headers <- renv_bootstrap_download_custom_headers(repos)
489
+ if (length(headers) && is.character(headers))
490
+ args$headers <- headers
491
+ }
492
+
493
+ # retrieve package database
494
+ db <- tryCatch(
495
+ as.data.frame(
496
+ do.call(utils::available.packages, args),
497
+ stringsAsFactors = FALSE
498
+ ),
499
+ error = identity
500
+ )
501
+
502
+ if (inherits(db, "error"))
503
+ next
504
+
505
+ # check for compatible entry
506
+ entry <- db[db$Package %in% "renv" & db$Version %in% version, ]
507
+ if (nrow(entry) == 0)
508
+ next
509
+
510
+ # found it; return spec to caller
511
+ spec <- list(entry = entry, type = type, repos = repos)
512
+ return(spec)
513
+
514
+ }
515
+ }
516
+
517
+ # if we got here, we failed to find renv
518
+ fmt <- "renv %s is not available from your declared package repositories"
519
+ stop(sprintf(fmt, version))
520
+
521
+ }
522
+
523
+ renv_bootstrap_download_cran_archive <- function(version) {
524
+
525
+ name <- sprintf("renv_%s.tar.gz", version)
526
+ repos <- renv_bootstrap_repos()
527
+ urls <- file.path(repos, "src/contrib/Archive/renv", name)
528
+ destfile <- file.path(tempdir(), name)
529
+
530
+ for (url in urls) {
531
+
532
+ status <- tryCatch(
533
+ renv_bootstrap_download_impl(url, destfile),
534
+ condition = identity
535
+ )
536
+
537
+ if (identical(status, 0L))
538
+ return(destfile)
539
+
540
+ }
541
+
542
+ return(FALSE)
543
+
544
+ }
545
+
546
+ renv_bootstrap_find <- function(version) {
547
+
548
+ path <- renv_bootstrap_find_cache(version)
549
+ if (length(path) && file.exists(path)) {
550
+ catf("- Using renv %s from global package cache", version)
551
+ return(path)
552
+ }
553
+
554
+ }
555
+
556
+ renv_bootstrap_find_cache <- function(version) {
557
+
558
+ md5 <- attr(version, "md5", exact = TRUE)
559
+ if (is.null(md5))
560
+ return()
561
+
562
+ # infer path to renv cache
563
+ cache <- Sys.getenv("RENV_PATHS_CACHE", unset = "")
564
+ if (!nzchar(cache)) {
565
+ root <- Sys.getenv("RENV_PATHS_ROOT", unset = NA)
566
+ if (!is.na(root))
567
+ cache <- file.path(root, "cache")
568
+ }
569
+
570
+ if (!nzchar(cache)) {
571
+ tools <- asNamespace("tools")
572
+ if (is.function(tools$R_user_dir)) {
573
+ root <- tools$R_user_dir("renv", "cache")
574
+ cache <- file.path(root, "cache")
575
+ }
576
+ }
577
+
578
+ # start completing path to cache
579
+ file.path(
580
+ cache,
581
+ renv_bootstrap_cache_version(),
582
+ renv_bootstrap_platform_prefix(),
583
+ "renv",
584
+ version,
585
+ md5,
586
+ "renv"
587
+ )
588
+
589
+ }
590
+
591
+ renv_bootstrap_download_tarball <- function(version) {
592
+
593
+ # if the user has provided the path to a tarball via
594
+ # an environment variable, then use it
595
+ tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA)
596
+ if (is.na(tarball))
597
+ return()
598
+
599
+ # allow directories
600
+ if (dir.exists(tarball)) {
601
+ name <- sprintf("renv_%s.tar.gz", version)
602
+ tarball <- file.path(tarball, name)
603
+ }
604
+
605
+ # bail if it doesn't exist
606
+ if (!file.exists(tarball)) {
607
+
608
+ # let the user know we weren't able to honour their request
609
+ fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist."
610
+ msg <- sprintf(fmt, tarball)
611
+ warning(msg)
612
+
613
+ # bail
614
+ return()
615
+
616
+ }
617
+
618
+ catf("- Using local tarball '%s'.", tarball)
619
+ tarball
620
+
621
+ }
622
+
623
+ renv_bootstrap_github_token <- function() {
624
+ for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) {
625
+ envval <- Sys.getenv(envvar, unset = NA)
626
+ if (!is.na(envval))
627
+ return(envval)
628
+ }
629
+ }
630
+
631
+ renv_bootstrap_download_github <- function(version) {
632
+
633
+ enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
634
+ if (!identical(enabled, "TRUE"))
635
+ return(FALSE)
636
+
637
+ # prepare download options
638
+ token <- renv_bootstrap_github_token()
639
+ if (is.null(token))
640
+ token <- ""
641
+
642
+ if (nzchar(Sys.which("curl")) && nzchar(token)) {
643
+ fmt <- "--location --fail --header \"Authorization: token %s\""
644
+ extra <- sprintf(fmt, token)
645
+ saved <- options("download.file.method", "download.file.extra")
646
+ options(download.file.method = "curl", download.file.extra = extra)
647
+ on.exit(do.call(base::options, saved), add = TRUE)
648
+ } else if (nzchar(Sys.which("wget")) && nzchar(token)) {
649
+ fmt <- "--header=\"Authorization: token %s\""
650
+ extra <- sprintf(fmt, token)
651
+ saved <- options("download.file.method", "download.file.extra")
652
+ options(download.file.method = "wget", download.file.extra = extra)
653
+ on.exit(do.call(base::options, saved), add = TRUE)
654
+ }
655
+
656
+ url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version)
657
+ name <- sprintf("renv_%s.tar.gz", version)
658
+ destfile <- file.path(tempdir(), name)
659
+
660
+ status <- tryCatch(
661
+ renv_bootstrap_download_impl(url, destfile),
662
+ condition = identity
663
+ )
664
+
665
+ if (!identical(status, 0L))
666
+ return(FALSE)
667
+
668
+ renv_bootstrap_download_augment(destfile)
669
+
670
+ return(destfile)
671
+
672
+ }
673
+
674
+ # Add Sha to DESCRIPTION. This is stop gap until #890, after which we
675
+ # can use renv::install() to fully capture metadata.
676
+ renv_bootstrap_download_augment <- function(destfile) {
677
+ sha <- renv_bootstrap_git_extract_sha1_tar(destfile)
678
+ if (is.null(sha)) {
679
+ return()
680
+ }
681
+
682
+ # Untar
683
+ tempdir <- tempfile("renv-github-")
684
+ on.exit(unlink(tempdir, recursive = TRUE), add = TRUE)
685
+ untar(destfile, exdir = tempdir)
686
+ pkgdir <- dir(tempdir, full.names = TRUE)[[1]]
687
+
688
+ # Modify description
689
+ desc_path <- file.path(pkgdir, "DESCRIPTION")
690
+ desc_lines <- readLines(desc_path)
691
+ remotes_fields <- c(
692
+ "RemoteType: github",
693
+ "RemoteHost: api.github.com",
694
+ "RemoteRepo: renv",
695
+ "RemoteUsername: rstudio",
696
+ "RemotePkgRef: rstudio/renv",
697
+ paste("RemoteRef: ", sha),
698
+ paste("RemoteSha: ", sha)
699
+ )
700
+ writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path)
701
+
702
+ # Re-tar
703
+ local({
704
+ old <- setwd(tempdir)
705
+ on.exit(setwd(old), add = TRUE)
706
+
707
+ tar(destfile, compression = "gzip")
708
+ })
709
+ invisible()
710
+ }
711
+
712
+ # Extract the commit hash from a git archive. Git archives include the SHA1
713
+ # hash as the comment field of the tarball pax extended header
714
+ # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html)
715
+ # For GitHub archives this should be the first header after the default one
716
+ # (512 byte) header.
717
+ renv_bootstrap_git_extract_sha1_tar <- function(bundle) {
718
+
719
+ # open the bundle for reading
720
+ # We use gzcon for everything because (from ?gzcon)
721
+ # > Reading from a connection which does not supply a 'gzip' magic
722
+ # > header is equivalent to reading from the original connection
723
+ conn <- gzcon(file(bundle, open = "rb", raw = TRUE))
724
+ on.exit(close(conn))
725
+
726
+ # The default pax header is 512 bytes long and the first pax extended header
727
+ # with the comment should be 51 bytes long
728
+ # `52 comment=` (11 chars) + 40 byte SHA1 hash
729
+ len <- 0x200 + 0x33
730
+ res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len])
731
+
732
+ if (grepl("^52 comment=", res)) {
733
+ sub("52 comment=", "", res)
734
+ } else {
735
+ NULL
736
+ }
737
+ }
738
+
739
+ renv_bootstrap_install <- function(version, tarball, library) {
740
+
741
+ # attempt to install it into project library
742
+ dir.create(library, showWarnings = FALSE, recursive = TRUE)
743
+ output <- renv_bootstrap_install_impl(library, tarball)
744
+
745
+ # check for successful install
746
+ status <- attr(output, "status")
747
+ if (is.null(status) || identical(status, 0L))
748
+ return(status)
749
+
750
+ # an error occurred; report it
751
+ header <- "installation of renv failed"
752
+ lines <- paste(rep.int("=", nchar(header)), collapse = "")
753
+ text <- paste(c(header, lines, output), collapse = "\n")
754
+ stop(text)
755
+
756
+ }
757
+
758
+ renv_bootstrap_install_impl <- function(library, tarball) {
759
+
760
+ # invoke using system2 so we can capture and report output
761
+ bin <- R.home("bin")
762
+ exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
763
+ R <- file.path(bin, exe)
764
+
765
+ args <- c(
766
+ "--vanilla", "CMD", "INSTALL", "--no-multiarch",
767
+ "-l", shQuote(path.expand(library)),
768
+ shQuote(path.expand(tarball))
769
+ )
770
+
771
+ system2(R, args, stdout = TRUE, stderr = TRUE)
772
+
773
+ }
774
+
775
+ renv_bootstrap_platform_prefix_default <- function() {
776
+
777
+ # read version component
778
+ version <- Sys.getenv("RENV_PATHS_VERSION", unset = "R-%v")
779
+
780
+ # expand placeholders
781
+ placeholders <- list(
782
+ list("%v", format(getRversion()[1, 1:2])),
783
+ list("%V", format(getRversion()[1, 1:3]))
784
+ )
785
+
786
+ for (placeholder in placeholders)
787
+ version <- gsub(placeholder[[1L]], placeholder[[2L]], version, fixed = TRUE)
788
+
789
+ # include SVN revision for development versions of R
790
+ # (to avoid sharing platform-specific artefacts with released versions of R)
791
+ devel <-
792
+ identical(R.version[["status"]], "Under development (unstable)") ||
793
+ identical(R.version[["nickname"]], "Unsuffered Consequences")
794
+
795
+ if (devel)
796
+ version <- paste(version, R.version[["svn rev"]], sep = "-r")
797
+
798
+ version
799
+
800
+ }
801
+
802
+ renv_bootstrap_platform_prefix <- function() {
803
+
804
+ # construct version prefix
805
+ version <- renv_bootstrap_platform_prefix_default()
806
+
807
+ # build list of path components
808
+ components <- c(version, R.version$platform)
809
+
810
+ # include prefix if provided by user
811
+ prefix <- renv_bootstrap_platform_prefix_impl()
812
+ if (!is.na(prefix) && nzchar(prefix))
813
+ components <- c(prefix, components)
814
+
815
+ # build prefix
816
+ paste(components, collapse = "/")
817
+
818
+ }
819
+
820
+ renv_bootstrap_platform_prefix_impl <- function() {
821
+
822
+ # if an explicit prefix has been supplied, use it
823
+ prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA)
824
+ if (!is.na(prefix))
825
+ return(prefix)
826
+
827
+ # if the user has requested an automatic prefix, generate it
828
+ auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA)
829
+ if (is.na(auto) && getRversion() >= "4.4.0")
830
+ auto <- "TRUE"
831
+
832
+ if (auto %in% c("TRUE", "True", "true", "1"))
833
+ return(renv_bootstrap_platform_prefix_auto())
834
+
835
+ # empty string on failure
836
+ ""
837
+
838
+ }
839
+
840
+ renv_bootstrap_platform_prefix_auto <- function() {
841
+
842
+ prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity)
843
+ if (inherits(prefix, "error") || prefix %in% "unknown") {
844
+
845
+ msg <- paste(
846
+ "failed to infer current operating system",
847
+ "please file a bug report at https://github.com/rstudio/renv/issues",
848
+ sep = "; "
849
+ )
850
+
851
+ warning(msg)
852
+
853
+ }
854
+
855
+ prefix
856
+
857
+ }
858
+
859
+ renv_bootstrap_platform_os <- function() {
860
+
861
+ sysinfo <- Sys.info()
862
+ sysname <- sysinfo[["sysname"]]
863
+
864
+ # handle Windows + macOS up front
865
+ if (sysname == "Windows")
866
+ return("windows")
867
+ else if (sysname == "Darwin")
868
+ return("macos")
869
+
870
+ # check for os-release files
871
+ for (file in c("/etc/os-release", "/usr/lib/os-release"))
872
+ if (file.exists(file))
873
+ return(renv_bootstrap_platform_os_via_os_release(file, sysinfo))
874
+
875
+ # check for redhat-release files
876
+ if (file.exists("/etc/redhat-release"))
877
+ return(renv_bootstrap_platform_os_via_redhat_release())
878
+
879
+ "unknown"
880
+
881
+ }
882
+
883
+ renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) {
884
+
885
+ # read /etc/os-release
886
+ release <- utils::read.table(
887
+ file = file,
888
+ sep = "=",
889
+ quote = c("\"", "'"),
890
+ col.names = c("Key", "Value"),
891
+ comment.char = "#",
892
+ stringsAsFactors = FALSE
893
+ )
894
+
895
+ vars <- as.list(release$Value)
896
+ names(vars) <- release$Key
897
+
898
+ # get os name
899
+ os <- tolower(sysinfo[["sysname"]])
900
+
901
+ # read id
902
+ id <- "unknown"
903
+ for (field in c("ID", "ID_LIKE")) {
904
+ if (field %in% names(vars) && nzchar(vars[[field]])) {
905
+ id <- vars[[field]]
906
+ break
907
+ }
908
+ }
909
+
910
+ # read version
911
+ version <- "unknown"
912
+ for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) {
913
+ if (field %in% names(vars) && nzchar(vars[[field]])) {
914
+ version <- vars[[field]]
915
+ break
916
+ }
917
+ }
918
+
919
+ # join together
920
+ paste(c(os, id, version), collapse = "-")
921
+
922
+ }
923
+
924
+ renv_bootstrap_platform_os_via_redhat_release <- function() {
925
+
926
+ # read /etc/redhat-release
927
+ contents <- readLines("/etc/redhat-release", warn = FALSE)
928
+
929
+ # infer id
930
+ id <- if (grepl("centos", contents, ignore.case = TRUE))
931
+ "centos"
932
+ else if (grepl("redhat", contents, ignore.case = TRUE))
933
+ "redhat"
934
+ else
935
+ "unknown"
936
+
937
+ # try to find a version component (very hacky)
938
+ version <- "unknown"
939
+
940
+ parts <- strsplit(contents, "[[:space:]]")[[1L]]
941
+ for (part in parts) {
942
+
943
+ nv <- tryCatch(numeric_version(part), error = identity)
944
+ if (inherits(nv, "error"))
945
+ next
946
+
947
+ version <- nv[1, 1]
948
+ break
949
+
950
+ }
951
+
952
+ paste(c("linux", id, version), collapse = "-")
953
+
954
+ }
955
+
956
+ renv_bootstrap_library_root_name <- function(project) {
957
+
958
+ # use project name as-is if requested
959
+ asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE")
960
+ if (asis)
961
+ return(basename(project))
962
+
963
+ # otherwise, disambiguate based on project's path
964
+ id <- substring(renv_bootstrap_hash_text(project), 1L, 8L)
965
+ paste(basename(project), id, sep = "-")
966
+
967
+ }
968
+
969
+ renv_bootstrap_library_root <- function(project) {
970
+
971
+ prefix <- renv_bootstrap_profile_prefix()
972
+
973
+ path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA)
974
+ if (!is.na(path))
975
+ return(paste(c(path, prefix), collapse = "/"))
976
+
977
+ path <- renv_bootstrap_library_root_impl(project)
978
+ if (!is.null(path)) {
979
+ name <- renv_bootstrap_library_root_name(project)
980
+ return(paste(c(path, prefix, name), collapse = "/"))
981
+ }
982
+
983
+ renv_bootstrap_paths_renv("library", project = project)
984
+
985
+ }
986
+
987
+ renv_bootstrap_library_root_impl <- function(project) {
988
+
989
+ root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
990
+ if (!is.na(root))
991
+ return(root)
992
+
993
+ type <- renv_bootstrap_project_type(project)
994
+ if (identical(type, "package")) {
995
+ userdir <- renv_bootstrap_user_dir()
996
+ return(file.path(userdir, "library"))
997
+ }
998
+
999
+ }
1000
+
1001
+ renv_bootstrap_validate_version <- function(version, description = NULL) {
1002
+
1003
+ # resolve description file
1004
+ #
1005
+ # avoid passing lib.loc to `packageDescription()` below, since R will
1006
+ # use the loaded version of the package by default anyhow. note that
1007
+ # this function should only be called after 'renv' is loaded
1008
+ # https://github.com/rstudio/renv/issues/1625
1009
+ description <- description %||% packageDescription("renv")
1010
+
1011
+ # check whether requested version 'version' matches loaded version of renv
1012
+ sha <- attr(version, "sha", exact = TRUE)
1013
+ valid <- if (!is.null(sha))
1014
+ renv_bootstrap_validate_version_dev(sha, description)
1015
+ else
1016
+ renv_bootstrap_validate_version_release(version, description)
1017
+
1018
+ if (valid)
1019
+ return(TRUE)
1020
+
1021
+ # the loaded version of renv doesn't match the requested version;
1022
+ # give the user instructions on how to proceed
1023
+ dev <- identical(description[["RemoteType"]], "github")
1024
+ remote <- if (dev)
1025
+ paste("rstudio/renv", description[["RemoteSha"]], sep = "@")
1026
+ else
1027
+ paste("renv", description[["Version"]], sep = "@")
1028
+
1029
+ # display both loaded version + sha if available
1030
+ friendly <- renv_bootstrap_version_friendly(
1031
+ version = description[["Version"]],
1032
+ sha = if (dev) description[["RemoteSha"]]
1033
+ )
1034
+
1035
+ fmt <- heredoc("
1036
+ renv %1$s was loaded from project library, but this project is configured to use renv %2$s.
1037
+ - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.
1038
+ - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.
1039
+ ")
1040
+ catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote)
1041
+
1042
+ FALSE
1043
+
1044
+ }
1045
+
1046
+ renv_bootstrap_validate_version_dev <- function(version, description) {
1047
+
1048
+ expected <- description[["RemoteSha"]]
1049
+ if (!is.character(expected))
1050
+ return(FALSE)
1051
+
1052
+ pattern <- sprintf("^\\Q%s\\E", version)
1053
+ grepl(pattern, expected, perl = TRUE)
1054
+
1055
+ }
1056
+
1057
+ renv_bootstrap_validate_version_release <- function(version, description) {
1058
+ expected <- description[["Version"]]
1059
+ is.character(expected) && identical(c(expected), c(version))
1060
+ }
1061
+
1062
+ renv_bootstrap_hash_text <- function(text) {
1063
+
1064
+ hashfile <- tempfile("renv-hash-")
1065
+ on.exit(unlink(hashfile), add = TRUE)
1066
+
1067
+ writeLines(text, con = hashfile)
1068
+ tools::md5sum(hashfile)
1069
+
1070
+ }
1071
+
1072
+ renv_bootstrap_load <- function(project, libpath, version) {
1073
+
1074
+ # try to load renv from the project library
1075
+ if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE))
1076
+ return(FALSE)
1077
+
1078
+ # warn if the version of renv loaded does not match
1079
+ renv_bootstrap_validate_version(version)
1080
+
1081
+ # execute renv load hooks, if any
1082
+ hooks <- getHook("renv::autoload")
1083
+ for (hook in hooks)
1084
+ if (is.function(hook))
1085
+ tryCatch(hook(), error = warnify)
1086
+
1087
+ # load the project
1088
+ renv::load(project)
1089
+
1090
+ TRUE
1091
+
1092
+ }
1093
+
1094
+ renv_bootstrap_profile_load <- function(project) {
1095
+
1096
+ # if RENV_PROFILE is already set, just use that
1097
+ profile <- Sys.getenv("RENV_PROFILE", unset = NA)
1098
+ if (!is.na(profile) && nzchar(profile))
1099
+ return(profile)
1100
+
1101
+ # check for a profile file (nothing to do if it doesn't exist)
1102
+ path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project)
1103
+ if (!file.exists(path))
1104
+ return(NULL)
1105
+
1106
+ # read the profile, and set it if it exists
1107
+ contents <- readLines(path, warn = FALSE)
1108
+ if (length(contents) == 0L)
1109
+ return(NULL)
1110
+
1111
+ # set RENV_PROFILE
1112
+ profile <- contents[[1L]]
1113
+ if (!profile %in% c("", "default"))
1114
+ Sys.setenv(RENV_PROFILE = profile)
1115
+
1116
+ profile
1117
+
1118
+ }
1119
+
1120
+ renv_bootstrap_profile_prefix <- function() {
1121
+ profile <- renv_bootstrap_profile_get()
1122
+ if (!is.null(profile))
1123
+ return(file.path("profiles", profile, "renv"))
1124
+ }
1125
+
1126
+ renv_bootstrap_profile_get <- function() {
1127
+ profile <- Sys.getenv("RENV_PROFILE", unset = "")
1128
+ renv_bootstrap_profile_normalize(profile)
1129
+ }
1130
+
1131
+ renv_bootstrap_profile_set <- function(profile) {
1132
+ profile <- renv_bootstrap_profile_normalize(profile)
1133
+ if (is.null(profile))
1134
+ Sys.unsetenv("RENV_PROFILE")
1135
+ else
1136
+ Sys.setenv(RENV_PROFILE = profile)
1137
+ }
1138
+
1139
+ renv_bootstrap_profile_normalize <- function(profile) {
1140
+
1141
+ if (is.null(profile) || profile %in% c("", "default"))
1142
+ return(NULL)
1143
+
1144
+ profile
1145
+
1146
+ }
1147
+
1148
+ renv_bootstrap_path_absolute <- function(path) {
1149
+
1150
+ substr(path, 1L, 1L) %in% c("~", "/", "\\") || (
1151
+ substr(path, 1L, 1L) %in% c(letters, LETTERS) &&
1152
+ substr(path, 2L, 3L) %in% c(":/", ":\\")
1153
+ )
1154
+
1155
+ }
1156
+
1157
+ renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) {
1158
+ renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv")
1159
+ root <- if (renv_bootstrap_path_absolute(renv)) NULL else project
1160
+ prefix <- if (profile) renv_bootstrap_profile_prefix()
1161
+ components <- c(root, renv, prefix, ...)
1162
+ paste(components, collapse = "/")
1163
+ }
1164
+
1165
+ renv_bootstrap_project_type <- function(path) {
1166
+
1167
+ descpath <- file.path(path, "DESCRIPTION")
1168
+ if (!file.exists(descpath))
1169
+ return("unknown")
1170
+
1171
+ desc <- tryCatch(
1172
+ read.dcf(descpath, all = TRUE),
1173
+ error = identity
1174
+ )
1175
+
1176
+ if (inherits(desc, "error"))
1177
+ return("unknown")
1178
+
1179
+ type <- desc$Type
1180
+ if (!is.null(type))
1181
+ return(tolower(type))
1182
+
1183
+ package <- desc$Package
1184
+ if (!is.null(package))
1185
+ return("package")
1186
+
1187
+ "unknown"
1188
+
1189
+ }
1190
+
1191
+ renv_bootstrap_user_dir <- function() {
1192
+ dir <- renv_bootstrap_user_dir_impl()
1193
+ path.expand(chartr("\\", "/", dir))
1194
+ }
1195
+
1196
+ renv_bootstrap_user_dir_impl <- function() {
1197
+
1198
+ # use local override if set
1199
+ override <- getOption("renv.userdir.override")
1200
+ if (!is.null(override))
1201
+ return(override)
1202
+
1203
+ # use R_user_dir if available
1204
+ tools <- asNamespace("tools")
1205
+ if (is.function(tools$R_user_dir))
1206
+ return(tools$R_user_dir("renv", "cache"))
1207
+
1208
+ # try using our own backfill for older versions of R
1209
+ envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME")
1210
+ for (envvar in envvars) {
1211
+ root <- Sys.getenv(envvar, unset = NA)
1212
+ if (!is.na(root))
1213
+ return(file.path(root, "R/renv"))
1214
+ }
1215
+
1216
+ # use platform-specific default fallbacks
1217
+ if (Sys.info()[["sysname"]] == "Windows")
1218
+ file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv")
1219
+ else if (Sys.info()[["sysname"]] == "Darwin")
1220
+ "~/Library/Caches/org.R-project.R/R/renv"
1221
+ else
1222
+ "~/.cache/R/renv"
1223
+
1224
+ }
1225
+
1226
+ renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) {
1227
+ sha <- sha %||% attr(version, "sha", exact = TRUE)
1228
+ parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L)))
1229
+ paste(parts, collapse = "")
1230
+ }
1231
+
1232
+ renv_bootstrap_exec <- function(project, libpath, version) {
1233
+ if (!renv_bootstrap_load(project, libpath, version))
1234
+ renv_bootstrap_run(project, libpath, version)
1235
+ }
1236
+
1237
+ renv_bootstrap_run <- function(project, libpath, version) {
1238
+ tryCatch(
1239
+ renv_bootstrap_run_impl(project, libpath, version),
1240
+ error = function(e) {
1241
+ msg <- paste(
1242
+ "failed to bootstrap renv: the project will not be loaded.",
1243
+ paste("Reason:", conditionMessage(e)),
1244
+ "Use `renv::activate()` to re-initialize the project.",
1245
+ sep = "\n"
1246
+ )
1247
+ warning(msg, call. = FALSE)
1248
+ }
1249
+ )
1250
+ }
1251
+
1252
+ renv_bootstrap_run_impl <- function(project, libpath, version) {
1253
+
1254
+ # perform bootstrap
1255
+ bootstrap(version, libpath)
1256
+
1257
+ # exit early if we're just testing bootstrap
1258
+ if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
1259
+ return(TRUE)
1260
+
1261
+ # try again to load
1262
+ if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
1263
+ return(renv::load(project = project))
1264
+ }
1265
+
1266
+ # failed to download or load renv; warn the user
1267
+ msg <- c(
1268
+ "Failed to find an renv installation: the project will not be loaded.",
1269
+ "Use `renv::activate()` to re-initialize the project."
1270
+ )
1271
+
1272
+ warning(paste(msg, collapse = "\n"), call. = FALSE)
1273
+
1274
+ }
1275
+
1276
+ renv_bootstrap_cache_version <- function() {
1277
+ # NOTE: users should normally not override the cache version;
1278
+ # this is provided just to make testing easier
1279
+ Sys.getenv("RENV_CACHE_VERSION", unset = "v5")
1280
+ }
1281
+
1282
+ renv_bootstrap_cache_version_previous <- function() {
1283
+ version <- renv_bootstrap_cache_version()
1284
+ number <- as.integer(substring(version, 2L))
1285
+ paste("v", number - 1L, sep = "")
1286
+ }
1287
+
1288
+ renv_json_read <- function(file = NULL, text = NULL) {
1289
+
1290
+ jlerr <- NULL
1291
+
1292
+ # if jsonlite is loaded, use that instead
1293
+ if ("jsonlite" %in% loadedNamespaces()) {
1294
+
1295
+ json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity)
1296
+ if (!inherits(json, "error"))
1297
+ return(json)
1298
+
1299
+ jlerr <- json
1300
+
1301
+ }
1302
+
1303
+ # otherwise, fall back to the default JSON reader
1304
+ json <- tryCatch(renv_json_read_default(file, text), error = identity)
1305
+ if (!inherits(json, "error"))
1306
+ return(json)
1307
+
1308
+ # report an error
1309
+ if (!is.null(jlerr))
1310
+ stop(jlerr)
1311
+ else
1312
+ stop(json)
1313
+
1314
+ }
1315
+
1316
+ renv_json_read_jsonlite <- function(file = NULL, text = NULL) {
1317
+ text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n")
1318
+ jsonlite::fromJSON(txt = text, simplifyVector = FALSE)
1319
+ }
1320
+
1321
+ renv_json_read_patterns <- function() {
1322
+
1323
+ list(
1324
+
1325
+ # objects
1326
+ list("{", "\t\n\tobject(\t\n\t", TRUE),
1327
+ list("}", "\t\n\t)\t\n\t", TRUE),
1328
+
1329
+ # arrays
1330
+ list("[", "\t\n\tarray(\t\n\t", TRUE),
1331
+ list("]", "\n\t\n)\n\t\n", TRUE),
1332
+
1333
+ # maps
1334
+ list(":", "\t\n\t=\t\n\t", TRUE),
1335
+
1336
+ # newlines
1337
+ list("\\u000a", "\n", FALSE)
1338
+
1339
+ )
1340
+
1341
+ }
1342
+
1343
+ renv_json_read_envir <- function() {
1344
+
1345
+ envir <- new.env(parent = emptyenv())
1346
+
1347
+ envir[["+"]] <- `+`
1348
+ envir[["-"]] <- `-`
1349
+
1350
+ envir[["object"]] <- function(...) {
1351
+ result <- list(...)
1352
+ names(result) <- as.character(names(result))
1353
+ result
1354
+ }
1355
+
1356
+ envir[["array"]] <- list
1357
+
1358
+ envir[["true"]] <- TRUE
1359
+ envir[["false"]] <- FALSE
1360
+ envir[["null"]] <- NULL
1361
+
1362
+ envir
1363
+
1364
+ }
1365
+
1366
+ renv_json_read_remap <- function(object, patterns) {
1367
+
1368
+ # repair names if necessary
1369
+ if (!is.null(names(object))) {
1370
+
1371
+ nms <- names(object)
1372
+ for (pattern in patterns)
1373
+ nms <- gsub(pattern[[2L]], pattern[[1L]], nms, fixed = TRUE)
1374
+ names(object) <- nms
1375
+
1376
+ }
1377
+
1378
+ # repair strings if necessary
1379
+ if (is.character(object)) {
1380
+ for (pattern in patterns)
1381
+ object <- gsub(pattern[[2L]], pattern[[1L]], object, fixed = TRUE)
1382
+ }
1383
+
1384
+ # recurse for other objects
1385
+ if (is.recursive(object))
1386
+ for (i in seq_along(object))
1387
+ object[i] <- list(renv_json_read_remap(object[[i]], patterns))
1388
+
1389
+ # return remapped object
1390
+ object
1391
+
1392
+ }
1393
+
1394
+ renv_json_read_default <- function(file = NULL, text = NULL) {
1395
+
1396
+ # read json text
1397
+ text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n")
1398
+
1399
+ # convert into something the R parser will understand
1400
+ patterns <- renv_json_read_patterns()
1401
+ transformed <- text
1402
+ for (pattern in patterns)
1403
+ transformed <- gsub(pattern[[1L]], pattern[[2L]], transformed, fixed = TRUE)
1404
+
1405
+ # parse it
1406
+ rfile <- tempfile("renv-json-", fileext = ".R")
1407
+ on.exit(unlink(rfile), add = TRUE)
1408
+ writeLines(transformed, con = rfile)
1409
+ json <- parse(rfile, keep.source = FALSE, srcfile = NULL)[[1L]]
1410
+
1411
+ # evaluate in safe environment
1412
+ result <- eval(json, envir = renv_json_read_envir())
1413
+
1414
+ # fix up strings if necessary -- do so only with reversible patterns
1415
+ patterns <- Filter(function(pattern) pattern[[3L]], patterns)
1416
+ renv_json_read_remap(result, patterns)
1417
+
1418
+ }
1419
+
1420
+
1421
+ # load the renv profile, if any
1422
+ renv_bootstrap_profile_load(project)
1423
+
1424
+ # construct path to library root
1425
+ root <- renv_bootstrap_library_root(project)
1426
+
1427
+ # construct library prefix for platform
1428
+ prefix <- renv_bootstrap_platform_prefix()
1429
+
1430
+ # construct full libpath
1431
+ libpath <- file.path(root, prefix)
1432
+
1433
+ # run bootstrap code
1434
+ renv_bootstrap_exec(project, libpath, version)
1435
+
1436
+ invisible()
1437
+
1438
+ })
renv/settings.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bioconductor.version": null,
3
+ "external.libraries": [],
4
+ "ignored.packages": [],
5
+ "package.dependency.fields": [
6
+ "Imports",
7
+ "Depends",
8
+ "LinkingTo"
9
+ ],
10
+ "ppm.enabled": null,
11
+ "ppm.ignored.urls": [],
12
+ "r.version": null,
13
+ "snapshot.dev": false,
14
+ "snapshot.type": "implicit",
15
+ "use.cache": true,
16
+ "vcs.ignore.cellar": true,
17
+ "vcs.ignore.library": true,
18
+ "vcs.ignore.local": true,
19
+ "vcs.manage.ignores": true
20
+ }