mirror of
https://github.com/msberends/AMR.git
synced 2024-12-26 22:06:11 +01:00
227 lines
8.2 KiB
R
227 lines
8.2 KiB
R
local({
|
|
|
|
## Helper function to get the path to the library directory for a
|
|
## given packrat project.
|
|
getPackratLibDir <- function(projDir = NULL) {
|
|
path <- file.path("packrat", "lib", R.version$platform, getRversion())
|
|
|
|
if (!is.null(projDir)) {
|
|
|
|
## Strip trailing slashes if necessary
|
|
projDir <- sub("/+$", "", projDir)
|
|
|
|
## Only prepend path if different from current working dir
|
|
if (!identical(normalizePath(projDir), normalizePath(getwd())))
|
|
path <- file.path(projDir, path)
|
|
}
|
|
|
|
path
|
|
}
|
|
|
|
## Ensure that we set the packrat library directory relative to the
|
|
## project directory. Normally, this should be the working directory,
|
|
## but we also use '.rs.getProjectDirectory()' if necessary (e.g. we're
|
|
## rebuilding a project while within a separate directory)
|
|
libDir <- if (exists(".rs.getProjectDirectory"))
|
|
getPackratLibDir(.rs.getProjectDirectory())
|
|
else
|
|
getPackratLibDir()
|
|
|
|
## Unload packrat in case it's loaded -- this ensures packrat _must_ be
|
|
## loaded from the private library. Note that `requireNamespace` will
|
|
## succeed if the package is already loaded, regardless of lib.loc!
|
|
if ("packrat" %in% loadedNamespaces())
|
|
try(unloadNamespace("packrat"), silent = TRUE)
|
|
|
|
if (suppressWarnings(requireNamespace("packrat", quietly = TRUE, lib.loc = libDir))) {
|
|
|
|
# Check 'print.banner.on.startup' -- when NA and RStudio, don't print
|
|
print.banner <- packrat::get_opts("print.banner.on.startup")
|
|
if (print.banner == "auto" && is.na(Sys.getenv("RSTUDIO", unset = NA))) {
|
|
print.banner <- TRUE
|
|
} else {
|
|
print.banner <- FALSE
|
|
}
|
|
return(packrat::on(print.banner = print.banner))
|
|
}
|
|
|
|
## Escape hatch to allow RStudio to handle bootstrapping. This
|
|
## enables RStudio to provide print output when automagically
|
|
## restoring a project from a bundle on load.
|
|
if (!is.na(Sys.getenv("RSTUDIO", unset = NA)) &&
|
|
is.na(Sys.getenv("RSTUDIO_PACKRAT_BOOTSTRAP", unset = NA))) {
|
|
Sys.setenv("RSTUDIO_PACKRAT_BOOTSTRAP" = "1")
|
|
setHook("rstudio.sessionInit", function(...) {
|
|
# Ensure that, on sourcing 'packrat/init.R', we are
|
|
# within the project root directory
|
|
if (exists(".rs.getProjectDirectory")) {
|
|
owd <- getwd()
|
|
setwd(.rs.getProjectDirectory())
|
|
on.exit(setwd(owd), add = TRUE)
|
|
}
|
|
source("packrat/init.R")
|
|
})
|
|
return(invisible(NULL))
|
|
}
|
|
|
|
## Bootstrapping -- only performed in interactive contexts,
|
|
## or when explicitly asked for on the command line
|
|
if (interactive() || "--bootstrap-packrat" %in% commandArgs(TRUE)) {
|
|
|
|
needsRestore <- "--bootstrap-packrat" %in% commandArgs(TRUE)
|
|
|
|
message("Packrat is not installed in the local library -- ",
|
|
"attempting to bootstrap an installation...")
|
|
|
|
## We need utils for the following to succeed -- there are calls to functions
|
|
## in 'restore' that are contained within utils. utils gets loaded at the
|
|
## end of start-up anyhow, so this should be fine
|
|
library("utils", character.only = TRUE)
|
|
|
|
## Install packrat into local project library
|
|
packratSrcPath <- list.files(full.names = TRUE,
|
|
file.path("packrat", "src", "packrat")
|
|
)
|
|
|
|
## No packrat tarballs available locally -- try some other means of installation
|
|
if (!length(packratSrcPath)) {
|
|
|
|
message("> No source tarball of packrat available locally")
|
|
|
|
## There are no packrat sources available -- try using a version of
|
|
## packrat installed in the user library to bootstrap
|
|
if (requireNamespace("packrat", quietly = TRUE) && packageVersion("packrat") >= "0.2.0.99") {
|
|
message("> Using user-library packrat (",
|
|
packageVersion("packrat"),
|
|
") to bootstrap this project")
|
|
}
|
|
|
|
## Couldn't find a user-local packrat -- try finding and using devtools
|
|
## to install
|
|
else if (requireNamespace("devtools", quietly = TRUE)) {
|
|
message("> Attempting to use devtools::install_github to install ",
|
|
"a temporary version of packrat")
|
|
library(stats) ## for setNames
|
|
devtools::install_github("rstudio/packrat")
|
|
}
|
|
|
|
## Try downloading packrat from CRAN if available
|
|
else if ("packrat" %in% rownames(available.packages())) {
|
|
message("> Installing packrat from CRAN")
|
|
install.packages("packrat")
|
|
}
|
|
|
|
## Fail -- couldn't find an appropriate means of installing packrat
|
|
else {
|
|
stop("Could not automatically bootstrap packrat -- try running ",
|
|
"\"'install.packages('devtools'); devtools::install_github('rstudio/packrat')\"",
|
|
"and restarting R to bootstrap packrat.")
|
|
}
|
|
|
|
# Restore the project, unload the temporary packrat, and load the private packrat
|
|
if (needsRestore)
|
|
packrat::restore(prompt = FALSE, restart = TRUE)
|
|
|
|
## This code path only reached if we didn't restart earlier
|
|
unloadNamespace("packrat")
|
|
requireNamespace("packrat", lib.loc = libDir, quietly = TRUE)
|
|
return(packrat::on())
|
|
|
|
}
|
|
|
|
## Multiple packrat tarballs available locally -- try to choose one
|
|
## TODO: read lock file and infer most appropriate from there; low priority because
|
|
## after bootstrapping packrat a restore should do the right thing
|
|
if (length(packratSrcPath) > 1) {
|
|
warning("Multiple versions of packrat available in the source directory;",
|
|
"using packrat source:\n- ", shQuote(packratSrcPath))
|
|
packratSrcPath <- packratSrcPath[[1]]
|
|
}
|
|
|
|
|
|
lib <- file.path("packrat", "lib", R.version$platform, getRversion())
|
|
if (!file.exists(lib)) {
|
|
dir.create(lib, recursive = TRUE)
|
|
}
|
|
|
|
message("> Installing packrat into project private library:")
|
|
message("- ", shQuote(lib))
|
|
|
|
surround <- function(x, with) {
|
|
if (!length(x)) return(character())
|
|
paste0(with, x, with)
|
|
}
|
|
|
|
|
|
## Invoke install.packages() in clean R session
|
|
peq <- function(x, y) paste(x, y, sep = " = ")
|
|
installArgs <- c(
|
|
peq("pkgs", surround(packratSrcPath, with = "'")),
|
|
peq("lib", surround(lib, with = "'")),
|
|
peq("repos", "NULL"),
|
|
peq("type", surround("source", with = "'"))
|
|
)
|
|
|
|
fmt <- "utils::install.packages(%s)"
|
|
installCmd <- sprintf(fmt, paste(installArgs, collapse = ", "))
|
|
|
|
## Write script to file (avoid issues with command line quoting
|
|
## on R 3.4.3)
|
|
installFile <- tempfile("packrat-bootstrap", fileext = ".R")
|
|
writeLines(installCmd, con = installFile)
|
|
on.exit(unlink(installFile), add = TRUE)
|
|
|
|
fullCmd <- paste(
|
|
surround(file.path(R.home("bin"), "R"), with = "\""),
|
|
"--vanilla",
|
|
"--slave",
|
|
"-f",
|
|
surround(installFile, with = "\"")
|
|
)
|
|
system(fullCmd)
|
|
|
|
## Tag the installed packrat so we know it's managed by packrat
|
|
## TODO: should this be taking information from the lockfile? this is a bit awkward
|
|
## because we're taking an un-annotated packrat source tarball and simply assuming it's now
|
|
## an 'installed from source' version
|
|
|
|
## -- InstallAgent -- ##
|
|
installAgent <- "InstallAgent: packrat 0.5.0"
|
|
|
|
## -- InstallSource -- ##
|
|
installSource <- "InstallSource: source"
|
|
|
|
packratDescPath <- file.path(lib, "packrat", "DESCRIPTION")
|
|
DESCRIPTION <- readLines(packratDescPath)
|
|
DESCRIPTION <- c(DESCRIPTION, installAgent, installSource)
|
|
cat(DESCRIPTION, file = packratDescPath, sep = "\n")
|
|
|
|
# Otherwise, continue on as normal
|
|
message("> Attaching packrat")
|
|
library("packrat", character.only = TRUE, lib.loc = lib)
|
|
|
|
message("> Restoring library")
|
|
if (needsRestore)
|
|
packrat::restore(prompt = FALSE, restart = FALSE)
|
|
|
|
# If the environment allows us to restart, do so with a call to restore
|
|
restart <- getOption("restart")
|
|
if (!is.null(restart)) {
|
|
message("> Packrat bootstrap successfully completed. ",
|
|
"Restarting R and entering packrat mode...")
|
|
return(restart())
|
|
}
|
|
|
|
# Callers (source-erers) can define this hidden variable to make sure we don't enter packrat mode
|
|
# Primarily useful for testing
|
|
if (!exists(".__DONT_ENTER_PACKRAT_MODE__.") && interactive()) {
|
|
message("> Packrat bootstrap successfully completed. Entering packrat mode...")
|
|
packrat::on()
|
|
}
|
|
|
|
Sys.unsetenv("RSTUDIO_PACKRAT_BOOTSTRAP")
|
|
|
|
}
|
|
|
|
})
|