diff --git a/README.md b/README.md
index 2a71815..3a35517 100644
--- a/README.md
+++ b/README.md
@@ -2,4 +2,7 @@
[![Build Status](https://travis-ci.org/ecohealthalliance/eha-ma-handbook.svg?branch=master)](https://travis-ci.org/ecohealthalliance/eha-ma-handbook)
+[![DOI](https://zenodo.org/badge/61732078.svg)](https://zenodo.org/badge/latestdoi/61732078)
+
+
This repo contains our handbook for EHA Modeling & Analytics best practices, rendered via [**bookdown**](https://bookdown.org/yihui/bookdown/). Read it at . Edit the `.Rmd` files above to make changes. Changes are automatically rendered when changes are approved and merged, usually with a delay of 5 minutes or so.
diff --git a/index.Rmd b/index.Rmd
index c707698..197771a 100644
--- a/index.Rmd
+++ b/index.Rmd
@@ -19,8 +19,7 @@ params:
# Introduction {#introduction .unnumbered}
This handbook describes best practices and guidelines for project management,
-organization, modeling and and programming we aim for our on the EHA Modeling &
-Analytics team.
+organization, modeling and programming we aim for at EHA.
This is a living document. To make changes, just click the edit button
() at the top of the page. It will take you to the
diff --git a/renv.lock b/renv.lock
index a63617e..3884ba4 100644
--- a/renv.lock
+++ b/renv.lock
@@ -13,152 +13,1499 @@
]
},
"Packages": {
+ "DiagrammeR": {
+ "Package": "DiagrammeR",
+ "Version": "1.0.10",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "RColorBrewer",
+ "downloader",
+ "dplyr",
+ "glue",
+ "htmltools",
+ "htmlwidgets",
+ "igraph",
+ "magrittr",
+ "purrr",
+ "readr",
+ "rlang",
+ "rstudioapi",
+ "scales",
+ "stringr",
+ "tibble",
+ "tidyr",
+ "viridis",
+ "visNetwork"
+ ],
+ "Hash": "f3de4a4878163a4629a528bbcc6e655d"
+ },
+ "MASS": {
+ "Package": "MASS",
+ "Version": "7.3-60",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "grDevices",
+ "graphics",
+ "methods",
+ "stats",
+ "utils"
+ ],
+ "Hash": "a56a6365b3fa73293ea8d084be0d9bb0"
+ },
+ "Matrix": {
+ "Package": "Matrix",
+ "Version": "1.6-1.1",
+ "Source": "Repository",
+ "Repository": "RSPM",
+ "Requirements": [
+ "R",
+ "grDevices",
+ "graphics",
+ "grid",
+ "lattice",
+ "methods",
+ "stats",
+ "utils"
+ ],
+ "Hash": "1a00d4828f33a9d690806e98bd17150c"
+ },
+ "R6": {
+ "Package": "R6",
+ "Version": "2.5.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "470851b6d5d0ac559e9d01bb352b4021"
+ },
+ "RColorBrewer": {
+ "Package": "RColorBrewer",
+ "Version": "1.1-3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "45f0398006e83a5b10b72a90663d8d8c"
+ },
+ "Rcpp": {
+ "Package": "Rcpp",
+ "Version": "1.0.11",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "methods",
+ "utils"
+ ],
+ "Hash": "ae6cbbe1492f4de79c45fce06f967ce8"
+ },
+ "V8": {
+ "Package": "V8",
+ "Version": "4.3.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "Rcpp",
+ "curl",
+ "jsonlite",
+ "utils"
+ ],
+ "Hash": "20d81ec18bde233d8cc3265761fe8c93"
+ },
+ "airtabler": {
+ "Package": "airtabler",
+ "Version": "0.2.3",
+ "Source": "GitHub",
+ "RemoteType": "github",
+ "RemoteHost": "api.github.com",
+ "RemoteRepo": "airtabler",
+ "RemoteUsername": "ecohealthalliance",
+ "RemoteRef": "feature/metadata_api",
+ "RemoteSha": "30570cc76e6457942cb3fd14094b29be9b13f10c",
+ "Requirements": [
+ "R",
+ "curl",
+ "deposits",
+ "dplyr",
+ "glue",
+ "httr",
+ "jsonlite",
+ "purrr",
+ "readxl",
+ "rlang",
+ "snakecase",
+ "stringr",
+ "tibble",
+ "tidyselect",
+ "utils"
+ ],
+ "Hash": "93b15466bc6b212dcd7c527721535d27"
+ },
+ "askpass": {
+ "Package": "askpass",
+ "Version": "1.2.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "sys"
+ ],
+ "Hash": "cad6cf7f1d5f6e906700b9d3e718c796"
+ },
+ "assertthat": {
+ "Package": "assertthat",
+ "Version": "0.2.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "tools"
+ ],
+ "Hash": "50c838a310445e954bc13f26f26a6ecf"
+ },
+ "backports": {
+ "Package": "backports",
+ "Version": "1.4.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "c39fbec8a30d23e721980b8afb31984c"
+ },
"base64enc": {
"Package": "base64enc",
"Version": "0.1-3",
"Source": "Repository",
"Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
"Hash": "543776ae6848fde2f48ff3816d0628bc"
},
+ "bit": {
+ "Package": "bit",
+ "Version": "4.0.5",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "d242abec29412ce988848d0294b208fd"
+ },
+ "bit64": {
+ "Package": "bit64",
+ "Version": "4.0.5",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "bit",
+ "methods",
+ "stats",
+ "utils"
+ ],
+ "Hash": "9fe98599ca456d6552421db0d6772d8f"
+ },
"bookdown": {
"Package": "bookdown",
- "Version": "0.24",
+ "Version": "0.35",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "htmltools",
+ "jquerylib",
+ "knitr",
+ "rmarkdown",
+ "tinytex",
+ "xfun",
+ "yaml"
+ ],
+ "Hash": "c6ff1e408f5f241cbcedc0ae28711163"
+ },
+ "bslib": {
+ "Package": "bslib",
+ "Version": "0.5.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "base64enc",
+ "cachem",
+ "grDevices",
+ "htmltools",
+ "jquerylib",
+ "jsonlite",
+ "memoise",
+ "mime",
+ "rlang",
+ "sass"
+ ],
+ "Hash": "283015ddfbb9d7bf15ea9f0b5698f0d9"
+ },
+ "cachem": {
+ "Package": "cachem",
+ "Version": "1.0.8",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "fastmap",
+ "rlang"
+ ],
+ "Hash": "c35768291560ce302c0a6589f92e837d"
+ },
+ "cellranger": {
+ "Package": "cellranger",
+ "Version": "1.1.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "rematch",
+ "tibble"
+ ],
+ "Hash": "f61dbaec772ccd2e17705c1e872e9e7c"
+ },
+ "checkmate": {
+ "Package": "checkmate",
+ "Version": "2.2.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "backports",
+ "utils"
+ ],
+ "Hash": "ca9c113196136f4a9ca9ce6079c2c99e"
+ },
+ "cli": {
+ "Package": "cli",
+ "Version": "3.6.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "utils"
+ ],
+ "Hash": "89e6d8219950eac806ae0c489052048a"
+ },
+ "clipr": {
+ "Package": "clipr",
+ "Version": "0.8.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "utils"
+ ],
+ "Hash": "3f038e5ac7f41d4ac41ce658c85e3042"
+ },
+ "colorspace": {
+ "Package": "colorspace",
+ "Version": "2.1-0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "grDevices",
+ "graphics",
+ "methods",
+ "stats"
+ ],
+ "Hash": "f20c47fd52fae58b4e377c37bb8c335b"
+ },
+ "commonmark": {
+ "Package": "commonmark",
+ "Version": "1.9.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "d691c61bff84bd63c383874d2d0c3307"
+ },
+ "cpp11": {
+ "Package": "cpp11",
+ "Version": "0.4.6",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "707fae4bbf73697ec8d85f9d7076c061"
+ },
+ "crayon": {
+ "Package": "crayon",
+ "Version": "1.5.2",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "3837766a1e1b527af25fa3e2d12a2800"
+ "Requirements": [
+ "grDevices",
+ "methods",
+ "utils"
+ ],
+ "Hash": "e8a1e41acf02548751f45c718d55aa6a"
+ },
+ "curl": {
+ "Package": "curl",
+ "Version": "5.1.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "9123f3ef96a2c1a93927d828b2fe7d4c"
+ },
+ "deposits": {
+ "Package": "deposits",
+ "Version": "0.2.1.042",
+ "Source": "GitHub",
+ "RemoteType": "github",
+ "RemoteUsername": "ropenscilabs",
+ "RemoteRepo": "deposits",
+ "RemoteRef": "HEAD",
+ "RemoteSha": "b17bd0ec5b8a04cacbbb68e95441bab168624d12",
+ "RemoteHost": "api.github.com",
+ "Requirements": [
+ "R6",
+ "checkmate",
+ "fs",
+ "here",
+ "httr2",
+ "jsonlite",
+ "jsonvalidate",
+ "methods",
+ "withr",
+ "xml2"
+ ],
+ "Hash": "3a2d92b4cd2e22d174b7f3682dbe9aad"
},
"digest": {
"Package": "digest",
- "Version": "0.6.27",
+ "Version": "0.6.33",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "a0cbe758a531d054b537d16dff4d58a1"
+ "Requirements": [
+ "R",
+ "utils"
+ ],
+ "Hash": "b18a9cf3c003977b0cc49d5e76ebe48d"
+ },
+ "downloader": {
+ "Package": "downloader",
+ "Version": "0.4",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "digest",
+ "utils"
+ ],
+ "Hash": "f4f2a915e0dedbdf016a83b63477349f"
+ },
+ "dplyr": {
+ "Package": "dplyr",
+ "Version": "1.1.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "R6",
+ "cli",
+ "generics",
+ "glue",
+ "lifecycle",
+ "magrittr",
+ "methods",
+ "pillar",
+ "rlang",
+ "tibble",
+ "tidyselect",
+ "utils",
+ "vctrs"
+ ],
+ "Hash": "e85ffbebaad5f70e1a2e2ef4302b4949"
+ },
+ "ellipsis": {
+ "Package": "ellipsis",
+ "Version": "0.3.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "rlang"
+ ],
+ "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077"
+ },
+ "emo": {
+ "Package": "emo",
+ "Version": "0.0.0.9000",
+ "Source": "GitHub",
+ "RemoteType": "github",
+ "RemoteHost": "api.github.com",
+ "RemoteRepo": "emo",
+ "RemoteUsername": "hadley",
+ "RemoteRef": "HEAD",
+ "RemoteSha": "3f03b11491ce3d6fc5601e210927eff73bf8e350",
+ "Requirements": [
+ "R",
+ "assertthat",
+ "crayon",
+ "glue",
+ "lubridate",
+ "magrittr",
+ "purrr",
+ "rlang",
+ "stringr",
+ "utils"
+ ],
+ "Hash": "10f2391a926b0087a671ed9965ea30a3"
},
"evaluate": {
"Package": "evaluate",
- "Version": "0.14",
+ "Version": "0.22",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "ec8ca05cffcc70569eaaad8469d2a3a7"
+ "Requirements": [
+ "R",
+ "methods"
+ ],
+ "Hash": "66f39c7a21e03c4dcb2c2d21d738d603"
+ },
+ "fansi": {
+ "Package": "fansi",
+ "Version": "1.0.4",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "grDevices",
+ "utils"
+ ],
+ "Hash": "1d9e7ad3c8312a192dea7d3db0274fde"
+ },
+ "farver": {
+ "Package": "farver",
+ "Version": "2.1.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "8106d78941f34855c440ddb946b8f7a5"
},
"fastmap": {
"Package": "fastmap",
- "Version": "1.1.0",
+ "Version": "1.1.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "f7736a18de97dea803bde0a2daaafb27"
+ },
+ "fontawesome": {
+ "Package": "fontawesome",
+ "Version": "0.5.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "htmltools",
+ "rlang"
+ ],
+ "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d"
+ },
+ "fs": {
+ "Package": "fs",
+ "Version": "1.6.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "methods"
+ ],
+ "Hash": "47b5f30c720c23999b913a1a635cf0bb"
+ },
+ "generics": {
+ "Package": "generics",
+ "Version": "0.1.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "methods"
+ ],
+ "Hash": "15e9634c0fcd294799e9b2e929ed1b86"
+ },
+ "ggplot2": {
+ "Package": "ggplot2",
+ "Version": "3.4.3",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "77bd60a6157420d4ffa93b27cf6a58b8"
+ "Requirements": [
+ "MASS",
+ "R",
+ "cli",
+ "glue",
+ "grDevices",
+ "grid",
+ "gtable",
+ "isoband",
+ "lifecycle",
+ "mgcv",
+ "rlang",
+ "scales",
+ "stats",
+ "tibble",
+ "vctrs",
+ "withr"
+ ],
+ "Hash": "85846544c596e71f8f46483ab165da33"
},
"git2r": {
"Package": "git2r",
- "Version": "0.28.0",
+ "Version": "0.32.0",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "f64fd34026f6025de71a4354800e6d79"
+ "Requirements": [
+ "R",
+ "graphics",
+ "utils"
+ ],
+ "Hash": "1882d7a76fd8c14b2322865f74c9a348"
},
"glue": {
"Package": "glue",
- "Version": "1.4.2",
+ "Version": "1.6.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "methods"
+ ],
+ "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e"
+ },
+ "gridExtra": {
+ "Package": "gridExtra",
+ "Version": "2.3",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "6efd734b14c6471cfe443345f3e35e29"
+ "Requirements": [
+ "grDevices",
+ "graphics",
+ "grid",
+ "gtable",
+ "utils"
+ ],
+ "Hash": "7d7f283939f563670a697165b2cf5560"
+ },
+ "gtable": {
+ "Package": "gtable",
+ "Version": "0.3.4",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cli",
+ "glue",
+ "grid",
+ "lifecycle",
+ "rlang"
+ ],
+ "Hash": "b29cf3031f49b04ab9c852c912547eef"
+ },
+ "here": {
+ "Package": "here",
+ "Version": "1.0.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "rprojroot"
+ ],
+ "Hash": "24b224366f9c2e7534d2344d10d59211"
},
"highr": {
"Package": "highr",
- "Version": "0.9",
+ "Version": "0.10",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "xfun"
+ ],
+ "Hash": "06230136b2d2b9ba5805e1963fa6e890"
+ },
+ "hms": {
+ "Package": "hms",
+ "Version": "1.1.3",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "8eb36c8125038e648e5d111c0d7b2ed4"
+ "Requirements": [
+ "lifecycle",
+ "methods",
+ "pkgconfig",
+ "rlang",
+ "vctrs"
+ ],
+ "Hash": "b59377caa7ed00fa41808342002138f9"
},
"htmltools": {
"Package": "htmltools",
- "Version": "0.5.2",
+ "Version": "0.5.6",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "base64enc",
+ "digest",
+ "ellipsis",
+ "fastmap",
+ "grDevices",
+ "rlang",
+ "utils"
+ ],
+ "Hash": "a2326a66919a3311f7fbb1e3bf568283"
+ },
+ "htmlwidgets": {
+ "Package": "htmlwidgets",
+ "Version": "1.6.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "grDevices",
+ "htmltools",
+ "jsonlite",
+ "knitr",
+ "rmarkdown",
+ "yaml"
+ ],
+ "Hash": "a865aa85bcb2697f47505bfd70422471"
+ },
+ "httpuv": {
+ "Package": "httpuv",
+ "Version": "1.6.11",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "R6",
+ "Rcpp",
+ "later",
+ "promises",
+ "utils"
+ ],
+ "Hash": "838602f54e32c1a0f8cc80708cefcefa"
+ },
+ "httr": {
+ "Package": "httr",
+ "Version": "1.4.7",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "R6",
+ "curl",
+ "jsonlite",
+ "mime",
+ "openssl"
+ ],
+ "Hash": "ac107251d9d9fd72f0ca8049988f1d7f"
+ },
+ "httr2": {
+ "Package": "httr2",
+ "Version": "0.2.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "R6",
+ "cli",
+ "curl",
+ "glue",
+ "magrittr",
+ "openssl",
+ "rappdirs",
+ "rlang",
+ "withr"
+ ],
+ "Hash": "193bb297368afbbb42dc85784a46b36e"
+ },
+ "igraph": {
+ "Package": "igraph",
+ "Version": "1.5.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "Matrix",
+ "R",
+ "cli",
+ "cpp11",
+ "grDevices",
+ "graphics",
+ "lifecycle",
+ "magrittr",
+ "methods",
+ "pkgconfig",
+ "rlang",
+ "stats",
+ "utils"
+ ],
+ "Hash": "80401cb5ec513e8ddc56764d03f63669"
+ },
+ "isoband": {
+ "Package": "isoband",
+ "Version": "0.2.7",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "526c484233f42522278ab06fb185cb26"
+ "Requirements": [
+ "grid",
+ "utils"
+ ],
+ "Hash": "0080607b4a1a7b28979aecef976d8bc2"
},
"jquerylib": {
"Package": "jquerylib",
"Version": "0.1.4",
"Source": "Repository",
"Repository": "CRAN",
+ "Requirements": [
+ "htmltools"
+ ],
"Hash": "5aab57a3bd297eee1c1d862735972182"
},
"jsonlite": {
"Package": "jsonlite",
- "Version": "1.7.2",
+ "Version": "1.8.7",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "98138e0994d41508c7a6b84a0600cfcb"
+ "Requirements": [
+ "methods"
+ ],
+ "Hash": "266a20443ca13c65688b2116d5220f76"
+ },
+ "jsonvalidate": {
+ "Package": "jsonvalidate",
+ "Version": "1.3.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "V8"
+ ],
+ "Hash": "cdc2843ef7f44f157198bb99aea7552d"
},
"knitr": {
"Package": "knitr",
- "Version": "1.34",
+ "Version": "1.44",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "evaluate",
+ "highr",
+ "methods",
+ "tools",
+ "xfun",
+ "yaml"
+ ],
+ "Hash": "60885b9f746c9dfaef110d070b5f7dc0"
+ },
+ "labeling": {
+ "Package": "labeling",
+ "Version": "0.4.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "graphics",
+ "stats"
+ ],
+ "Hash": "b64ec208ac5bc1852b285f665d6368b3"
+ },
+ "later": {
+ "Package": "later",
+ "Version": "1.3.1",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "aa958054ac6f0360926bb952ea302f0f"
+ "Requirements": [
+ "Rcpp",
+ "rlang"
+ ],
+ "Hash": "40401c9cf2bc2259dfe83311c9384710"
+ },
+ "lattice": {
+ "Package": "lattice",
+ "Version": "0.21-9",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "grDevices",
+ "graphics",
+ "grid",
+ "stats",
+ "utils"
+ ],
+ "Hash": "5558c61e0136e247252f5f952cdaad6a"
+ },
+ "lifecycle": {
+ "Package": "lifecycle",
+ "Version": "1.0.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cli",
+ "glue",
+ "rlang"
+ ],
+ "Hash": "001cecbeac1cff9301bdc3775ee46a86"
+ },
+ "lubridate": {
+ "Package": "lubridate",
+ "Version": "1.9.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "generics",
+ "methods",
+ "timechange"
+ ],
+ "Hash": "680ad542fbcf801442c83a6ac5a2126c"
},
"magrittr": {
"Package": "magrittr",
+ "Version": "2.0.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "7ce2733a9826b3aeb1775d56fd305472"
+ },
+ "memoise": {
+ "Package": "memoise",
"Version": "2.0.1",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "41287f1ac7d28a92f0a286ed507928d3"
+ "Requirements": [
+ "cachem",
+ "rlang"
+ ],
+ "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c"
+ },
+ "mgcv": {
+ "Package": "mgcv",
+ "Version": "1.9-0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "Matrix",
+ "R",
+ "graphics",
+ "methods",
+ "nlme",
+ "splines",
+ "stats",
+ "utils"
+ ],
+ "Hash": "086028ca0460d0c368028d3bda58f31b"
+ },
+ "mime": {
+ "Package": "mime",
+ "Version": "0.12",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "tools"
+ ],
+ "Hash": "18e9c28c1d3ca1560ce30658b22ce104"
+ },
+ "munsell": {
+ "Package": "munsell",
+ "Version": "0.5.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "colorspace",
+ "methods"
+ ],
+ "Hash": "6dfe8bf774944bd5595785e3229d8771"
+ },
+ "nlme": {
+ "Package": "nlme",
+ "Version": "3.1-163",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "graphics",
+ "lattice",
+ "stats",
+ "utils"
+ ],
+ "Hash": "8d1938040a05566f4f7a14af4feadd6b"
+ },
+ "openssl": {
+ "Package": "openssl",
+ "Version": "2.1.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "askpass"
+ ],
+ "Hash": "2a0dc8c6adfb6f032e4d4af82d258ab5"
+ },
+ "pillar": {
+ "Package": "pillar",
+ "Version": "1.9.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "cli",
+ "fansi",
+ "glue",
+ "lifecycle",
+ "rlang",
+ "utf8",
+ "utils",
+ "vctrs"
+ ],
+ "Hash": "15da5a8412f317beeee6175fbc76f4bb"
+ },
+ "pkgconfig": {
+ "Package": "pkgconfig",
+ "Version": "2.0.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "utils"
+ ],
+ "Hash": "01f28d4278f15c76cddbea05899c5d6f"
+ },
+ "prettyunits": {
+ "Package": "prettyunits",
+ "Version": "1.2.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "6b01fc98b1e86c4f705ce9dcfd2f57c7"
+ },
+ "progress": {
+ "Package": "progress",
+ "Version": "1.2.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R6",
+ "crayon",
+ "hms",
+ "prettyunits"
+ ],
+ "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061"
+ },
+ "promises": {
+ "Package": "promises",
+ "Version": "1.2.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R6",
+ "Rcpp",
+ "fastmap",
+ "later",
+ "magrittr",
+ "rlang",
+ "stats"
+ ],
+ "Hash": "0d8a15c9d000970ada1ab21405387dee"
+ },
+ "purrr": {
+ "Package": "purrr",
+ "Version": "1.0.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cli",
+ "lifecycle",
+ "magrittr",
+ "rlang",
+ "vctrs"
+ ],
+ "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc"
+ },
+ "rappdirs": {
+ "Package": "rappdirs",
+ "Version": "0.3.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "5e3c5dc0b071b21fa128676560dbe94d"
+ },
+ "readr": {
+ "Package": "readr",
+ "Version": "2.1.4",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "R6",
+ "cli",
+ "clipr",
+ "cpp11",
+ "crayon",
+ "hms",
+ "lifecycle",
+ "methods",
+ "rlang",
+ "tibble",
+ "tzdb",
+ "utils",
+ "vroom"
+ ],
+ "Hash": "b5047343b3825f37ad9d3b5d89aa1078"
+ },
+ "readxl": {
+ "Package": "readxl",
+ "Version": "1.4.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cellranger",
+ "cpp11",
+ "progress",
+ "tibble",
+ "utils"
+ ],
+ "Hash": "8cf9c239b96df1bbb133b74aef77ad0a"
+ },
+ "rematch": {
+ "Package": "rematch",
+ "Version": "2.0.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "cbff1b666c6fa6d21202f07e2318d4f1"
},
"renv": {
"Package": "renv",
- "Version": "0.14.0",
+ "Version": "1.0.3",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "30e5eba91b67f7f4d75d31de14bbfbdc"
+ "Requirements": [
+ "utils"
+ ],
+ "Hash": "41b847654f567341725473431dd0d5ab"
},
"rlang": {
"Package": "rlang",
- "Version": "0.4.11",
+ "Version": "1.1.1",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "515f341d3affe0de9e4a7f762efb0456"
+ "Requirements": [
+ "R",
+ "utils"
+ ],
+ "Hash": "a85c767b55f0bf9b7ad16c6d7baee5bb"
},
"rmarkdown": {
"Package": "rmarkdown",
- "Version": "2.11",
+ "Version": "2.25",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "320017b52d05a943981272b295750388"
+ "Requirements": [
+ "R",
+ "bslib",
+ "evaluate",
+ "fontawesome",
+ "htmltools",
+ "jquerylib",
+ "jsonlite",
+ "knitr",
+ "methods",
+ "stringr",
+ "tinytex",
+ "tools",
+ "utils",
+ "xfun",
+ "yaml"
+ ],
+ "Hash": "d65e35823c817f09f4de424fcdfa812a"
+ },
+ "rprojroot": {
+ "Package": "rprojroot",
+ "Version": "2.0.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "1de7ab598047a87bba48434ba35d497d"
+ },
+ "rstudioapi": {
+ "Package": "rstudioapi",
+ "Version": "0.15.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "5564500e25cffad9e22244ced1379887"
+ },
+ "sass": {
+ "Package": "sass",
+ "Version": "0.4.7",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R6",
+ "fs",
+ "htmltools",
+ "rappdirs",
+ "rlang"
+ ],
+ "Hash": "6bd4d33b50ff927191ec9acbf52fd056"
+ },
+ "scales": {
+ "Package": "scales",
+ "Version": "1.2.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "R6",
+ "RColorBrewer",
+ "farver",
+ "labeling",
+ "lifecycle",
+ "munsell",
+ "rlang",
+ "viridisLite"
+ ],
+ "Hash": "906cb23d2f1c5680b8ce439b44c6fa63"
+ },
+ "shiny": {
+ "Package": "shiny",
+ "Version": "1.7.5",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "R6",
+ "bslib",
+ "cachem",
+ "commonmark",
+ "crayon",
+ "ellipsis",
+ "fastmap",
+ "fontawesome",
+ "glue",
+ "grDevices",
+ "htmltools",
+ "httpuv",
+ "jsonlite",
+ "later",
+ "lifecycle",
+ "methods",
+ "mime",
+ "promises",
+ "rlang",
+ "sourcetools",
+ "tools",
+ "utils",
+ "withr",
+ "xtable"
+ ],
+ "Hash": "438b99792adbe82a8329ad8697d45afe"
+ },
+ "snakecase": {
+ "Package": "snakecase",
+ "Version": "0.11.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "stringi",
+ "stringr"
+ ],
+ "Hash": "58767e44739b76965332e8a4fe3f91f1"
+ },
+ "sourcetools": {
+ "Package": "sourcetools",
+ "Version": "0.1.7-1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "5f5a7629f956619d519205ec475fe647"
},
"stringi": {
"Package": "stringi",
- "Version": "1.7.4",
+ "Version": "1.7.12",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "ebaccb577da50829a3bb1b8296f318a5"
+ "Requirements": [
+ "R",
+ "stats",
+ "tools",
+ "utils"
+ ],
+ "Hash": "ca8bd84263c77310739d2cf64d84d7c9"
},
"stringr": {
"Package": "stringr",
- "Version": "1.4.0",
+ "Version": "1.5.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cli",
+ "glue",
+ "lifecycle",
+ "magrittr",
+ "rlang",
+ "stringi",
+ "vctrs"
+ ],
+ "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8"
+ },
+ "sys": {
+ "Package": "sys",
+ "Version": "3.4.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "3a1be13d68d47a8cd0bfd74739ca1555"
+ },
+ "tibble": {
+ "Package": "tibble",
+ "Version": "3.2.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "fansi",
+ "lifecycle",
+ "magrittr",
+ "methods",
+ "pillar",
+ "pkgconfig",
+ "rlang",
+ "utils",
+ "vctrs"
+ ],
+ "Hash": "a84e2cc86d07289b3b6f5069df7a004c"
+ },
+ "tidyr": {
+ "Package": "tidyr",
+ "Version": "1.3.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cli",
+ "cpp11",
+ "dplyr",
+ "glue",
+ "lifecycle",
+ "magrittr",
+ "purrr",
+ "rlang",
+ "stringr",
+ "tibble",
+ "tidyselect",
+ "utils",
+ "vctrs"
+ ],
+ "Hash": "e47debdc7ce599b070c8e78e8ac0cfcf"
+ },
+ "tidyselect": {
+ "Package": "tidyselect",
+ "Version": "1.2.0",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "0759e6b6c0957edb1311028a49a35e76"
+ "Requirements": [
+ "R",
+ "cli",
+ "glue",
+ "lifecycle",
+ "rlang",
+ "vctrs",
+ "withr"
+ ],
+ "Hash": "79540e5fcd9e0435af547d885f184fd5"
+ },
+ "timechange": {
+ "Package": "timechange",
+ "Version": "0.2.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cpp11"
+ ],
+ "Hash": "8548b44f79a35ba1791308b61e6012d7"
},
"tinytex": {
"Package": "tinytex",
- "Version": "0.33",
+ "Version": "0.47",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "xfun"
+ ],
+ "Hash": "8d4ccb733843e513c1c1cdd66a759f0d"
+ },
+ "tzdb": {
+ "Package": "tzdb",
+ "Version": "0.4.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cpp11"
+ ],
+ "Hash": "f561504ec2897f4d46f0c7657e488ae1"
+ },
+ "utf8": {
+ "Package": "utf8",
+ "Version": "1.2.3",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "6e0ad90ac5669e35d5456cb61b295acb"
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "1fe17157424bb09c48a8b3b550c753bc"
+ },
+ "vctrs": {
+ "Package": "vctrs",
+ "Version": "0.6.3",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "cli",
+ "glue",
+ "lifecycle",
+ "rlang"
+ ],
+ "Hash": "d0ef2856b83dc33ea6e255caf6229ee2"
+ },
+ "viridis": {
+ "Package": "viridis",
+ "Version": "0.6.4",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "ggplot2",
+ "gridExtra",
+ "viridisLite"
+ ],
+ "Hash": "80cd127bc8c9d3d9f0904ead9a9102f1"
+ },
+ "viridisLite": {
+ "Package": "viridisLite",
+ "Version": "0.4.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "c826c7c4241b6fc89ff55aaea3fa7491"
+ },
+ "visNetwork": {
+ "Package": "visNetwork",
+ "Version": "2.1.2",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "grDevices",
+ "htmltools",
+ "htmlwidgets",
+ "jsonlite",
+ "magrittr",
+ "methods",
+ "stats",
+ "utils"
+ ],
+ "Hash": "3e48b097e8d9a91ecced2ed4817a678d"
+ },
+ "vroom": {
+ "Package": "vroom",
+ "Version": "1.6.4",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "bit64",
+ "cli",
+ "cpp11",
+ "crayon",
+ "glue",
+ "hms",
+ "lifecycle",
+ "methods",
+ "progress",
+ "rlang",
+ "stats",
+ "tibble",
+ "tidyselect",
+ "tzdb",
+ "vctrs",
+ "withr"
+ ],
+ "Hash": "9db52c1656cf19c124f93124ea57f0fd"
+ },
+ "withr": {
+ "Package": "withr",
+ "Version": "2.5.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "grDevices",
+ "graphics",
+ "stats"
+ ],
+ "Hash": "d77c6f74be05c33164e33fbc85540cae"
},
"xfun": {
"Package": "xfun",
- "Version": "0.26",
+ "Version": "0.40",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "stats",
+ "tools"
+ ],
+ "Hash": "be07d23211245fc7d4209f54c4e4ffc8"
+ },
+ "xml2": {
+ "Package": "xml2",
+ "Version": "1.3.5",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "methods"
+ ],
+ "Hash": "6c40e5cfcc6aefd88110666e18c31f40"
+ },
+ "xtable": {
+ "Package": "xtable",
+ "Version": "1.8-4",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "a270216f7ffda25e53298293046d1d05"
+ "Requirements": [
+ "R",
+ "stats",
+ "utils"
+ ],
+ "Hash": "b8acdf8af494d9ec19ccb2481a9b11c2"
},
"yaml": {
"Package": "yaml",
- "Version": "2.2.1",
+ "Version": "2.3.7",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "2826c5d9efb0a88f657c7a679c7106db"
+ "Hash": "0d0056cc5383fbc240ccd0cb584bf436"
}
}
}
diff --git a/renv/.gitignore b/renv/.gitignore
index 2129631..6ae4167 100644
--- a/renv/.gitignore
+++ b/renv/.gitignore
@@ -1,3 +1,5 @@
+cellar/
+sandbox/
library/
local/
lock/
diff --git a/renv/activate.R b/renv/activate.R
index 304fd90..cb5401f 100644
--- a/renv/activate.R
+++ b/renv/activate.R
@@ -2,32 +2,66 @@
local({
# the requested version of renv
- version <- "0.14.0"
+ version <- "1.0.3"
+ attr(version, "sha") <- NULL
# the project directory
project <- getwd()
- # allow environment variable to control activation
- activate <- Sys.getenv("RENV_ACTIVATE_PROJECT")
- if (!nzchar(activate)) {
+ # use start-up diagnostics if enabled
+ diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE")
+ if (diagnostics) {
+ start <- Sys.time()
+ profile <- tempfile("renv-startup-", fileext = ".Rprof")
+ utils::Rprof(profile)
+ on.exit({
+ utils::Rprof(NULL)
+ elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L)
+ writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed)))
+ writeLines(sprintf("- Profile: %s", profile))
+ print(utils::summaryRprof(profile))
+ }, add = TRUE)
+ }
- # don't auto-activate when R CMD INSTALL is running
- if (nzchar(Sys.getenv("R_INSTALL_PKG")))
- return(FALSE)
+ # figure out whether the autoloader is enabled
+ enabled <- local({
- }
+ # first, check config option
+ override <- getOption("renv.config.autoloader.enabled")
+ if (!is.null(override))
+ return(override)
+
+ # next, check environment variables
+ # TODO: prefer using the configuration one in the future
+ envvars <- c(
+ "RENV_CONFIG_AUTOLOADER_ENABLED",
+ "RENV_AUTOLOADER_ENABLED",
+ "RENV_ACTIVATE_PROJECT"
+ )
+
+ for (envvar in envvars) {
+ envval <- Sys.getenv(envvar, unset = NA)
+ if (!is.na(envval))
+ return(tolower(envval) %in% c("true", "t", "1"))
+ }
- # bail if activation was explicitly disabled
- if (tolower(activate) %in% c("false", "f", "0"))
+ # enable by default
+ TRUE
+
+ })
+
+ if (!enabled)
return(FALSE)
# avoid recursion
- if (nzchar(Sys.getenv("RENV_R_INITIALIZING")))
+ if (identical(getOption("renv.autoloader.running"), TRUE)) {
+ warning("ignoring recursive attempt to run renv autoloader")
return(invisible(TRUE))
+ }
# signal that we're loading renv during R startup
- Sys.setenv("RENV_R_INITIALIZING" = "true")
- on.exit(Sys.unsetenv("RENV_R_INITIALIZING"), add = TRUE)
+ options(renv.autoloader.running = TRUE)
+ on.exit(options(renv.autoloader.running = NULL), add = TRUE)
# signal that we've consented to use renv
options(renv.consent = TRUE)
@@ -36,33 +70,81 @@ local({
# mask 'utils' packages, will come first on the search path
library(utils, lib.loc = .Library)
- # check to see if renv has already been loaded
- if ("renv" %in% loadedNamespaces()) {
-
- # if renv has already been loaded, and it's the requested version of renv,
- # nothing to do
- spec <- .getNamespaceInfo(.getNamespace("renv"), "spec")
- if (identical(spec[["version"]], version))
- return(invisible(TRUE))
-
- # otherwise, unload and attempt to load the correct version of renv
+ # unload renv if it's already been loaded
+ if ("renv" %in% loadedNamespaces())
unloadNamespace("renv")
- }
-
# load bootstrap tools
+ `%||%` <- function(x, y) {
+ if (is.null(x)) y else x
+ }
+
+ catf <- function(fmt, ..., appendLF = TRUE) {
+
+ quiet <- getOption("renv.bootstrap.quiet", default = FALSE)
+ if (quiet)
+ return(invisible())
+
+ msg <- sprintf(fmt, ...)
+ cat(msg, file = stdout(), sep = if (appendLF) "\n" else "")
+
+ invisible(msg)
+
+ }
+
+ header <- function(label,
+ ...,
+ prefix = "#",
+ suffix = "-",
+ n = min(getOption("width"), 78))
+ {
+ label <- sprintf(label, ...)
+ n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L)
+ if (n <= 0)
+ return(paste(prefix, label))
+
+ tail <- paste(rep.int(suffix, n), collapse = "")
+ paste0(prefix, " ", label, " ", tail)
+
+ }
+
+ startswith <- function(string, prefix) {
+ substring(string, 1, nchar(prefix)) == prefix
+ }
+
bootstrap <- function(version, library) {
+ friendly <- renv_bootstrap_version_friendly(version)
+ section <- header(sprintf("Bootstrapping renv %s", friendly))
+ catf(section)
+
# attempt to download renv
- tarball <- tryCatch(renv_bootstrap_download(version), error = identity)
- if (inherits(tarball, "error"))
- stop("failed to download renv ", version)
+ catf("- Downloading renv ... ", appendLF = FALSE)
+ withCallingHandlers(
+ tarball <- renv_bootstrap_download(version),
+ error = function(err) {
+ catf("FAILED")
+ stop("failed to download:\n", conditionMessage(err))
+ }
+ )
+ catf("OK")
+ on.exit(unlink(tarball), add = TRUE)
# now attempt to install
- status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity)
- if (inherits(status, "error"))
- stop("failed to install renv ", version)
+ catf("- Installing renv ... ", appendLF = FALSE)
+ withCallingHandlers(
+ status <- renv_bootstrap_install(version, tarball, library),
+ error = function(err) {
+ catf("FAILED")
+ stop("failed to install:\n", conditionMessage(err))
+ }
+ )
+ catf("OK")
+ # add empty line to break up bootstrapping from normal output
+ catf("")
+
+ return(invisible())
}
renv_bootstrap_tests_running <- function() {
@@ -71,23 +153,32 @@ local({
renv_bootstrap_repos <- function() {
+ # get CRAN repository
+ cran <- getOption("renv.repos.cran", "https://cloud.r-project.org")
+
# check for repos override
repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA)
- if (!is.na(repos))
+ if (!is.na(repos)) {
+
+ # check for RSPM; if set, use a fallback repository for renv
+ rspm <- Sys.getenv("RSPM", unset = NA)
+ if (identical(rspm, repos))
+ repos <- c(RSPM = rspm, CRAN = cran)
+
return(repos)
- # if we're testing, re-use the test repositories
- if (renv_bootstrap_tests_running())
- return(getOption("renv.tests.repos"))
+ }
+
+ # check for lockfile repositories
+ repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity)
+ if (!inherits(repos, "error") && length(repos))
+ return(repos)
# retrieve current repos
repos <- getOption("repos")
# ensure @CRAN@ entries are resolved
- repos[repos == "@CRAN@"] <- getOption(
- "renv.repos.cran",
- "https://cloud.r-project.org"
- )
+ repos[repos == "@CRAN@"] <- cran
# add in renv.bootstrap.repos if set
default <- c(FALLBACK = "https://cloud.r-project.org")
@@ -100,31 +191,60 @@ local({
}
+ renv_bootstrap_repos_lockfile <- function() {
+
+ lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock")
+ if (!file.exists(lockpath))
+ return(NULL)
+
+ lockfile <- tryCatch(renv_json_read(lockpath), error = identity)
+ if (inherits(lockfile, "error")) {
+ warning(lockfile)
+ return(NULL)
+ }
+
+ repos <- lockfile$R$Repositories
+ if (length(repos) == 0)
+ return(NULL)
+
+ keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1))
+ vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1))
+ names(vals) <- keys
+
+ return(vals)
+
+ }
+
renv_bootstrap_download <- function(version) {
- # if the renv version number has 4 components, assume it must
- # be retrieved via github
- nv <- numeric_version(version)
- components <- unclass(nv)[[1]]
+ sha <- attr(version, "sha", exact = TRUE)
- methods <- if (length(components) == 4L) {
- list(
- renv_bootstrap_download_github
+ methods <- if (!is.null(sha)) {
+
+ # attempting to bootstrap a development version of renv
+ c(
+ function() renv_bootstrap_download_tarball(sha),
+ function() renv_bootstrap_download_github(sha)
)
+
} else {
- list(
- renv_bootstrap_download_cran_latest,
- renv_bootstrap_download_cran_archive
+
+ # attempting to bootstrap a release version of renv
+ c(
+ function() renv_bootstrap_download_tarball(version),
+ function() renv_bootstrap_download_cran_latest(version),
+ function() renv_bootstrap_download_cran_archive(version)
)
+
}
for (method in methods) {
- path <- tryCatch(method(version), error = identity)
+ path <- tryCatch(method(), error = identity)
if (is.character(path) && file.exists(path))
return(path)
}
- stop("failed to download renv ", version)
+ stop("All download methods failed")
}
@@ -140,43 +260,75 @@ local({
if (fixup)
mode <- "w+b"
- utils::download.file(
+ args <- list(
url = url,
destfile = destfile,
mode = mode,
quiet = TRUE
)
+ if ("headers" %in% names(formals(utils::download.file)))
+ args$headers <- renv_bootstrap_download_custom_headers(url)
+
+ do.call(utils::download.file, args)
+
}
- renv_bootstrap_download_cran_latest <- function(version) {
+ renv_bootstrap_download_custom_headers <- function(url) {
- spec <- renv_bootstrap_download_cran_latest_find(version)
+ headers <- getOption("renv.download.headers")
+ if (is.null(headers))
+ return(character())
+
+ if (!is.function(headers))
+ stopf("'renv.download.headers' is not a function")
+
+ headers <- headers(url)
+ if (length(headers) == 0L)
+ return(character())
+
+ if (is.list(headers))
+ headers <- unlist(headers, recursive = FALSE, use.names = TRUE)
+
+ ok <-
+ is.character(headers) &&
+ is.character(names(headers)) &&
+ all(nzchar(names(headers)))
+
+ if (!ok)
+ stop("invocation of 'renv.download.headers' did not return a named character vector")
- message("* Downloading renv ", version, " ... ", appendLF = FALSE)
+ headers
+ }
+
+ renv_bootstrap_download_cran_latest <- function(version) {
+
+ spec <- renv_bootstrap_download_cran_latest_find(version)
type <- spec$type
repos <- spec$repos
- info <- tryCatch(
- utils::download.packages(
- pkgs = "renv",
- destdir = tempdir(),
- repos = repos,
- type = type,
- quiet = TRUE
- ),
+ baseurl <- utils::contrib.url(repos = repos, type = type)
+ ext <- if (identical(type, "source"))
+ ".tar.gz"
+ else if (Sys.info()[["sysname"]] == "Windows")
+ ".zip"
+ else
+ ".tgz"
+ name <- sprintf("renv_%s%s", version, ext)
+ url <- paste(baseurl, name, sep = "/")
+
+ destfile <- file.path(tempdir(), name)
+ status <- tryCatch(
+ renv_bootstrap_download_impl(url, destfile),
condition = identity
)
- if (inherits(info, "condition")) {
- message("FAILED")
+ if (inherits(status, "condition"))
return(FALSE)
- }
# report success and return
- message("OK (downloaded ", type, ")")
- info[1, 2]
+ destfile
}
@@ -232,8 +384,6 @@ local({
urls <- file.path(repos, "src/contrib/Archive/renv", name)
destfile <- file.path(tempdir(), name)
- message("* Downloading renv ", version, " ... ", appendLF = FALSE)
-
for (url in urls) {
status <- tryCatch(
@@ -241,18 +391,47 @@ local({
condition = identity
)
- if (identical(status, 0L)) {
- message("OK")
+ if (identical(status, 0L))
return(destfile)
- }
}
- message("FAILED")
return(FALSE)
}
+ renv_bootstrap_download_tarball <- function(version) {
+
+ # if the user has provided the path to a tarball via
+ # an environment variable, then use it
+ tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA)
+ if (is.na(tarball))
+ return()
+
+ # allow directories
+ if (dir.exists(tarball)) {
+ name <- sprintf("renv_%s.tar.gz", version)
+ tarball <- file.path(tarball, name)
+ }
+
+ # bail if it doesn't exist
+ if (!file.exists(tarball)) {
+
+ # let the user know we weren't able to honour their request
+ fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist."
+ msg <- sprintf(fmt, tarball)
+ warning(msg)
+
+ # bail
+ return()
+
+ }
+
+ catf("- Using local tarball '%s'.", tarball)
+ tarball
+
+ }
+
renv_bootstrap_download_github <- function(version) {
enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
@@ -275,8 +454,6 @@ local({
on.exit(do.call(base::options, saved), add = TRUE)
}
- message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE)
-
url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version)
name <- sprintf("renv_%s.tar.gz", version)
destfile <- file.path(tempdir(), name)
@@ -286,40 +463,113 @@ local({
condition = identity
)
- if (!identical(status, 0L)) {
- message("FAILED")
+ if (!identical(status, 0L))
return(FALSE)
- }
- message("OK")
+ renv_bootstrap_download_augment(destfile)
+
return(destfile)
}
+ # Add Sha to DESCRIPTION. This is stop gap until #890, after which we
+ # can use renv::install() to fully capture metadata.
+ renv_bootstrap_download_augment <- function(destfile) {
+ sha <- renv_bootstrap_git_extract_sha1_tar(destfile)
+ if (is.null(sha)) {
+ return()
+ }
+
+ # Untar
+ tempdir <- tempfile("renv-github-")
+ on.exit(unlink(tempdir, recursive = TRUE), add = TRUE)
+ untar(destfile, exdir = tempdir)
+ pkgdir <- dir(tempdir, full.names = TRUE)[[1]]
+
+ # Modify description
+ desc_path <- file.path(pkgdir, "DESCRIPTION")
+ desc_lines <- readLines(desc_path)
+ remotes_fields <- c(
+ "RemoteType: github",
+ "RemoteHost: api.github.com",
+ "RemoteRepo: renv",
+ "RemoteUsername: rstudio",
+ "RemotePkgRef: rstudio/renv",
+ paste("RemoteRef: ", sha),
+ paste("RemoteSha: ", sha)
+ )
+ writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path)
+
+ # Re-tar
+ local({
+ old <- setwd(tempdir)
+ on.exit(setwd(old), add = TRUE)
+
+ tar(destfile, compression = "gzip")
+ })
+ invisible()
+ }
+
+ # Extract the commit hash from a git archive. Git archives include the SHA1
+ # hash as the comment field of the tarball pax extended header
+ # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html)
+ # For GitHub archives this should be the first header after the default one
+ # (512 byte) header.
+ renv_bootstrap_git_extract_sha1_tar <- function(bundle) {
+
+ # open the bundle for reading
+ # We use gzcon for everything because (from ?gzcon)
+ # > Reading from a connection which does not supply a 'gzip' magic
+ # > header is equivalent to reading from the original connection
+ conn <- gzcon(file(bundle, open = "rb", raw = TRUE))
+ on.exit(close(conn))
+
+ # The default pax header is 512 bytes long and the first pax extended header
+ # with the comment should be 51 bytes long
+ # `52 comment=` (11 chars) + 40 byte SHA1 hash
+ len <- 0x200 + 0x33
+ res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len])
+
+ if (grepl("^52 comment=", res)) {
+ sub("52 comment=", "", res)
+ } else {
+ NULL
+ }
+ }
+
renv_bootstrap_install <- function(version, tarball, library) {
# attempt to install it into project library
- message("* Installing renv ", version, " ... ", appendLF = FALSE)
dir.create(library, showWarnings = FALSE, recursive = TRUE)
+ output <- renv_bootstrap_install_impl(library, tarball)
+
+ # check for successful install
+ status <- attr(output, "status")
+ if (is.null(status) || identical(status, 0L))
+ return(status)
+
+ # an error occurred; report it
+ header <- "installation of renv failed"
+ lines <- paste(rep.int("=", nchar(header)), collapse = "")
+ text <- paste(c(header, lines, output), collapse = "\n")
+ stop(text)
+
+ }
+
+ renv_bootstrap_install_impl <- function(library, tarball) {
# invoke using system2 so we can capture and report output
bin <- R.home("bin")
exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
- r <- file.path(bin, exe)
- args <- c("--vanilla", "CMD", "INSTALL", "-l", shQuote(library), shQuote(tarball))
- output <- system2(r, args, stdout = TRUE, stderr = TRUE)
- message("Done!")
+ R <- file.path(bin, exe)
- # check for successful install
- status <- attr(output, "status")
- if (is.numeric(status) && !identical(status, 0L)) {
- header <- "Error installing renv:"
- lines <- paste(rep.int("=", nchar(header)), collapse = "")
- text <- c(header, lines, output)
- writeLines(text, con = stderr())
- }
+ args <- c(
+ "--vanilla", "CMD", "INSTALL", "--no-multiarch",
+ "-l", shQuote(path.expand(library)),
+ shQuote(path.expand(tarball))
+ )
- status
+ system2(R, args, stdout = TRUE, stderr = TRUE)
}
@@ -499,49 +749,92 @@ local({
renv_bootstrap_library_root <- function(project) {
+ prefix <- renv_bootstrap_profile_prefix()
+
path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA)
if (!is.na(path))
- return(path)
+ return(paste(c(path, prefix), collapse = "/"))
- path <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
- if (!is.na(path)) {
+ path <- renv_bootstrap_library_root_impl(project)
+ if (!is.null(path)) {
name <- renv_bootstrap_library_root_name(project)
- return(file.path(path, name))
+ return(paste(c(path, prefix, name), collapse = "/"))
}
- prefix <- renv_bootstrap_profile_prefix()
- paste(c(project, prefix, "renv/library"), collapse = "/")
+ renv_bootstrap_paths_renv("library", project = project)
}
- renv_bootstrap_validate_version <- function(version) {
+ renv_bootstrap_library_root_impl <- function(project) {
- loadedversion <- utils::packageDescription("renv", fields = "Version")
- if (version == loadedversion)
- return(TRUE)
+ root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
+ if (!is.na(root))
+ return(root)
+
+ type <- renv_bootstrap_project_type(project)
+ if (identical(type, "package")) {
+ userdir <- renv_bootstrap_user_dir()
+ return(file.path(userdir, "library"))
+ }
+
+ }
- # assume four-component versions are from GitHub; three-component
- # versions are from CRAN
- components <- strsplit(loadedversion, "[.-]")[[1]]
- remote <- if (length(components) == 4L)
- paste("rstudio/renv", loadedversion, sep = "@")
+ renv_bootstrap_validate_version <- function(version, description = NULL) {
+
+ # resolve description file
+ #
+ # avoid passing lib.loc to `packageDescription()` below, since R will
+ # use the loaded version of the package by default anyhow. note that
+ # this function should only be called after 'renv' is loaded
+ # https://github.com/rstudio/renv/issues/1625
+ description <- description %||% packageDescription("renv")
+
+ # check whether requested version 'version' matches loaded version of renv
+ sha <- attr(version, "sha", exact = TRUE)
+ valid <- if (!is.null(sha))
+ renv_bootstrap_validate_version_dev(sha, description)
else
- paste("renv", loadedversion, sep = "@")
+ renv_bootstrap_validate_version_release(version, description)
+
+ if (valid)
+ return(TRUE)
+
+ # the loaded version of renv doesn't match the requested version;
+ # give the user instructions on how to proceed
+ remote <- if (!is.null(description[["RemoteSha"]])) {
+ paste("rstudio/renv", description[["RemoteSha"]], sep = "@")
+ } else {
+ paste("renv", description[["Version"]], sep = "@")
+ }
+
+ # display both loaded version + sha if available
+ friendly <- renv_bootstrap_version_friendly(
+ version = description[["Version"]],
+ sha = description[["RemoteSha"]]
+ )
fmt <- paste(
"renv %1$s was loaded from project library, but this project is configured to use renv %2$s.",
- "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.",
- "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.",
+ "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.",
+ "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.",
sep = "\n"
)
-
- msg <- sprintf(fmt, loadedversion, version, remote)
- warning(msg, call. = FALSE)
+ catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote)
FALSE
}
+ renv_bootstrap_validate_version_dev <- function(version, description) {
+ expected <- description[["RemoteSha"]]
+ is.character(expected) && startswith(expected, version)
+ }
+
+ renv_bootstrap_validate_version_release <- function(version, description) {
+ expected <- description[["Version"]]
+ is.character(expected) && identical(expected, version)
+ }
+
renv_bootstrap_hash_text <- function(text) {
hashfile <- tempfile("renv-hash-")
@@ -561,6 +854,12 @@ local({
# warn if the version of renv loaded does not match
renv_bootstrap_validate_version(version)
+ # execute renv load hooks, if any
+ hooks <- getHook("renv::autoload")
+ for (hook in hooks)
+ if (is.function(hook))
+ tryCatch(hook(), error = warnify)
+
# load the project
renv::load(project)
@@ -576,7 +875,7 @@ local({
return(profile)
# check for a profile file (nothing to do if it doesn't exist)
- path <- file.path(project, "renv/local/profile")
+ path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project)
if (!file.exists(path))
return(NULL)
@@ -587,7 +886,7 @@ local({
# set RENV_PROFILE
profile <- contents[[1L]]
- if (nzchar(profile))
+ if (!profile %in% c("", "default"))
Sys.setenv(RENV_PROFILE = profile)
profile
@@ -597,7 +896,7 @@ local({
renv_bootstrap_profile_prefix <- function() {
profile <- renv_bootstrap_profile_get()
if (!is.null(profile))
- return(file.path("renv/profiles", profile))
+ return(file.path("profiles", profile, "renv"))
}
renv_bootstrap_profile_get <- function() {
@@ -621,6 +920,245 @@ local({
profile
}
+
+ renv_bootstrap_path_absolute <- function(path) {
+
+ substr(path, 1L, 1L) %in% c("~", "/", "\\") || (
+ substr(path, 1L, 1L) %in% c(letters, LETTERS) &&
+ substr(path, 2L, 3L) %in% c(":/", ":\\")
+ )
+
+ }
+
+ renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) {
+ renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv")
+ root <- if (renv_bootstrap_path_absolute(renv)) NULL else project
+ prefix <- if (profile) renv_bootstrap_profile_prefix()
+ components <- c(root, renv, prefix, ...)
+ paste(components, collapse = "/")
+ }
+
+ renv_bootstrap_project_type <- function(path) {
+
+ descpath <- file.path(path, "DESCRIPTION")
+ if (!file.exists(descpath))
+ return("unknown")
+
+ desc <- tryCatch(
+ read.dcf(descpath, all = TRUE),
+ error = identity
+ )
+
+ if (inherits(desc, "error"))
+ return("unknown")
+
+ type <- desc$Type
+ if (!is.null(type))
+ return(tolower(type))
+
+ package <- desc$Package
+ if (!is.null(package))
+ return("package")
+
+ "unknown"
+
+ }
+
+ renv_bootstrap_user_dir <- function() {
+ dir <- renv_bootstrap_user_dir_impl()
+ path.expand(chartr("\\", "/", dir))
+ }
+
+ renv_bootstrap_user_dir_impl <- function() {
+
+ # use local override if set
+ override <- getOption("renv.userdir.override")
+ if (!is.null(override))
+ return(override)
+
+ # use R_user_dir if available
+ tools <- asNamespace("tools")
+ if (is.function(tools$R_user_dir))
+ return(tools$R_user_dir("renv", "cache"))
+
+ # try using our own backfill for older versions of R
+ envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME")
+ for (envvar in envvars) {
+ root <- Sys.getenv(envvar, unset = NA)
+ if (!is.na(root))
+ return(file.path(root, "R/renv"))
+ }
+
+ # use platform-specific default fallbacks
+ if (Sys.info()[["sysname"]] == "Windows")
+ file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv")
+ else if (Sys.info()[["sysname"]] == "Darwin")
+ "~/Library/Caches/org.R-project.R/R/renv"
+ else
+ "~/.cache/R/renv"
+
+ }
+
+ renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) {
+ sha <- sha %||% attr(version, "sha", exact = TRUE)
+ parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L)))
+ paste(parts, collapse = "")
+ }
+
+ renv_bootstrap_exec <- function(project, libpath, version) {
+ if (!renv_bootstrap_load(project, libpath, version))
+ renv_bootstrap_run(version, libpath)
+ }
+
+ renv_bootstrap_run <- function(version, libpath) {
+
+ # perform bootstrap
+ bootstrap(version, libpath)
+
+ # exit early if we're just testing bootstrap
+ if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
+ return(TRUE)
+
+ # try again to load
+ if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
+ return(renv::load(project = getwd()))
+ }
+
+ # failed to download or load renv; warn the user
+ msg <- c(
+ "Failed to find an renv installation: the project will not be loaded.",
+ "Use `renv::activate()` to re-initialize the project."
+ )
+
+ warning(paste(msg, collapse = "\n"), call. = FALSE)
+
+ }
+
+ renv_json_read <- function(file = NULL, text = NULL) {
+
+ jlerr <- NULL
+
+ # if jsonlite is loaded, use that instead
+ if ("jsonlite" %in% loadedNamespaces()) {
+
+ json <- catch(renv_json_read_jsonlite(file, text))
+ if (!inherits(json, "error"))
+ return(json)
+
+ jlerr <- json
+
+ }
+
+ # otherwise, fall back to the default JSON reader
+ json <- catch(renv_json_read_default(file, text))
+ if (!inherits(json, "error"))
+ return(json)
+
+ # report an error
+ if (!is.null(jlerr))
+ stop(jlerr)
+ else
+ stop(json)
+
+ }
+
+ renv_json_read_jsonlite <- function(file = NULL, text = NULL) {
+ text <- paste(text %||% read(file), collapse = "\n")
+ jsonlite::fromJSON(txt = text, simplifyVector = FALSE)
+ }
+
+ renv_json_read_default <- function(file = NULL, text = NULL) {
+
+ # find strings in the JSON
+ text <- paste(text %||% read(file), collapse = "\n")
+ pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
+ locs <- gregexpr(pattern, text, perl = TRUE)[[1]]
+
+ # if any are found, replace them with placeholders
+ replaced <- text
+ strings <- character()
+ replacements <- character()
+
+ if (!identical(c(locs), -1L)) {
+
+ # get the string values
+ starts <- locs
+ ends <- locs + attr(locs, "match.length") - 1L
+ strings <- substring(text, starts, ends)
+
+ # only keep those requiring escaping
+ strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE)
+
+ # compute replacements
+ replacements <- sprintf('"\032%i\032"', seq_along(strings))
+
+ # replace the strings
+ mapply(function(string, replacement) {
+ replaced <<- sub(string, replacement, replaced, fixed = TRUE)
+ }, strings, replacements)
+
+ }
+
+ # transform the JSON into something the R parser understands
+ transformed <- replaced
+ transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE)
+ transformed <- gsub("[[{]", "list(", transformed, perl = TRUE)
+ transformed <- gsub("[]}]", ")", transformed, perl = TRUE)
+ transformed <- gsub(":", "=", transformed, fixed = TRUE)
+ text <- paste(transformed, collapse = "\n")
+
+ # parse it
+ json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]]
+
+ # construct map between source strings, replaced strings
+ map <- as.character(parse(text = strings))
+ names(map) <- as.character(parse(text = replacements))
+
+ # convert to list
+ map <- as.list(map)
+
+ # remap strings in object
+ remapped <- renv_json_remap(json, map)
+
+ # evaluate
+ eval(remapped, envir = baseenv())
+
+ }
+
+ renv_json_remap <- function(json, map) {
+
+ # fix names
+ if (!is.null(names(json))) {
+ lhs <- match(names(json), names(map), nomatch = 0L)
+ rhs <- match(names(map), names(json), nomatch = 0L)
+ names(json)[rhs] <- map[lhs]
+ }
+
+ # fix values
+ if (is.character(json))
+ return(map[[json]] %||% json)
+
+ # handle true, false, null
+ if (is.name(json)) {
+ text <- as.character(json)
+ if (text == "true")
+ return(TRUE)
+ else if (text == "false")
+ return(FALSE)
+ else if (text == "null")
+ return(NULL)
+ }
+
+ # recurse
+ if (is.recursive(json)) {
+ for (i in seq_along(json)) {
+ json[i] <- list(renv_json_remap(json[[i]], map))
+ }
+ }
+
+ json
+
+ }
# load the renv profile, if any
renv_bootstrap_profile_load(project)
@@ -634,35 +1172,9 @@ local({
# construct full libpath
libpath <- file.path(root, prefix)
- # attempt to load
- if (renv_bootstrap_load(project, libpath, version))
- return(TRUE)
-
- # load failed; inform user we're about to bootstrap
- prefix <- paste("# Bootstrapping renv", version)
- postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "")
- header <- paste(prefix, postfix)
- message(header)
-
- # perform bootstrap
- bootstrap(version, libpath)
-
- # exit early if we're just testing bootstrap
- if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
- return(TRUE)
-
- # try again to load
- if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
- message("* Successfully installed and loaded renv ", version, ".")
- return(renv::load())
- }
-
- # failed to download or load renv; warn the user
- msg <- c(
- "Failed to find an renv installation: the project will not be loaded.",
- "Use `renv::activate()` to re-initialize the project."
- )
+ # run bootstrap code
+ renv_bootstrap_exec(project, libpath, version)
- warning(paste(msg, collapse = "\n"), call. = FALSE)
+ invisible()
})