Skip to content

Commit 266be47

Browse files
authored
Merge pull request #22 from LibraryCarpentry/update/packages
Update 2 packages
2 parents 4753339 + 7927c2e commit 266be47

File tree

2 files changed

+892
-229
lines changed

2 files changed

+892
-229
lines changed

renv/activate.R

+100-92
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
local({
33

44
# the requested version of renv
5-
version <- "1.0.11"
5+
version <- "1.1.0"
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",
@@ -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)
@@ -951,8 +950,14 @@ local({
951950
}
952951

953952
renv_bootstrap_validate_version_dev <- function(version, description) {
953+
954954
expected <- description[["RemoteSha"]]
955-
is.character(expected) && startswith(expected, version)
955+
if (!is.character(expected))
956+
return(FALSE)
957+
958+
pattern <- sprintf("^\\Q%s\\E", version)
959+
grepl(pattern, expected, perl = TRUE)
960+
956961
}
957962

958963
renv_bootstrap_validate_version_release <- function(version, description) {
@@ -1132,10 +1137,10 @@ local({
11321137

11331138
renv_bootstrap_exec <- function(project, libpath, version) {
11341139
if (!renv_bootstrap_load(project, libpath, version))
1135-
renv_bootstrap_run(version, libpath)
1140+
renv_bootstrap_run(project, libpath, version)
11361141
}
11371142

1138-
renv_bootstrap_run <- function(version, libpath) {
1143+
renv_bootstrap_run <- function(project, libpath, version) {
11391144

11401145
# perform bootstrap
11411146
bootstrap(version, libpath)
@@ -1146,7 +1151,7 @@ local({
11461151

11471152
# try again to load
11481153
if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
1149-
return(renv::load(project = getwd()))
1154+
return(renv::load(project = project))
11501155
}
11511156

11521157
# failed to download or load renv; warn the user
@@ -1192,98 +1197,101 @@ local({
11921197
jsonlite::fromJSON(txt = text, simplifyVector = FALSE)
11931198
}
11941199

1195-
renv_json_read_default <- function(file = NULL, text = NULL) {
1196-
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]]
1201-
1202-
# if any are found, replace them with placeholders
1203-
replaced <- text
1204-
strings <- character()
1205-
replacements <- character()
1206-
1207-
if (!identical(c(locs), -1L)) {
1208-
1209-
# get the string values
1210-
starts <- locs
1211-
ends <- locs + attr(locs, "match.length") - 1L
1212-
strings <- substring(text, starts, ends)
1213-
1214-
# only keep those requiring escaping
1215-
strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE)
1216-
1217-
# compute replacements
1218-
replacements <- sprintf('"\032%i\032"', seq_along(strings))
1219-
1220-
# replace the strings
1221-
mapply(function(string, replacement) {
1222-
replaced <<- sub(string, replacement, replaced, fixed = TRUE)
1223-
}, strings, replacements)
1200+
renv_json_read_patterns <- function() {
1201+
1202+
list(
1203+
1204+
# objects
1205+
list("{", "\t\n\tobject(\t\n\t"),
1206+
list("}", "\t\n\t)\t\n\t"),
1207+
1208+
# arrays
1209+
list("[", "\t\n\tarray(\t\n\t"),
1210+
list("]", "\n\t\n)\n\t\n"),
1211+
1212+
# maps
1213+
list(":", "\t\n\t=\t\n\t")
1214+
1215+
)
1216+
1217+
}
12241218

1219+
renv_json_read_envir <- function() {
1220+
1221+
envir <- new.env(parent = emptyenv())
1222+
1223+
envir[["+"]] <- `+`
1224+
envir[["-"]] <- `-`
1225+
1226+
envir[["object"]] <- function(...) {
1227+
result <- list(...)
1228+
names(result) <- as.character(names(result))
1229+
result
12251230
}
1226-
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")
1234-
1235-
# parse it
1236-
json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]]
1237-
1238-
# construct map between source strings, replaced strings
1239-
map <- as.character(parse(text = strings))
1240-
names(map) <- as.character(parse(text = replacements))
1241-
1242-
# convert to list
1243-
map <- as.list(map)
1244-
1245-
# remap strings in object
1246-
remapped <- renv_json_read_remap(json, map)
1247-
1248-
# evaluate
1249-
eval(remapped, envir = baseenv())
1250-
1231+
1232+
envir[["array"]] <- list
1233+
1234+
envir[["true"]] <- TRUE
1235+
envir[["false"]] <- FALSE
1236+
envir[["null"]] <- NULL
1237+
1238+
envir
1239+
12511240
}
12521241

1253-
renv_json_read_remap <- function(json, map) {
1254-
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]
1242+
renv_json_read_remap <- function(object, patterns) {
1243+
1244+
# repair names if necessary
1245+
if (!is.null(names(object))) {
1246+
1247+
nms <- names(object)
1248+
for (pattern in patterns)
1249+
nms <- gsub(pattern[[2L]], pattern[[1L]], nms, fixed = TRUE)
1250+
names(object) <- nms
1251+
12601252
}
1261-
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)
1253+
1254+
# repair strings if necessary
1255+
if (is.character(object)) {
1256+
for (pattern in patterns)
1257+
object <- gsub(pattern[[2L]], pattern[[1L]], object, fixed = TRUE)
12751258
}
1259+
1260+
# recurse for other objects
1261+
if (is.recursive(object))
1262+
for (i in seq_along(object))
1263+
object[i] <- list(renv_json_read_remap(object[[i]], patterns))
1264+
1265+
# return remapped object
1266+
object
1267+
1268+
}
12761269

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-
}
1282-
}
1270+
renv_json_read_default <- function(file = NULL, text = NULL) {
12831271

1284-
json
1272+
# read json text
1273+
text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n")
1274+
1275+
# convert into something the R parser will understand
1276+
patterns <- renv_json_read_patterns()
1277+
transformed <- text
1278+
for (pattern in patterns)
1279+
transformed <- gsub(pattern[[1L]], pattern[[2L]], transformed, fixed = TRUE)
1280+
1281+
# parse it
1282+
rfile <- tempfile("renv-json-", fileext = ".R")
1283+
on.exit(unlink(rfile), add = TRUE)
1284+
writeLines(transformed, con = rfile)
1285+
json <- parse(rfile, keep.source = FALSE, srcfile = NULL)[[1L]]
12851286

1287+
# evaluate in safe environment
1288+
result <- eval(json, envir = renv_json_read_envir())
1289+
1290+
# fix up strings if necessary
1291+
renv_json_read_remap(result, patterns)
1292+
12861293
}
1294+
12871295

12881296
# load the renv profile, if any
12891297
renv_bootstrap_profile_load(project)

0 commit comments

Comments
 (0)