22local({
33
44 # the requested version of renv
5- version <- " 1.0.3 "
5+ version <- " 1.0.11 "
66 attr(version , " sha" ) <- NULL
77
88 # the project directory
9- project <- getwd()
9+ project <- Sys.getenv(" RENV_PROJECT" )
10+ if (! nzchar(project ))
11+ project <- getwd()
1012
1113 # use start-up diagnostics if enabled
1214 diagnostics <- Sys.getenv(" RENV_STARTUP_DIAGNOSTICS" , unset = " FALSE" )
@@ -31,6 +33,14 @@ local({
3133 if (! is.null(override ))
3234 return (override )
3335
36+ # if we're being run in a context where R_LIBS is already set,
37+ # don't load -- presumably we're being run as a sub-process and
38+ # the parent process has already set up library paths for us
39+ rcmd <- Sys.getenv(" R_CMD" , unset = NA )
40+ rlibs <- Sys.getenv(" R_LIBS" , unset = NA )
41+ if (! is.na(rlibs ) && ! is.na(rcmd ))
42+ return (FALSE )
43+
3444 # next, check environment variables
3545 # TODO: prefer using the configuration one in the future
3646 envvars <- c(
@@ -50,9 +60,22 @@ local({
5060
5161 })
5262
53- if (! enabled )
63+ # bail if we're not enabled
64+ if (! enabled ) {
65+
66+ # if we're not enabled, we might still need to manually load
67+ # the user profile here
68+ profile <- Sys.getenv(" R_PROFILE_USER" , unset = " ~/.Rprofile" )
69+ if (file.exists(profile )) {
70+ cfg <- Sys.getenv(" RENV_CONFIG_USER_PROFILE" , unset = " TRUE" )
71+ if (tolower(cfg ) %in% c(" true" , " t" , " 1" ))
72+ sys.source(profile , envir = globalenv())
73+ }
74+
5475 return (FALSE )
5576
77+ }
78+
5679 # avoid recursion
5780 if (identical(getOption(" renv.autoloader.running" ), TRUE )) {
5881 warning(" ignoring recursive attempt to run renv autoloader" )
@@ -75,6 +98,66 @@ local({
7598 unloadNamespace(" renv" )
7699
77100 # load bootstrap tools
101+ ansify <- function (text ) {
102+ if (renv_ansify_enabled())
103+ renv_ansify_enhanced(text )
104+ else
105+ renv_ansify_default(text )
106+ }
107+
108+ renv_ansify_enabled <- function () {
109+
110+ override <- Sys.getenv(" RENV_ANSIFY_ENABLED" , unset = NA )
111+ if (! is.na(override ))
112+ return (as.logical(override ))
113+
114+ pane <- Sys.getenv(" RSTUDIO_CHILD_PROCESS_PANE" , unset = NA )
115+ if (identical(pane , " build" ))
116+ return (FALSE )
117+
118+ testthat <- Sys.getenv(" TESTTHAT" , unset = " false" )
119+ if (tolower(testthat ) %in% " true" )
120+ return (FALSE )
121+
122+ iderun <- Sys.getenv(" R_CLI_HAS_HYPERLINK_IDE_RUN" , unset = " false" )
123+ if (tolower(iderun ) %in% " false" )
124+ return (FALSE )
125+
126+ TRUE
127+
128+ }
129+
130+ renv_ansify_default <- function (text ) {
131+ text
132+ }
133+
134+ renv_ansify_enhanced <- function (text ) {
135+
136+ # R help links
137+ pattern <- " `\\ ?(renv::(?:[^`])+)`"
138+ replacement <- " `\0 33]8;;ide:help:\\ 1\a ?\\ 1\0 33]8;;\a `"
139+ text <- gsub(pattern , replacement , text , perl = TRUE )
140+
141+ # runnable code
142+ pattern <- " `(renv::(?:[^`])+)`"
143+ replacement <- " `\0 33]8;;ide:run:\\ 1\a\\ 1\0 33]8;;\a `"
144+ text <- gsub(pattern , replacement , text , perl = TRUE )
145+
146+ # return ansified text
147+ text
148+
149+ }
150+
151+ renv_ansify_init <- function () {
152+
153+ envir <- renv_envir_self()
154+ if (renv_ansify_enabled())
155+ assign(" ansify" , renv_ansify_enhanced , envir = envir )
156+ else
157+ assign(" ansify" , renv_ansify_default , envir = envir )
158+
159+ }
160+
78161 `%||%` <- function (x , y ) {
79162 if (is.null(x )) y else x
80163 }
@@ -108,6 +191,24 @@ local({
108191
109192 }
110193
194+ heredoc <- function (text , leave = 0 ) {
195+
196+ # remove leading, trailing whitespace
197+ trimmed <- gsub(" ^\\ s*\\ n|\\ n\\ s*$" , " " , text )
198+
199+ # split into lines
200+ lines <- strsplit(trimmed , " \n " , fixed = TRUE )[[1L ]]
201+
202+ # compute common indent
203+ indent <- regexpr(" [^[:space:]]" , lines )
204+ common <- min(setdiff(indent , - 1L )) - leave
205+ text <- paste(substring(lines , common ), collapse = " \n " )
206+
207+ # substitute in ANSI links for executable renv code
208+ ansify(text )
209+
210+ }
211+
111212 startswith <- function (string , prefix ) {
112213 substring(string , 1 , nchar(prefix )) == prefix
113214 }
@@ -267,8 +368,11 @@ local({
267368 quiet = TRUE
268369 )
269370
270- if (" headers" %in% names(formals(utils :: download.file )))
271- args $ headers <- renv_bootstrap_download_custom_headers(url )
371+ if (" headers" %in% names(formals(utils :: download.file ))) {
372+ headers <- renv_bootstrap_download_custom_headers(url )
373+ if (length(headers ) && is.character(headers ))
374+ args $ headers <- headers
375+ }
272376
273377 do.call(utils :: download.file , args )
274378
@@ -347,10 +451,21 @@ local({
347451 for (type in types ) {
348452 for (repos in renv_bootstrap_repos()) {
349453
454+ # build arguments for utils::available.packages() call
455+ args <- list (type = type , repos = repos )
456+
457+ # add custom headers if available -- note that
458+ # utils::available.packages() will pass this to download.file()
459+ if (" headers" %in% names(formals(utils :: download.file ))) {
460+ headers <- renv_bootstrap_download_custom_headers(repos )
461+ if (length(headers ) && is.character(headers ))
462+ args $ headers <- headers
463+ }
464+
350465 # retrieve package database
351466 db <- tryCatch(
352467 as.data.frame(
353- utils :: available.packages( type = type , repos = repos ),
468+ do.call( utils :: available.packages , args ),
354469 stringsAsFactors = FALSE
355470 ),
356471 error = identity
@@ -432,23 +547,31 @@ local({
432547
433548 }
434549
550+ renv_bootstrap_github_token <- function () {
551+ for (envvar in c(" GITHUB_TOKEN" , " GITHUB_PAT" , " GH_TOKEN" )) {
552+ envval <- Sys.getenv(envvar , unset = NA )
553+ if (! is.na(envval ))
554+ return (envval )
555+ }
556+ }
557+
435558 renv_bootstrap_download_github <- function (version ) {
436559
437560 enabled <- Sys.getenv(" RENV_BOOTSTRAP_FROM_GITHUB" , unset = " TRUE" )
438561 if (! identical(enabled , " TRUE" ))
439562 return (FALSE )
440563
441564 # prepare download options
442- pat <- Sys.getenv( " GITHUB_PAT " )
443- if (nzchar(Sys.which(" curl" )) && nzchar(pat )) {
565+ token <- renv_bootstrap_github_token( )
566+ if (nzchar(Sys.which(" curl" )) && nzchar(token )) {
444567 fmt <- " --location --fail --header \" Authorization: token %s\" "
445- extra <- sprintf(fmt , pat )
568+ extra <- sprintf(fmt , token )
446569 saved <- options(" download.file.method" , " download.file.extra" )
447570 options(download.file.method = " curl" , download.file.extra = extra )
448571 on.exit(do.call(base :: options , saved ), add = TRUE )
449- } else if (nzchar(Sys.which(" wget" )) && nzchar(pat )) {
572+ } else if (nzchar(Sys.which(" wget" )) && nzchar(token )) {
450573 fmt <- " --header=\" Authorization: token %s\" "
451- extra <- sprintf(fmt , pat )
574+ extra <- sprintf(fmt , token )
452575 saved <- options(" download.file.method" , " download.file.extra" )
453576 options(download.file.method = " wget" , download.file.extra = extra )
454577 on.exit(do.call(base :: options , saved ), add = TRUE )
@@ -610,6 +733,9 @@ local({
610733
611734 # if the user has requested an automatic prefix, generate it
612735 auto <- Sys.getenv(" RENV_PATHS_PREFIX_AUTO" , unset = NA )
736+ if (is.na(auto ) && getRversion() > = " 4.4.0" )
737+ auto <- " TRUE"
738+
613739 if (auto %in% c(" TRUE" , " True" , " true" , " 1" ))
614740 return (renv_bootstrap_platform_prefix_auto())
615741
@@ -801,24 +927,23 @@ local({
801927
802928 # the loaded version of renv doesn't match the requested version;
803929 # give the user instructions on how to proceed
804- remote <- if (! is.null(description [[" RemoteSha" ]])) {
930+ dev <- identical(description [[" RemoteType" ]], " github" )
931+ remote <- if (dev )
805932 paste(" rstudio/renv" , description [[" RemoteSha" ]], sep = " @" )
806- } else {
933+ else
807934 paste(" renv" , description [[" Version" ]], sep = " @" )
808- }
809935
810936 # display both loaded version + sha if available
811937 friendly <- renv_bootstrap_version_friendly(
812938 version = description [[" Version" ]],
813- sha = description [[" RemoteSha" ]]
939+ sha = if ( dev ) description [[" RemoteSha" ]]
814940 )
815941
816- fmt <- paste(
817- " renv %1$s was loaded from project library, but this project is configured to use renv %2$s." ,
818- " - Use `renv::record(\" %3$s\" )` to record renv %1$s in the lockfile." ,
819- " - Use `renv::restore(packages = \" renv\" )` to install renv %2$s into the project library." ,
820- sep = " \n "
821- )
942+ fmt <- heredoc("
943+ renv %1$s was loaded from project library, but this project is configured to use renv %2$s.
944+ - Use `renv::record(\" %3$s\" )` to record renv %1$s in the lockfile.
945+ - Use `renv::restore(packages = \" renv\" )` to install renv %2$s into the project library.
946+ " )
822947 catf(fmt , friendly , renv_bootstrap_version_friendly(version ), remote )
823948
824949 FALSE
@@ -1041,7 +1166,7 @@ local({
10411166 # if jsonlite is loaded, use that instead
10421167 if (" jsonlite" %in% loadedNamespaces()) {
10431168
1044- json <- catch (renv_json_read_jsonlite(file , text ))
1169+ json <- tryCatch (renv_json_read_jsonlite(file , text ), error = identity )
10451170 if (! inherits(json , " error" ))
10461171 return (json )
10471172
@@ -1050,7 +1175,7 @@ local({
10501175 }
10511176
10521177 # otherwise, fall back to the default JSON reader
1053- json <- catch (renv_json_read_default(file , text ))
1178+ json <- tryCatch (renv_json_read_default(file , text ), error = identity )
10541179 if (! inherits(json , " error" ))
10551180 return (json )
10561181
@@ -1063,14 +1188,14 @@ local({
10631188 }
10641189
10651190 renv_json_read_jsonlite <- function (file = NULL , text = NULL ) {
1066- text <- paste(text %|| % read (file ), collapse = " \n " )
1191+ text <- paste(text %|| % readLines (file , warn = FALSE ), collapse = " \n " )
10671192 jsonlite :: fromJSON(txt = text , simplifyVector = FALSE )
10681193 }
10691194
10701195 renv_json_read_default <- function (file = NULL , text = NULL ) {
10711196
10721197 # find strings in the JSON
1073- text <- paste(text %|| % read (file ), collapse = " \n " )
1198+ text <- paste(text %|| % readLines (file , warn = FALSE ), collapse = " \n " )
10741199 pattern <- ' ["](?:(?:\\\\ .)|(?:[^"\\\\ ]))*?["]'
10751200 locs <- gregexpr(pattern , text , perl = TRUE )[[1 ]]
10761201
@@ -1118,14 +1243,14 @@ local({
11181243 map <- as.list(map )
11191244
11201245 # remap strings in object
1121- remapped <- renv_json_remap (json , map )
1246+ remapped <- renv_json_read_remap (json , map )
11221247
11231248 # evaluate
11241249 eval(remapped , envir = baseenv())
11251250
11261251 }
11271252
1128- renv_json_remap <- function (json , map ) {
1253+ renv_json_read_remap <- function (json , map ) {
11291254
11301255 # fix names
11311256 if (! is.null(names(json ))) {
@@ -1152,7 +1277,7 @@ local({
11521277 # recurse
11531278 if (is.recursive(json )) {
11541279 for (i in seq_along(json )) {
1155- json [i ] <- list (renv_json_remap (json [[i ]], map ))
1280+ json [i ] <- list (renv_json_read_remap (json [[i ]], map ))
11561281 }
11571282 }
11581283
0 commit comments