diff --git a/.Rbuildignore b/.Rbuildignore index 2958231..3b608b9 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -11,4 +11,5 @@ ^docs$ ^pkgdown$ ^README.html$ -^extras$ \ No newline at end of file +^extras$ +^vignettes/articles$ diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 70c8a25..16c6c8b 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -2,7 +2,7 @@ # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: [main, develop] + branches: [main, master] pull_request: release: types: [published] diff --git a/.gitignore b/.gitignore index 1a8ad42..8873f22 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ README.html SRS.* extras/SRS.qmd extras/SRS.docx +docs +inst/doc diff --git a/DESCRIPTION b/DESCRIPTION index b9fb042..56f5fdb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: studyGenerics Type: Package Title: A centralised repository of tested and frequently used methods for OMOP-CDM studies -Version: 0.0.0.9000 +Version: 0.0.0.9002 Authors@R: c( person( "Cesar", "Barboza", @@ -37,7 +37,13 @@ Imports: fs, usethis Config/roxygen2/version: 8.0.0 -Suggests: +Suggests: + gert, + gh, + knitr, + rmarkdown, testthat (>= 3.0.0) Config/testthat/edition: 3 URL: https://mi-erasmusmc.github.io/studyGenerics/ +VignetteBuilder: knitr +Config/Needs/website: rmarkdown diff --git a/NAMESPACE b/NAMESPACE index 58b8ee9..a381a5e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,8 +3,11 @@ export(arrangeCdmNames) export(assertCdmNames) export(createResultsDir) +export(developCheckout) export(getPkgZips) export(insertStructure) +export(issueOpen) +export(pullRequest) export(setLoggers) export(unZipStudyFiles) export(zipStudyFiles) @@ -16,6 +19,8 @@ importFrom(checkmate,assertCharacter) importFrom(checkmate,assertDirectoryExists) importFrom(checkmate,assertFileExists) importFrom(checkmate,assertLogical) +importFrom(checkmate,assertTRUE) +importFrom(checkmate,checkClass) importFrom(cli,cli_abort) importFrom(cli,cli_alert_danger) importFrom(cli,cli_alert_info) diff --git a/NEWS.md b/NEWS.md index 6781947..d5e6ab1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,15 @@ +# studyGenerics 0.0.9002 + +* New article about `insertStructure()` + +* New `updateColumnValues()` + +* 'macOS solves' article + +# studyGenerics 0.0.9001 + +* Version control functions: `issueOpen()`, `pullRequest`, `developCheckout` + # studyGenerics 0.0.9000 -* readme and initial functions. \ No newline at end of file +* readme and initial functions. diff --git a/R/getPkgZips.R b/R/getPkgZips.R index 6903e94..a72d57f 100644 --- a/R/getPkgZips.R +++ b/R/getPkgZips.R @@ -411,3 +411,33 @@ mockLock <- function() { return(lockfile) } +suppPackages <- function() { + list( + Packages = list( + devtools = list( + Package = "devtools", + Version = "2.5.2" + ), # 2.5.2 exists in multiple releases, should pick from the newest (R v4.6) + dplyr = list( + Package = "dplyr", + Version = "0.6" + ), # there is no 0.6 in any of the releases, should get v1.2.1 as alternate from R v4.4 + tidyrr = list( + Package = "tidyr", + Version = "1.3.2" + ), # tidyrr does not exist + RPostgres = list( + Package = "RPostgres", + Version = NULL + ), # no version provided, should get v1.4.10 as alternate from R v4.4 + renv = list( + Package = "renv", + Version = "1.0.7" + ), # renv already exists in lockfile, if override_lock = TRUE, should get v1.0.7 from R v4.2 + xfun = list( + Package = "xfun", + Version = NULL + ) + ) + ) # xfun already exists in lockfile, if override_lock = TRUE, should get v0.57 from R v4.4 +} diff --git a/R/updateColumnValues.R b/R/updateColumnValues.R new file mode 100644 index 0000000..01486b4 --- /dev/null +++ b/R/updateColumnValues.R @@ -0,0 +1,27 @@ +#' Update values in a summarised result +#' +#' @description +#' Updates the character values of specific column(s) in a summarised result object +#' (e.g., changing cohort names to a more polished version for Shiny app labels) +#' according to a given name mapping. +#' +#' @param summarised_result The summarised result with values to update. +#' @param names_map A named vector containing the mapping between old and new names. +#' @param variable The column name(s) containing the values to be updated in the +#' summarised result object. +#' +#' @returns The summarised result itself with updated values. +#' +updateColumnValues <- function( + summarised_result, + names_map, + variable +) { + + summarised_result[[variable]] <- dplyr::recode( + summarised_result[[variable]], + !!!names_map + ) + + return(summarised_result) +} \ No newline at end of file diff --git a/R/versionControl.R b/R/versionControl.R index 439ad10..ac11872 100644 --- a/R/versionControl.R +++ b/R/versionControl.R @@ -8,15 +8,24 @@ #' #' @returns A message with the link of the PR #' @importFrom checkmate assertCharacter assertLogical assertTRUE checkClass -#' @importFrom gh gh gh_tree_remote gh_token_exists -#' @importFrom gert git_branch_create git_branch #' @export -#' @examples issueOpen <- function( title, body, newBranch = FALSE ) { + if (!requireNamespace("gh", quietly = TRUE)) { + stop( + "Package \"gh\" must be installed to use this function.", + call. = FALSE + ) + } + if (!requireNamespace("gert", quietly = TRUE)) { + stop( + "Package \"gert\" must be installed to use this function.", + call. = FALSE + ) + } checkmate::assertCharacter( title, len = 1, @@ -85,15 +94,24 @@ issueOpen <- function( #' #' @returns A message with the link of the issue #' @importFrom checkmate assertCharacter assertLogical assertTRUE checkClass -#' @importFrom gh gh gh_tree_remote gh_token_exists -#' @importFrom gert git_branch_create git_branch #' @export -#' @examples pullRequest <- function( title, body, base = "develop" ) { + if (!requireNamespace("gh", quietly = TRUE)) { + stop( + "Package \"gh\" must be installed to use this function.", + call. = FALSE + ) + } + if (!requireNamespace("gert", quietly = TRUE)) { + stop( + "Package \"gert\" must be installed to use this function.", + call. = FALSE + ) + } checkmate::assertCharacter( title, len = 1, @@ -136,10 +154,14 @@ pullRequest <- function( #' and pull latest changes #' #' @returns Git log messages after checking out and pulling 'develop' -#' @importFrom gert git_branch_exists git_branch_checkout git_pull #' @export -#' @examples developCheckout <- function() { + if (!requireNamespace("gert", quietly = TRUE)) { + stop( + "Package \"gert\" must be installed to use this function.", + call. = FALSE + ) + } branch <- "develop" if (gert::git_branch_exists(branch)) { gert::git_branch_checkout( diff --git a/man/developCheckout.Rd b/man/developCheckout.Rd new file mode 100644 index 0000000..e22452d --- /dev/null +++ b/man/developCheckout.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/versionControl.R +\name{developCheckout} +\alias{developCheckout} +\title{`developCheckout()` is a wrapper for gert functions to swiftly default to develop +and pull latest changes} +\usage{ +developCheckout() +} +\value{ +Git log messages after checking out and pulling 'develop' +} +\description{ +`developCheckout()` is a wrapper for gert functions to swiftly default to develop +and pull latest changes +} diff --git a/man/insertDocs.Rd b/man/insertDocs.Rd index ddd3a3c..93cbcf9 100644 --- a/man/insertDocs.Rd +++ b/man/insertDocs.Rd @@ -4,7 +4,7 @@ \alias{insertDocs} \title{Insert default documentation files} \usage{ -insertDocs() +insertDocs(path) } \value{ No return value. diff --git a/man/issueOpen.Rd b/man/issueOpen.Rd new file mode 100644 index 0000000..bca03d0 --- /dev/null +++ b/man/issueOpen.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/versionControl.R +\name{issueOpen} +\alias{issueOpen} +\title{`issueOpen()` is a wrapper for gh::gh() to swiftly post +in the GitHub repository of the current project} +\usage{ +issueOpen(title, body, newBranch = FALSE) +} +\arguments{ +\item{title}{of the issue in character} + +\item{body}{of the issue in character} + +\item{newBranch}{Logical. Default TRUE, will open a new +branch in GitHub format} +} +\value{ +A message with the link of the PR +} +\description{ +`issueOpen()` is a wrapper for gh::gh() to swiftly post +in the GitHub repository of the current project +} diff --git a/man/pullRequest.Rd b/man/pullRequest.Rd new file mode 100644 index 0000000..f141647 --- /dev/null +++ b/man/pullRequest.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/versionControl.R +\name{pullRequest} +\alias{pullRequest} +\title{`pullRequest()` is a wrapper for gh::gh() to swiftly ask merging +code from the current branch} +\usage{ +pullRequest(title, body, base = "develop") +} +\arguments{ +\item{title}{of the issue in character} + +\item{body}{of the issue in character} + +\item{base}{The target branch, in character. Defaults to "develop"} +} +\value{ +A message with the link of the issue +} +\description{ +`pullRequest()` is a wrapper for gh::gh() to swiftly ask merging +code from the current branch +} diff --git a/man/updateColumnValues.Rd b/man/updateColumnValues.Rd new file mode 100644 index 0000000..5c5a237 --- /dev/null +++ b/man/updateColumnValues.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/updateColumnValues.R +\name{updateColumnValues} +\alias{updateColumnValues} +\title{Update values in a summarised result} +\usage{ +updateColumnValues(summarised_result, names_map, variable) +} +\arguments{ +\item{summarised_result}{The summarised result with values to update.} + +\item{names_map}{A named vector containing the mapping between old and new names.} + +\item{variable}{The column name(s) containing the values to be updated in the +summarised result object.} +} +\value{ +The summarised result itself with updated values. +} +\description{ +Updates the character values of specific column(s) in a summarised result object +(e.g., changing cohort names to a more polished version for Shiny app labels) +according to a given name mapping. +} diff --git a/studyGenerics.Rproj b/studyGenerics.Rproj index 270314b..f18f51a 100644 --- a/studyGenerics.Rproj +++ b/studyGenerics.Rproj @@ -1,4 +1,4 @@ -Version: 1.0 +sVersion: 1.0 RestoreWorkspace: Default SaveWorkspace: Default diff --git a/tests/testthat/test-cdmNames.R b/tests/testthat/test-cdmNames.R index 17f44ba..2c9c6f8 100644 --- a/tests/testthat/test-cdmNames.R +++ b/tests/testthat/test-cdmNames.R @@ -1,5 +1,5 @@ test_that("assertCdmNames works", { - # Assert a group of acryonims + # Assert a group of acronyms labels <- c( "BCR", "IQVIA LPD Belgium", @@ -9,9 +9,9 @@ test_that("assertCdmNames works", { ) assertCdmNames(labels = labels) |> expect_invisible() - # Error acronim do not match + # Error acronym do not match labels <- c( - "BCRX", # Mispelled acronym + "BCRX", # Misspelled acronym "IQVIA LPD Belgium", "NLHR@UiO:PERINATAL", "IQVIA US - AmbEMR", @@ -22,7 +22,7 @@ test_that("assertCdmNames works", { }) test_that("assertCdmNames against expected acronyms", { - # Assert a group of acryonims + # Assert a group of acronyms labels <- c( "BCR", "IQVIA LPD Belgium", @@ -42,7 +42,7 @@ test_that("assertCdmNames against expected acronyms", { expect_error() # Incorrect acronym labels <- c( - "BCRX", # Mispelled acronym + "BCRX", # Misspelled acronym "IQVIA LPD Belgium", "NLHR@UiO:PERINATAL", "IQVIA US - AmbEMR", @@ -78,9 +78,9 @@ test_that("arrangeCdmNames returns required acronyms in order", { "IQVIA US - AmbEMR", "IQVIA US - PMTX+" )) - # Error acronim do not match + # Error acronym do not match labels <- c( - "BCRX", # Mispelled acronym + "BCRX", # Misspelled acronym "IQVIA LPD Belgium", "NLHR@UiO:PERINATAL", "IQVIA US - AmbEMR", diff --git a/tests/testthat/test-getPkgZips.R b/tests/testthat/test-getPkgZips.R index 0daaf50..22257e8 100644 --- a/tests/testthat/test-getPkgZips.R +++ b/tests/testthat/test-getPkgZips.R @@ -44,7 +44,8 @@ test_that("Message checks - lockfile only", { # Test on lockfile + supp, override_lock = FALSE ---- test_that("Message checks - lockfile + supp, override_lock = FALSE", { - msgs <- capture_messages(pkg_summary <- getPkgZips(lockfile_path = lockfile, supplement = supp)) + lockfile <- mockLock() + msgs <- capture_messages(pkg_summary <- getPkgZips(lockfile_path = lockfile, supplement = suppPackages())) expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find DarwinShinyModules v0.4.0 or a suitable alternate version under R v4.4", msgs))) expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find utils vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) @@ -71,7 +72,7 @@ test_that("Message checks - lockfile + supp, override_lock = FALSE", { test_that("Message checks - lockfile + supp, override_lock = TRUE", { lockfile <- mockLock() - msgs <- capture_messages(pkg_summary <- getPkgZips(lockfile_path = lockfile, supplement = supp, override_lock = TRUE)) + msgs <- capture_messages(pkg_summary <- getPkgZips(lockfile_path = lockfile, supplement = suppPackages(), override_lock = TRUE)) expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find DarwinShinyModules v0.4.0 or a suitable alternate version under R v4.4", msgs))) expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find utils vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) @@ -103,34 +104,8 @@ test_that("mockLock()", { lockfile <- mockLock() # Create a supplementary file ---- - supp <- list( - Packages = list( - devtools = list( - Package = "devtools", - Version = "2.5.2" - ), # 2.5.2 exists in multiple releases, should pick from the newest (R v4.6) - dplyr = list( - Package = "dplyr", - Version = "0.6" - ), # there is no 0.6 in any of the releases, should get v1.2.1 as alternate from R v4.4 - tidyrr = list( - Package = "tidyr", - Version = "1.3.2" - ), # tidyrr does not exist - RPostgres = list( - Package = "RPostgres", - Version = NULL - ), # no version provided, should get v1.4.10 as alternate from R v4.4 - renv = list( - Package = "renv", - Version = "1.0.7" - ), # renv already exists in lockfile, if override_lock = TRUE, should get v1.0.7 from R v4.2 - xfun = list( - Package = "xfun", - Version = NULL - ) - ) - ) # xfun already exists in lockfile, if override_lock = TRUE, should get v0.57 from R v4.4 + supp <- suppPackages() + # Sanity check of counts ---- lock <- renv::lockfile_read(lockfile) pkgs <- names(lock[["Packages"]]) @@ -151,7 +126,6 @@ test_that("mockLock()", { expect_equal(n_reqs, 46) # expect_equal(n_reqs_wo_overlap, 41) expect_equal(n_all, 56) # not 58 bc of the supps overlap - }) diff --git a/tests/testthat/test-updateColumnValues.R b/tests/testthat/test-updateColumnValues.R new file mode 100644 index 0000000..5e5c1dd --- /dev/null +++ b/tests/testthat/test-updateColumnValues.R @@ -0,0 +1,48 @@ +test_that("updateColumnValues updates summarised result correctly", { + + # Create mock summarised result + x <- dplyr::tibble( + "result_id" = 1L, + "cdm_name" = "cprd", + "group_name" = "cohort_name", + "group_level" = c( + "acetaminophen", + "acetaminophen", + "diclofenac", + "ibuprofen" + ), + "strata_name" = "sex &&& age_group", + "strata_level" = c( + "male &&& <40", + "male &&& >=40", + "male &&& >=40", + "male &&& >=40" + ), + "variable_name" = "number_subjects", + "variable_level" = NA_character_, + "estimate_name" = "count", + "estimate_type" = "integer", + "estimate_value" = c("5", "15", "8", "12"), + "additional_name" = "overall", + "additional_level" = "overall" + ) |> + omopgenerics::newSummarisedResult() + + # Define mapping to custom new names + names_map <- c( + "acetaminophen" = "Acetamoniphen cohort", + "diclofenac" ="Diclofenac cohort (outdated)", + "ibuprofen" = "Ibuprofen cohort" + ) + + # Test function + x <- updateColumnValues( + summarised_result = x, + names_map = names_map, + variable = "group_level" + ) + + check_names <- all(x$group_level %in% unname(names_map)) + expect_true(check_names) + +}) diff --git a/tests/testthat/test-versionControl.R b/tests/testthat/test-versionControl.R deleted file mode 100644 index d259011..0000000 --- a/tests/testthat/test-versionControl.R +++ /dev/null @@ -1,6 +0,0 @@ -test_that("Opening issue and creating branch", { - issueOpen( - title = "Title Test Issue studyGenerics", - body = "Body Test Issue studyGenerics" - ) -}) diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..47018d6 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,5 @@ +*.html +*.R + +/.quarto/ +**/*.quarto_ipynb diff --git a/vignettes/articles/.gitignore b/vignettes/articles/.gitignore new file mode 100644 index 0000000..ad29309 --- /dev/null +++ b/vignettes/articles/.gitignore @@ -0,0 +1,2 @@ +/.quarto/ +**/*.quarto_ipynb diff --git a/vignettes/articles/macos_solves.Rmd b/vignettes/articles/macos_solves.Rmd new file mode 100644 index 0000000..aed17ae --- /dev/null +++ b/vignettes/articles/macos_solves.Rmd @@ -0,0 +1,79 @@ +--- +title: "macOS solves" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{macos_solves} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +A reference of recurrent instructions specific for macOS. + +## R + Java + +Depends a bit on how you've installed java (package manager vs. direct download) + +### 1. Terminal + +```bash +# Homebrew +brew info openjdk +ls /opt/homebrew/opt/openjdk # expected installation location +brew --prefix openjdk # prints actual installation path (should be /opt/homebrew/opt/openjdk) +brew list | grep openjdk + +# Look for installs on computer +/usr/libexec/java_home -V # list all java installs on computer + + +# R CMD javareconf # R reconfiguration + +export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home # output either from /usr/libexec/java_home -V or brew --prefix openjdk +sudo R CMD javareconf # R reconfiguration with admin privileges +``` + +### 2. R + +```R +# Then restart R session! +install.packages("rJava") # should work now +``` + +## R + gettext + +Might get an error linked to gettext when trying to install a package in R + +### 1. Terminal + +```bash +# Install gettext with homebrew +brew install gettext + +# Update Makeovers +cd ~/.R +ls +nano Makevars # or whatever text editor +``` + +In Makevars, add the following lines: + +```make +LDFLAGS += -L/opt/homebrew/opt/gettext/lib +CPPFLAGS += -I/opt/homebrew/opt/gettext/include +``` + +Save the update and close the text editor + +### 2. R + +```R +# restart R and retry the installation +install.packages("iCantRememberTheNameOfThePackageIhadThisIssueWith") +``` diff --git a/vignettes/articles/new_study_package.Rmd b/vignettes/articles/new_study_package.Rmd new file mode 100644 index 0000000..f8bdbd7 --- /dev/null +++ b/vignettes/articles/new_study_package.Rmd @@ -0,0 +1,50 @@ +--- +title: "Inserting a New Package Structure" +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +## Create an empty project + +First, create a new empty project for your new study package with the package use this or from the menu in RStudio (Menu > File > New Project). The package will open a new instance of Positron or Rstudio. + +```{r, eval=FALSE} +library(usethis) + +usethis::create_package( + path = "~/P1C1001" + ) + +``` + +## Initiate an environment + +Inside the new study package use `renv` to initialise a new environment to start installing packages and install `studyGenerics` + +```{r, eval=FALSE} +library(renv) + +renv::init() + +renv::install("mi-erasmusmc/studyGenerics") + +``` + +## Insert the structure + +Finally, use the function `studyGenerics::insertStructure` to create a common configuration of packages and files to start developing a study package. You can use the parameter `n_obj` to define the number of objectives in your study. This will create a file to write a script for each objective in the /R folder. + +```{r, eval=FALSE} +library(studyGenerics) + +studyGenerics::insertStructure( + path = ".", # Default to create the study structure in the package you are currently in + n_obj = 3 # Default 3, in number. +) + +``` \ No newline at end of file diff --git a/vignettes/articles/renv.lock b/vignettes/articles/renv.lock new file mode 100644 index 0000000..5d1f54c --- /dev/null +++ b/vignettes/articles/renv.lock @@ -0,0 +1,607 @@ +{ + "R": { + "Version": "4.4.1", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://packagemanager.posit.co/cran/latest" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.6.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "d4335fe7207f1c01ab8c41762f5840d4" + }, + "askpass": { + "Package": "askpass", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "sys" + ], + "Hash": "c39f4155b3ceb1a9a2799d700fbd4b6a" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-6", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "5edb675b7baa6e9a0d86dd2c28de1676" + }, + "bslib": { + "Package": "bslib", + "Version": "0.11.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "cachem", + "fastmap", + "grDevices", + "htmltools", + "jquerylib", + "jsonlite", + "lifecycle", + "memoise", + "mime", + "rlang", + "sass" + ], + "Hash": "82c0dcea3e967cfeaa263e920798a77e" + }, + "cachem": { + "Package": "cachem", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "fastmap", + "rlang" + ], + "Hash": "cd9a672193789068eb5a2aad65a0dedf" + }, + "cli": { + "Package": "cli", + "Version": "3.6.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "a73d822b669d443ff8de6928f9c49850" + }, + "clipr": { + "Package": "clipr", + "Version": "0.8.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "utils" + ], + "Hash": "3f038e5ac7f41d4ac41ce658c85e3042" + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grDevices", + "methods", + "utils" + ], + "Hash": "859d96e65ef198fd43e82b9628d593ef" + }, + "credentials": { + "Package": "credentials", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "askpass", + "curl", + "jsonlite", + "openssl", + "sys" + ], + "Hash": "bda033f0a309540bb66d5e85872c6973" + }, + "curl": { + "Package": "curl", + "Version": "7.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "2e004ed19964915a8faf48a574439be9" + }, + "desc": { + "Package": "desc", + "Version": "1.4.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "cli", + "utils" + ], + "Hash": "99b79fcbd6c4d1ce087f5c5c758b384f" + }, + "digest": { + "Package": "digest", + "Version": "0.6.39", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "utils" + ], + "Hash": "d18028e978a88b2b16ef8d400cb49adf" + }, + "evaluate": { + "Package": "evaluate", + "Version": "1.0.5", + "Source": "Repository", + "Repository": "https://cloud.r-project.org", + "Requirements": [ + "R" + ], + "Hash": "94cf2c54237f6841cee68e3ba4ab5a14" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "htmltools", + "rlang" + ], + "Hash": "bd1297f9b5b1fc1372d19e2c4cd82215" + }, + "fs": { + "Package": "fs", + "Version": "2.1.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "methods" + ], + "Hash": "09278623bca442bc53b0940ffa2f6d87" + }, + "gert": { + "Package": "gert", + "Version": "2.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "askpass", + "credentials", + "openssl", + "rstudioapi", + "sys", + "zip" + ], + "Hash": "8c696f49b5150a2541af009311c2fc83" + }, + "gh": { + "Package": "gh", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "gitcreds", + "glue", + "httr2", + "ini", + "jsonlite", + "lifecycle", + "rlang" + ], + "Hash": "d92acb7afad09df6839e4e456e538d03" + }, + "gitcreds": { + "Package": "gitcreds", + "Version": "0.1.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "ab08ac61f3e1be454ae21911eb8bc2fe" + }, + "glue": { + "Package": "glue", + "Version": "1.8.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "f8122473e9a49e00d0642f78235ca5e3" + }, + "highr": { + "Package": "highr", + "Version": "0.12", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "xfun" + ], + "Hash": "2a2f862ade01a56dcbcd60944de11255" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.9", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "base64enc", + "digest", + "fastmap", + "grDevices", + "rlang", + "utils" + ], + "Hash": "102298e238c14eb830cc4b5edd23c3e8" + }, + "httr2": { + "Package": "httr2", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "curl", + "glue", + "lifecycle", + "magrittr", + "openssl", + "rappdirs", + "rlang", + "vctrs", + "withr" + ], + "Hash": "c20959a9442c0e3adb1e8d3809c5d1f7" + }, + "ini": { + "Package": "ini", + "Version": "0.3.1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "6154ec2223172bce8162d4153cda21f7" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "htmltools" + ], + "Hash": "5aab57a3bd297eee1c1d862735972182" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "2.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods" + ], + "Hash": "b0776f526d36d8bd4a3344a88fe165c4" + }, + "knitr": { + "Package": "knitr", + "Version": "1.51", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "evaluate", + "highr", + "methods", + "tools", + "xfun", + "yaml" + ], + "Hash": "27682babb50f03b6eb7939ea69ec79ca" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "rlang" + ], + "Hash": "36dbfe4fba6c064db50a671a90297c85" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "665e77ab6e5f37a7913226d40b324e37" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "cachem", + "rlang" + ], + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mime": { + "Package": "mime", + "Version": "0.13", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tools" + ], + "Hash": "0ec19f34c72fab674d8f2b4b1c6410e1" + }, + "openssl": { + "Package": "openssl", + "Version": "2.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "askpass" + ], + "Hash": "865a99ecdce7c318efa3a467b7614ec3" + }, + "purrr": { + "Package": "purrr", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "lifecycle", + "magrittr", + "rlang", + "vctrs" + ], + "Hash": "0a35605539b085a4828ec55ad973fe60" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "f146a5bfc94db048309712535d4d0aee" + }, + "renv": { + "Package": "renv", + "Version": "1.0.11", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "utils" + ], + "Hash": "47623f66b4e80b3b0587bc5d7b309888" + }, + "rlang": { + "Package": "rlang", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "f88151fb9ca15e72dc351deb1328716e" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.31", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ], + "Hash": "f34039d57d861d2869cbf9be813ed08e" + }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "b2453de2d29aa646afe4781defdc7903" + }, + "rstudioapi": { + "Package": "rstudioapi", + "Version": "0.18.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "d6e1ecf8e39b6d53c8acde372b2f92d1" + }, + "sass": { + "Package": "sass", + "Version": "0.4.10", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ], + "Hash": "3fb78d066fb92299b1d13f6a7c9a90a8" + }, + "sys": { + "Package": "sys", + "Version": "3.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "de342ebfebdbf40477d0758d05426646" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.59", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "xfun" + ], + "Hash": "2688c3e240d4ccc7d6aae804f7fdf322" + }, + "usethis": { + "Package": "usethis", + "Version": "3.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "clipr", + "crayon", + "curl", + "desc", + "fs", + "gert", + "gh", + "glue", + "jsonlite", + "lifecycle", + "purrr", + "rappdirs", + "rlang", + "rprojroot", + "rstudioapi", + "stats", + "tools", + "utils", + "whisker", + "withr", + "yaml" + ], + "Hash": "caa93b7eada0b69e299f61db5984faa7" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.7.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang" + ], + "Hash": "2dcde2d30d3ad67bf1d3a37177457b87" + }, + "whisker": { + "Package": "whisker", + "Version": "0.4.1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "c6abfa47a46d281a7d5159d0a8891e88" + }, + "withr": { + "Package": "withr", + "Version": "3.0.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics" + ], + "Hash": "cc2d62c76458d425210d1eb1478b30b4" + }, + "xfun": { + "Package": "xfun", + "Version": "0.57", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "stats", + "tools" + ], + "Hash": "476c8908ae56baf122e69bb2c2d9f631" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.12", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "7cd77cb32abd9220d744307e9fc94ffb" + }, + "zip": { + "Package": "zip", + "Version": "3.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "cli" + ], + "Hash": "b6637f22cadc4e12ad70c4b7d8d63e15" + } + } +}