2
2
local({
3
3
4
4
# the requested version of renv
5
- version <- " 1.0.3 "
5
+ version <- " 1.0.11 "
6
6
attr(version , " sha" ) <- NULL
7
7
8
8
# the project directory
9
- project <- getwd()
9
+ project <- Sys.getenv(" RENV_PROJECT" )
10
+ if (! nzchar(project ))
11
+ project <- getwd()
10
12
11
13
# use start-up diagnostics if enabled
12
14
diagnostics <- Sys.getenv(" RENV_STARTUP_DIAGNOSTICS" , unset = " FALSE" )
@@ -31,6 +33,14 @@ local({
31
33
if (! is.null(override ))
32
34
return (override )
33
35
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
+
34
44
# next, check environment variables
35
45
# TODO: prefer using the configuration one in the future
36
46
envvars <- c(
@@ -50,9 +60,22 @@ local({
50
60
51
61
})
52
62
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
+
54
75
return (FALSE )
55
76
77
+ }
78
+
56
79
# avoid recursion
57
80
if (identical(getOption(" renv.autoloader.running" ), TRUE )) {
58
81
warning(" ignoring recursive attempt to run renv autoloader" )
@@ -75,6 +98,66 @@ local({
75
98
unloadNamespace(" renv" )
76
99
77
100
# 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
+
78
161
`%||%` <- function (x , y ) {
79
162
if (is.null(x )) y else x
80
163
}
@@ -108,6 +191,24 @@ local({
108
191
109
192
}
110
193
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
+
111
212
startswith <- function (string , prefix ) {
112
213
substring(string , 1 , nchar(prefix )) == prefix
113
214
}
@@ -267,8 +368,11 @@ local({
267
368
quiet = TRUE
268
369
)
269
370
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
+ }
272
376
273
377
do.call(utils :: download.file , args )
274
378
@@ -347,10 +451,21 @@ local({
347
451
for (type in types ) {
348
452
for (repos in renv_bootstrap_repos()) {
349
453
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
+
350
465
# retrieve package database
351
466
db <- tryCatch(
352
467
as.data.frame(
353
- utils :: available.packages( type = type , repos = repos ),
468
+ do.call( utils :: available.packages , args ),
354
469
stringsAsFactors = FALSE
355
470
),
356
471
error = identity
@@ -432,23 +547,31 @@ local({
432
547
433
548
}
434
549
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
+
435
558
renv_bootstrap_download_github <- function (version ) {
436
559
437
560
enabled <- Sys.getenv(" RENV_BOOTSTRAP_FROM_GITHUB" , unset = " TRUE" )
438
561
if (! identical(enabled , " TRUE" ))
439
562
return (FALSE )
440
563
441
564
# 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 )) {
444
567
fmt <- " --location --fail --header \" Authorization: token %s\" "
445
- extra <- sprintf(fmt , pat )
568
+ extra <- sprintf(fmt , token )
446
569
saved <- options(" download.file.method" , " download.file.extra" )
447
570
options(download.file.method = " curl" , download.file.extra = extra )
448
571
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 )) {
450
573
fmt <- " --header=\" Authorization: token %s\" "
451
- extra <- sprintf(fmt , pat )
574
+ extra <- sprintf(fmt , token )
452
575
saved <- options(" download.file.method" , " download.file.extra" )
453
576
options(download.file.method = " wget" , download.file.extra = extra )
454
577
on.exit(do.call(base :: options , saved ), add = TRUE )
@@ -610,6 +733,9 @@ local({
610
733
611
734
# if the user has requested an automatic prefix, generate it
612
735
auto <- Sys.getenv(" RENV_PATHS_PREFIX_AUTO" , unset = NA )
736
+ if (is.na(auto ) && getRversion() > = " 4.4.0" )
737
+ auto <- " TRUE"
738
+
613
739
if (auto %in% c(" TRUE" , " True" , " true" , " 1" ))
614
740
return (renv_bootstrap_platform_prefix_auto())
615
741
@@ -801,24 +927,23 @@ local({
801
927
802
928
# the loaded version of renv doesn't match the requested version;
803
929
# 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 )
805
932
paste(" rstudio/renv" , description [[" RemoteSha" ]], sep = " @" )
806
- } else {
933
+ else
807
934
paste(" renv" , description [[" Version" ]], sep = " @" )
808
- }
809
935
810
936
# display both loaded version + sha if available
811
937
friendly <- renv_bootstrap_version_friendly(
812
938
version = description [[" Version" ]],
813
- sha = description [[" RemoteSha" ]]
939
+ sha = if ( dev ) description [[" RemoteSha" ]]
814
940
)
815
941
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
+ " )
822
947
catf(fmt , friendly , renv_bootstrap_version_friendly(version ), remote )
823
948
824
949
FALSE
@@ -1041,7 +1166,7 @@ local({
1041
1166
# if jsonlite is loaded, use that instead
1042
1167
if (" jsonlite" %in% loadedNamespaces()) {
1043
1168
1044
- json <- catch (renv_json_read_jsonlite(file , text ))
1169
+ json <- tryCatch (renv_json_read_jsonlite(file , text ), error = identity )
1045
1170
if (! inherits(json , " error" ))
1046
1171
return (json )
1047
1172
@@ -1050,7 +1175,7 @@ local({
1050
1175
}
1051
1176
1052
1177
# 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 )
1054
1179
if (! inherits(json , " error" ))
1055
1180
return (json )
1056
1181
@@ -1063,14 +1188,14 @@ local({
1063
1188
}
1064
1189
1065
1190
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 " )
1067
1192
jsonlite :: fromJSON(txt = text , simplifyVector = FALSE )
1068
1193
}
1069
1194
1070
1195
renv_json_read_default <- function (file = NULL , text = NULL ) {
1071
1196
1072
1197
# find strings in the JSON
1073
- text <- paste(text %|| % read (file ), collapse = " \n " )
1198
+ text <- paste(text %|| % readLines (file , warn = FALSE ), collapse = " \n " )
1074
1199
pattern <- ' ["](?:(?:\\\\ .)|(?:[^"\\\\ ]))*?["]'
1075
1200
locs <- gregexpr(pattern , text , perl = TRUE )[[1 ]]
1076
1201
@@ -1118,14 +1243,14 @@ local({
1118
1243
map <- as.list(map )
1119
1244
1120
1245
# remap strings in object
1121
- remapped <- renv_json_remap (json , map )
1246
+ remapped <- renv_json_read_remap (json , map )
1122
1247
1123
1248
# evaluate
1124
1249
eval(remapped , envir = baseenv())
1125
1250
1126
1251
}
1127
1252
1128
- renv_json_remap <- function (json , map ) {
1253
+ renv_json_read_remap <- function (json , map ) {
1129
1254
1130
1255
# fix names
1131
1256
if (! is.null(names(json ))) {
@@ -1152,7 +1277,7 @@ local({
1152
1277
# recurse
1153
1278
if (is.recursive(json )) {
1154
1279
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 ))
1156
1281
}
1157
1282
}
1158
1283
0 commit comments