22local({
33
44 # the requested version of renv
5- version <- " 1.0.11 "
5+ version <- " 1.1.5 "
66 attr(version , " sha" ) <- NULL
77
88 # the project directory
@@ -42,7 +42,7 @@ local({
4242 return (FALSE )
4343
4444 # next, check environment variables
45- # TODO: prefer using the configuration one in the future
45+ # prefer using the configuration one in the future
4646 envvars <- c(
4747 " RENV_CONFIG_AUTOLOADER_ENABLED" ,
4848 " RENV_AUTOLOADER_ENABLED" ,
@@ -135,12 +135,12 @@ local({
135135
136136 # R help links
137137 pattern <- " `\\ ?(renv::(?:[^`])+)`"
138- replacement <- " `\0 33]8;;ide: help:\\ 1\a ?\\ 1\0 33]8;;\a `"
138+ replacement <- " `\0 33]8;;x-r- help:\\ 1\a ?\\ 1\0 33]8;;\a `"
139139 text <- gsub(pattern , replacement , text , perl = TRUE )
140140
141141 # runnable code
142142 pattern <- " `(renv::(?:[^`])+)`"
143- replacement <- " `\0 33]8;;ide: run:\\ 1\a\\ 1\0 33]8;;\a `"
143+ replacement <- " `\0 33]8;;x-r- run:\\ 1\a\\ 1\0 33]8;;\a `"
144144 text <- gsub(pattern , replacement , text , perl = TRUE )
145145
146146 # return ansified text
@@ -209,10 +209,6 @@ local({
209209
210210 }
211211
212- startswith <- function (string , prefix ) {
213- substring(string , 1 , nchar(prefix )) == prefix
214- }
215-
216212 bootstrap <- function (version , library ) {
217213
218214 friendly <- renv_bootstrap_version_friendly(version )
@@ -563,6 +559,9 @@ local({
563559
564560 # prepare download options
565561 token <- renv_bootstrap_github_token()
562+ if (is.null(token ))
563+ token <- " "
564+
566565 if (nzchar(Sys.which(" curl" )) && nzchar(token )) {
567566 fmt <- " --location --fail --header \" Authorization: token %s\" "
568567 extra <- sprintf(fmt , token )
@@ -696,11 +695,19 @@ local({
696695
697696 }
698697
699- renv_bootstrap_platform_prefix <- function () {
698+ renv_bootstrap_platform_prefix_default <- function () {
700699
701- # construct version prefix
702- version <- paste(R.version $ major , R.version $ minor , sep = " ." )
703- prefix <- paste(" R" , numeric_version(version )[1 , 1 : 2 ], sep = " -" )
700+ # read version component
701+ version <- Sys.getenv(" RENV_PATHS_VERSION" , unset = " R-%v" )
702+
703+ # expand placeholders
704+ placeholders <- list (
705+ list (" %v" , format(getRversion()[1 , 1 : 2 ])),
706+ list (" %V" , format(getRversion()[1 , 1 : 3 ]))
707+ )
708+
709+ for (placeholder in placeholders )
710+ version <- gsub(placeholder [[1L ]], placeholder [[2L ]], version , fixed = TRUE )
704711
705712 # include SVN revision for development versions of R
706713 # (to avoid sharing platform-specific artefacts with released versions of R)
@@ -709,10 +716,19 @@ local({
709716 identical(R.version [[" nickname" ]], " Unsuffered Consequences" )
710717
711718 if (devel )
712- prefix <- paste(prefix , R.version [[" svn rev" ]], sep = " -r" )
719+ version <- paste(version , R.version [[" svn rev" ]], sep = " -r" )
720+
721+ version
722+
723+ }
724+
725+ renv_bootstrap_platform_prefix <- function () {
726+
727+ # construct version prefix
728+ version <- renv_bootstrap_platform_prefix_default()
713729
714730 # build list of path components
715- components <- c(prefix , R.version $ platform )
731+ components <- c(version , R.version $ platform )
716732
717733 # include prefix if provided by user
718734 prefix <- renv_bootstrap_platform_prefix_impl()
@@ -951,8 +967,14 @@ local({
951967 }
952968
953969 renv_bootstrap_validate_version_dev <- function (version , description ) {
970+
954971 expected <- description [[" RemoteSha" ]]
955- is.character(expected ) && startswith(expected , version )
972+ if (! is.character(expected ))
973+ return (FALSE )
974+
975+ pattern <- sprintf(" ^\\ Q%s\\ E" , version )
976+ grepl(pattern , expected , perl = TRUE )
977+
956978 }
957979
958980 renv_bootstrap_validate_version_release <- function (version , description ) {
@@ -1132,10 +1154,10 @@ local({
11321154
11331155 renv_bootstrap_exec <- function (project , libpath , version ) {
11341156 if (! renv_bootstrap_load(project , libpath , version ))
1135- renv_bootstrap_run(version , libpath )
1157+ renv_bootstrap_run(project , libpath , version )
11361158 }
11371159
1138- renv_bootstrap_run <- function (version , libpath ) {
1160+ renv_bootstrap_run <- function (project , libpath , version ) {
11391161
11401162 # perform bootstrap
11411163 bootstrap(version , libpath )
@@ -1146,7 +1168,7 @@ local({
11461168
11471169 # try again to load
11481170 if (requireNamespace(" renv" , lib.loc = libpath , quietly = TRUE )) {
1149- return (renv :: load(project = getwd() ))
1171+ return (renv :: load(project = project ))
11501172 }
11511173
11521174 # failed to download or load renv; warn the user
@@ -1192,98 +1214,105 @@ local({
11921214 jsonlite :: fromJSON(txt = text , simplifyVector = FALSE )
11931215 }
11941216
1195- renv_json_read_default <- function (file = NULL , text = NULL ) {
1217+ renv_json_read_patterns <- function () {
11961218
1197- # find strings in the JSON
1198- text <- paste(text %|| % readLines(file , warn = FALSE ), collapse = " \n " )
1199- pattern <- ' ["](?:(?:\\\\ .)|(?:[^"\\\\ ]))*?["]'
1200- locs <- gregexpr(pattern , text , perl = TRUE )[[1 ]]
1219+ list (
12011220
1202- # if any are found, replace them with placeholders
1203- replaced <- text
1204- strings <- character ()
1205- replacements <- character ()
1221+ # objects
1222+ list (" {" , " \t\n\t object(\t\n\t " , TRUE ),
1223+ list (" }" , " \t\n\t )\t\n\t " , TRUE ),
12061224
1207- if (! identical(c(locs ), - 1L )) {
1225+ # arrays
1226+ list (" [" , " \t\n\t array(\t\n\t " , TRUE ),
1227+ list (" ]" , " \n\t\n )\n\t\n " , TRUE ),
12081228
1209- # get the string values
1210- starts <- locs
1211- ends <- locs + attr(locs , " match.length" ) - 1L
1212- strings <- substring(text , starts , ends )
1229+ # maps
1230+ list (" :" , " \t\n\t =\t\n\t " , TRUE ),
12131231
1214- # only keep those requiring escaping
1215- strings <- grep( " [[ \\ ]{}:] " , strings , perl = TRUE , value = TRUE )
1232+ # newlines
1233+ list ( " \\ u000a " , " \n " , FALSE )
12161234
1217- # compute replacements
1218- replacements <- sprintf(' "\0 32%i\0 32"' , seq_along(strings ))
1235+ )
12191236
1220- # replace the strings
1221- mapply(function (string , replacement ) {
1222- replaced <<- sub(string , replacement , replaced , fixed = TRUE )
1223- }, strings , replacements )
1237+ }
12241238
1225- }
1239+ renv_json_read_envir <- function () {
12261240
1227- # transform the JSON into something the R parser understands
1228- transformed <- replaced
1229- transformed <- gsub(" {}" , " `names<-`(list(), character())" , transformed , fixed = TRUE )
1230- transformed <- gsub(" [[{]" , " list(" , transformed , perl = TRUE )
1231- transformed <- gsub(" []}]" , " )" , transformed , perl = TRUE )
1232- transformed <- gsub(" :" , " =" , transformed , fixed = TRUE )
1233- text <- paste(transformed , collapse = " \n " )
1241+ envir <- new.env(parent = emptyenv())
12341242
1235- # parse it
1236- json <- parse( text = text , keep.source = FALSE , srcfile = NULL )[[ 1L ]]
1243+ envir [[ " + " ]] <- `+`
1244+ envir [[ " - " ]] <- `-`
12371245
1238- # construct map between source strings, replaced strings
1239- map <- as.character(parse(text = strings ))
1240- names(map ) <- as.character(parse(text = replacements ))
1246+ envir [[" object" ]] <- function (... ) {
1247+ result <- list (... )
1248+ names(result ) <- as.character(names(result ))
1249+ result
1250+ }
12411251
1242- # convert to list
1243- map <- as.list(map )
1252+ envir [[" array" ]] <- list
12441253
1245- # remap strings in object
1246- remapped <- renv_json_read_remap(json , map )
1254+ envir [[" true" ]] <- TRUE
1255+ envir [[" false" ]] <- FALSE
1256+ envir [[" null" ]] <- NULL
12471257
1248- # evaluate
1249- eval(remapped , envir = baseenv())
1258+ envir
12501259
12511260 }
12521261
1253- renv_json_read_remap <- function (json , map ) {
1262+ renv_json_read_remap <- function (object , patterns ) {
12541263
1255- # fix names
1256- if (! is.null(names(json ))) {
1257- lhs <- match(names(json ), names(map ), nomatch = 0L )
1258- rhs <- match(names(map ), names(json ), nomatch = 0L )
1259- names(json )[rhs ] <- map [lhs ]
1260- }
1264+ # repair names if necessary
1265+ if (! is.null(names(object ))) {
1266+
1267+ nms <- names(object )
1268+ for (pattern in patterns )
1269+ nms <- gsub(pattern [[2L ]], pattern [[1L ]], nms , fixed = TRUE )
1270+ names(object ) <- nms
12611271
1262- # fix values
1263- if (is.character(json ))
1264- return (map [[json ]] %|| % json )
1265-
1266- # handle true, false, null
1267- if (is.name(json )) {
1268- text <- as.character(json )
1269- if (text == " true" )
1270- return (TRUE )
1271- else if (text == " false" )
1272- return (FALSE )
1273- else if (text == " null" )
1274- return (NULL )
12751272 }
12761273
1277- # recurse
1278- if (is.recursive(json )) {
1279- for (i in seq_along(json )) {
1280- json [i ] <- list (renv_json_read_remap(json [[i ]], map ))
1281- }
1274+ # repair strings if necessary
1275+ if (is.character(object )) {
1276+ for (pattern in patterns )
1277+ object <- gsub(pattern [[2L ]], pattern [[1L ]], object , fixed = TRUE )
12821278 }
12831279
1284- json
1280+ # recurse for other objects
1281+ if (is.recursive(object ))
1282+ for (i in seq_along(object ))
1283+ object [i ] <- list (renv_json_read_remap(object [[i ]], patterns ))
1284+
1285+ # return remapped object
1286+ object
12851287
12861288 }
1289+
1290+ renv_json_read_default <- function (file = NULL , text = NULL ) {
1291+
1292+ # read json text
1293+ text <- paste(text %|| % readLines(file , warn = FALSE ), collapse = " \n " )
1294+
1295+ # convert into something the R parser will understand
1296+ patterns <- renv_json_read_patterns()
1297+ transformed <- text
1298+ for (pattern in patterns )
1299+ transformed <- gsub(pattern [[1L ]], pattern [[2L ]], transformed , fixed = TRUE )
1300+
1301+ # parse it
1302+ rfile <- tempfile(" renv-json-" , fileext = " .R" )
1303+ on.exit(unlink(rfile ), add = TRUE )
1304+ writeLines(transformed , con = rfile )
1305+ json <- parse(rfile , keep.source = FALSE , srcfile = NULL )[[1L ]]
1306+
1307+ # evaluate in safe environment
1308+ result <- eval(json , envir = renv_json_read_envir())
1309+
1310+ # fix up strings if necessary -- do so only with reversible patterns
1311+ patterns <- Filter(function (pattern ) pattern [[3L ]], patterns )
1312+ renv_json_read_remap(result , patterns )
1313+
1314+ }
1315+
12871316
12881317 # load the renv profile, if any
12891318 renv_bootstrap_profile_load(project )
0 commit comments