Visualizes Quality Control(QC) Results of the Metabolomics for Quartet Project.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

654 linhas
17KB

  1. local({
  2. # the requested version of renv
  3. version <- "0.13.0"
  4. # the project directory
  5. project <- getwd()
  6. # avoid recursion
  7. if (!is.na(Sys.getenv("RENV_R_INITIALIZING", unset = NA)))
  8. return(invisible(TRUE))
  9. # signal that we're loading renv during R startup
  10. Sys.setenv("RENV_R_INITIALIZING" = "true")
  11. on.exit(Sys.unsetenv("RENV_R_INITIALIZING"), add = TRUE)
  12. # signal that we've consented to use renv
  13. options(renv.consent = TRUE)
  14. # load the 'utils' package eagerly -- this ensures that renv shims, which
  15. # mask 'utils' packages, will come first on the search path
  16. library(utils, lib.loc = .Library)
  17. # check to see if renv has already been loaded
  18. if ("renv" %in% loadedNamespaces()) {
  19. # if renv has already been loaded, and it's the requested version of renv,
  20. # nothing to do
  21. spec <- .getNamespaceInfo(.getNamespace("renv"), "spec")
  22. if (identical(spec[["version"]], version))
  23. return(invisible(TRUE))
  24. # otherwise, unload and attempt to load the correct version of renv
  25. unloadNamespace("renv")
  26. }
  27. # load bootstrap tools
  28. bootstrap <- function(version, library) {
  29. # attempt to download renv
  30. tarball <- tryCatch(renv_bootstrap_download(version), error = identity)
  31. if (inherits(tarball, "error"))
  32. stop("failed to download renv ", version)
  33. # now attempt to install
  34. status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity)
  35. if (inherits(status, "error"))
  36. stop("failed to install renv ", version)
  37. }
  38. renv_bootstrap_tests_running <- function() {
  39. getOption("renv.tests.running", default = FALSE)
  40. }
  41. renv_bootstrap_repos <- function() {
  42. # check for repos override
  43. repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA)
  44. if (!is.na(repos))
  45. return(repos)
  46. # if we're testing, re-use the test repositories
  47. if (renv_bootstrap_tests_running())
  48. return(getOption("renv.tests.repos"))
  49. # retrieve current repos
  50. repos <- getOption("repos")
  51. # ensure @CRAN@ entries are resolved
  52. repos[repos == "@CRAN@"] <- "https://cloud.r-project.org"
  53. # add in renv.bootstrap.repos if set
  54. default <- c(FALLBACK = "https://cloud.r-project.org")
  55. extra <- getOption("renv.bootstrap.repos", default = default)
  56. repos <- c(repos, extra)
  57. # remove duplicates that might've snuck in
  58. dupes <- duplicated(repos) | duplicated(names(repos))
  59. repos[!dupes]
  60. }
  61. renv_bootstrap_download <- function(version) {
  62. # if the renv version number has 4 components, assume it must
  63. # be retrieved via github
  64. nv <- numeric_version(version)
  65. components <- unclass(nv)[[1]]
  66. methods <- if (length(components) == 4L) {
  67. list(
  68. renv_bootstrap_download_github
  69. )
  70. } else {
  71. list(
  72. renv_bootstrap_download_cran_latest,
  73. renv_bootstrap_download_cran_archive
  74. )
  75. }
  76. for (method in methods) {
  77. path <- tryCatch(method(version), error = identity)
  78. if (is.character(path) && file.exists(path))
  79. return(path)
  80. }
  81. stop("failed to download renv ", version)
  82. }
  83. renv_bootstrap_download_impl <- function(url, destfile) {
  84. mode <- "wb"
  85. # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715
  86. fixup <-
  87. Sys.info()[["sysname"]] == "Windows" &&
  88. substring(url, 1L, 5L) == "file:"
  89. if (fixup)
  90. mode <- "w+b"
  91. utils::download.file(
  92. url = url,
  93. destfile = destfile,
  94. mode = mode,
  95. quiet = TRUE
  96. )
  97. }
  98. renv_bootstrap_download_cran_latest <- function(version) {
  99. repos <- renv_bootstrap_download_cran_latest_find(version)
  100. message("* Downloading renv ", version, " ... ", appendLF = FALSE)
  101. downloader <- function(type) {
  102. tryCatch(
  103. utils::download.packages(
  104. pkgs = "renv",
  105. destdir = tempdir(),
  106. repos = repos,
  107. type = type,
  108. quiet = TRUE
  109. ),
  110. condition = identity
  111. )
  112. }
  113. # first, try downloading a binary on Windows + macOS if appropriate
  114. binary <-
  115. !identical(.Platform$pkgType, "source") &&
  116. !identical(getOption("pkgType"), "source") &&
  117. Sys.info()[["sysname"]] %in% c("Darwin", "Windows")
  118. if (binary) {
  119. info <- downloader(type = "binary")
  120. if (!inherits(info, "condition")) {
  121. message("OK (downloaded binary)")
  122. return(info[1, 2])
  123. }
  124. }
  125. # otherwise, try downloading a source tarball
  126. info <- downloader(type = "source")
  127. if (inherits(info, "condition")) {
  128. message("FAILED")
  129. return(FALSE)
  130. }
  131. # report success and return
  132. message("OK (downloaded source)")
  133. info[1, 2]
  134. }
  135. renv_bootstrap_download_cran_latest_find <- function(version) {
  136. all <- renv_bootstrap_repos()
  137. for (repos in all) {
  138. db <- tryCatch(
  139. as.data.frame(
  140. x = utils::available.packages(repos = repos),
  141. stringsAsFactors = FALSE
  142. ),
  143. error = identity
  144. )
  145. if (inherits(db, "error"))
  146. next
  147. entry <- db[db$Package %in% "renv" & db$Version %in% version, ]
  148. if (nrow(entry) == 0)
  149. next
  150. return(repos)
  151. }
  152. fmt <- "renv %s is not available from your declared package repositories"
  153. stop(sprintf(fmt, version))
  154. }
  155. renv_bootstrap_download_cran_archive <- function(version) {
  156. name <- sprintf("renv_%s.tar.gz", version)
  157. repos <- renv_bootstrap_repos()
  158. urls <- file.path(repos, "src/contrib/Archive/renv", name)
  159. destfile <- file.path(tempdir(), name)
  160. message("* Downloading renv ", version, " ... ", appendLF = FALSE)
  161. for (url in urls) {
  162. status <- tryCatch(
  163. renv_bootstrap_download_impl(url, destfile),
  164. condition = identity
  165. )
  166. if (identical(status, 0L)) {
  167. message("OK")
  168. return(destfile)
  169. }
  170. }
  171. message("FAILED")
  172. return(FALSE)
  173. }
  174. renv_bootstrap_download_github <- function(version) {
  175. enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
  176. if (!identical(enabled, "TRUE"))
  177. return(FALSE)
  178. # prepare download options
  179. pat <- Sys.getenv("GITHUB_PAT")
  180. if (nzchar(Sys.which("curl")) && nzchar(pat)) {
  181. fmt <- "--location --fail --header \"Authorization: token %s\""
  182. extra <- sprintf(fmt, pat)
  183. saved <- options("download.file.method", "download.file.extra")
  184. options(download.file.method = "curl", download.file.extra = extra)
  185. on.exit(do.call(base::options, saved), add = TRUE)
  186. } else if (nzchar(Sys.which("wget")) && nzchar(pat)) {
  187. fmt <- "--header=\"Authorization: token %s\""
  188. extra <- sprintf(fmt, pat)
  189. saved <- options("download.file.method", "download.file.extra")
  190. options(download.file.method = "wget", download.file.extra = extra)
  191. on.exit(do.call(base::options, saved), add = TRUE)
  192. }
  193. message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE)
  194. url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version)
  195. name <- sprintf("renv_%s.tar.gz", version)
  196. destfile <- file.path(tempdir(), name)
  197. status <- tryCatch(
  198. renv_bootstrap_download_impl(url, destfile),
  199. condition = identity
  200. )
  201. if (!identical(status, 0L)) {
  202. message("FAILED")
  203. return(FALSE)
  204. }
  205. message("OK")
  206. return(destfile)
  207. }
  208. renv_bootstrap_install <- function(version, tarball, library) {
  209. # attempt to install it into project library
  210. message("* Installing renv ", version, " ... ", appendLF = FALSE)
  211. dir.create(library, showWarnings = FALSE, recursive = TRUE)
  212. # invoke using system2 so we can capture and report output
  213. bin <- R.home("bin")
  214. exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
  215. r <- file.path(bin, exe)
  216. args <- c("--vanilla", "CMD", "INSTALL", "-l", shQuote(library), shQuote(tarball))
  217. output <- system2(r, args, stdout = TRUE, stderr = TRUE)
  218. message("Done!")
  219. # check for successful install
  220. status <- attr(output, "status")
  221. if (is.numeric(status) && !identical(status, 0L)) {
  222. header <- "Error installing renv:"
  223. lines <- paste(rep.int("=", nchar(header)), collapse = "")
  224. text <- c(header, lines, output)
  225. writeLines(text, con = stderr())
  226. }
  227. status
  228. }
  229. renv_bootstrap_platform_prefix <- function() {
  230. # construct version prefix
  231. version <- paste(R.version$major, R.version$minor, sep = ".")
  232. prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-")
  233. # include SVN revision for development versions of R
  234. # (to avoid sharing platform-specific artefacts with released versions of R)
  235. devel <-
  236. identical(R.version[["status"]], "Under development (unstable)") ||
  237. identical(R.version[["nickname"]], "Unsuffered Consequences")
  238. if (devel)
  239. prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r")
  240. # build list of path components
  241. components <- c(prefix, R.version$platform)
  242. # include prefix if provided by user
  243. prefix <- renv_bootstrap_platform_prefix_impl()
  244. if (!is.na(prefix) && nzchar(prefix))
  245. components <- c(prefix, components)
  246. # build prefix
  247. paste(components, collapse = "/")
  248. }
  249. renv_bootstrap_platform_prefix_impl <- function() {
  250. # if an explicit prefix has been supplied, use it
  251. prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA)
  252. if (!is.na(prefix))
  253. return(prefix)
  254. # if the user has requested an automatic prefix, generate it
  255. auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA)
  256. if (auto %in% c("TRUE", "True", "true", "1"))
  257. return(renv_bootstrap_platform_prefix_auto())
  258. # empty string on failure
  259. ""
  260. }
  261. renv_bootstrap_platform_prefix_auto <- function() {
  262. prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity)
  263. if (inherits(prefix, "error") || prefix %in% "unknown") {
  264. msg <- paste(
  265. "failed to infer current operating system",
  266. "please file a bug report at https://github.com/rstudio/renv/issues",
  267. sep = "; "
  268. )
  269. warning(msg)
  270. }
  271. prefix
  272. }
  273. renv_bootstrap_platform_os <- function() {
  274. sysinfo <- Sys.info()
  275. sysname <- sysinfo[["sysname"]]
  276. # handle Windows + macOS up front
  277. if (sysname == "Windows")
  278. return("windows")
  279. else if (sysname == "Darwin")
  280. return("macos")
  281. # check for os-release files
  282. for (file in c("/etc/os-release", "/usr/lib/os-release"))
  283. if (file.exists(file))
  284. return(renv_bootstrap_platform_os_via_os_release(file, sysinfo))
  285. # check for redhat-release files
  286. if (file.exists("/etc/redhat-release"))
  287. return(renv_bootstrap_platform_os_via_redhat_release())
  288. "unknown"
  289. }
  290. renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) {
  291. # read /etc/os-release
  292. release <- utils::read.table(
  293. file = file,
  294. sep = "=",
  295. quote = c("\"", "'"),
  296. col.names = c("Key", "Value"),
  297. comment.char = "#",
  298. stringsAsFactors = FALSE
  299. )
  300. vars <- as.list(release$Value)
  301. names(vars) <- release$Key
  302. # get os name
  303. os <- tolower(sysinfo[["sysname"]])
  304. # read id
  305. id <- "unknown"
  306. for (field in c("ID", "ID_LIKE")) {
  307. if (field %in% names(vars) && nzchar(vars[[field]])) {
  308. id <- vars[[field]]
  309. break
  310. }
  311. }
  312. # read version
  313. version <- "unknown"
  314. for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) {
  315. if (field %in% names(vars) && nzchar(vars[[field]])) {
  316. version <- vars[[field]]
  317. break
  318. }
  319. }
  320. # join together
  321. paste(c(os, id, version), collapse = "-")
  322. }
  323. renv_bootstrap_platform_os_via_redhat_release <- function() {
  324. # read /etc/redhat-release
  325. contents <- readLines("/etc/redhat-release", warn = FALSE)
  326. # infer id
  327. id <- if (grepl("centos", contents, ignore.case = TRUE))
  328. "centos"
  329. else if (grepl("redhat", contents, ignore.case = TRUE))
  330. "redhat"
  331. else
  332. "unknown"
  333. # try to find a version component (very hacky)
  334. version <- "unknown"
  335. parts <- strsplit(contents, "[[:space:]]")[[1L]]
  336. for (part in parts) {
  337. nv <- tryCatch(numeric_version(part), error = identity)
  338. if (inherits(nv, "error"))
  339. next
  340. version <- nv[1, 1]
  341. break
  342. }
  343. paste(c("linux", id, version), collapse = "-")
  344. }
  345. renv_bootstrap_library_root_name <- function(project) {
  346. # use project name as-is if requested
  347. asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE")
  348. if (asis)
  349. return(basename(project))
  350. # otherwise, disambiguate based on project's path
  351. id <- substring(renv_bootstrap_hash_text(project), 1L, 8L)
  352. paste(basename(project), id, sep = "-")
  353. }
  354. renv_bootstrap_library_root <- function(project) {
  355. path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA)
  356. if (!is.na(path))
  357. return(path)
  358. path <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
  359. if (!is.na(path)) {
  360. name <- renv_bootstrap_library_root_name(project)
  361. return(file.path(path, name))
  362. }
  363. prefix <- renv_bootstrap_profile_prefix()
  364. paste(c(project, prefix, "renv/library"), collapse = "/")
  365. }
  366. renv_bootstrap_validate_version <- function(version) {
  367. loadedversion <- utils::packageDescription("renv", fields = "Version")
  368. if (version == loadedversion)
  369. return(TRUE)
  370. # assume four-component versions are from GitHub; three-component
  371. # versions are from CRAN
  372. components <- strsplit(loadedversion, "[.-]")[[1]]
  373. remote <- if (length(components) == 4L)
  374. paste("rstudio/renv", loadedversion, sep = "@")
  375. else
  376. paste("renv", loadedversion, sep = "@")
  377. fmt <- paste(
  378. "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.",
  379. "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.",
  380. "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.",
  381. sep = "\n"
  382. )
  383. msg <- sprintf(fmt, loadedversion, version, remote)
  384. warning(msg, call. = FALSE)
  385. FALSE
  386. }
  387. renv_bootstrap_hash_text <- function(text) {
  388. hashfile <- tempfile("renv-hash-")
  389. on.exit(unlink(hashfile), add = TRUE)
  390. writeLines(text, con = hashfile)
  391. tools::md5sum(hashfile)
  392. }
  393. renv_bootstrap_load <- function(project, libpath, version) {
  394. # try to load renv from the project library
  395. if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE))
  396. return(FALSE)
  397. # warn if the version of renv loaded does not match
  398. renv_bootstrap_validate_version(version)
  399. # load the project
  400. renv::load(project)
  401. TRUE
  402. }
  403. renv_bootstrap_profile_load <- function(project) {
  404. # if RENV_PROFILE is already set, just use that
  405. profile <- Sys.getenv("RENV_PROFILE", unset = NA)
  406. if (!is.na(profile) && nzchar(profile))
  407. return(profile)
  408. # check for a profile file (nothing to do if it doesn't exist)
  409. path <- file.path(project, "renv/local/profile")
  410. if (!file.exists(path))
  411. return(NULL)
  412. # read the profile, and set it if it exists
  413. contents <- readLines(path, warn = FALSE)
  414. if (length(contents) == 0L)
  415. return(NULL)
  416. # set RENV_PROFILE
  417. profile <- contents[[1L]]
  418. if (nzchar(profile))
  419. Sys.setenv(RENV_PROFILE = profile)
  420. profile
  421. }
  422. renv_bootstrap_profile_prefix <- function() {
  423. profile <- renv_bootstrap_profile_get()
  424. if (!is.null(profile))
  425. return(file.path("renv/profiles", profile))
  426. }
  427. renv_bootstrap_profile_get <- function() {
  428. profile <- Sys.getenv("RENV_PROFILE", unset = "")
  429. renv_bootstrap_profile_normalize(profile)
  430. }
  431. renv_bootstrap_profile_set <- function(profile) {
  432. profile <- renv_bootstrap_profile_normalize(profile)
  433. if (is.null(profile))
  434. Sys.unsetenv("RENV_PROFILE")
  435. else
  436. Sys.setenv(RENV_PROFILE = profile)
  437. }
  438. renv_bootstrap_profile_normalize <- function(profile) {
  439. if (is.null(profile) || profile %in% c("", "default"))
  440. return(NULL)
  441. profile
  442. }
  443. # load the renv profile, if any
  444. renv_bootstrap_profile_load(project)
  445. # construct path to library root
  446. root <- renv_bootstrap_library_root(project)
  447. # construct library prefix for platform
  448. prefix <- renv_bootstrap_platform_prefix()
  449. # construct full libpath
  450. libpath <- file.path(root, prefix)
  451. # attempt to load
  452. if (renv_bootstrap_load(project, libpath, version))
  453. return(TRUE)
  454. # load failed; inform user we're about to bootstrap
  455. prefix <- paste("# Bootstrapping renv", version)
  456. postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "")
  457. header <- paste(prefix, postfix)
  458. message(header)
  459. # perform bootstrap
  460. bootstrap(version, libpath)
  461. # exit early if we're just testing bootstrap
  462. if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
  463. return(TRUE)
  464. # try again to load
  465. if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
  466. message("* Successfully installed and loaded renv ", version, ".")
  467. return(renv::load())
  468. }
  469. # failed to download or load renv; warn the user
  470. msg <- c(
  471. "Failed to find an renv installation: the project will not be loaded.",
  472. "Use `renv::activate()` to re-initialize the project."
  473. )
  474. warning(paste(msg, collapse = "\n"), call. = FALSE)
  475. })