From 6f1abfeaa71e17cf10e58e9c9f4d1351ef638fd9 Mon Sep 17 00:00:00 2001 From: Nicholas Masel Date: Wed, 9 Oct 2024 13:39:08 +0000 Subject: [PATCH 1/8] remove nulls before setting autos --- DESCRIPTION | 2 +- R/autos.R | 7 ++- tests/testthat/_snaps/R4.4/autos.md | 8 +++ tests/testthat/_snaps/R4.4/init.md | 57 +++++++++++++++++++ .../testthat/man/_envsetup_testthat_null.yml | 33 +++++++++++ tests/testthat/test-autos.R | 13 +++++ 6 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 tests/testthat/_snaps/R4.4/autos.md create mode 100644 tests/testthat/_snaps/R4.4/init.md create mode 100644 tests/testthat/man/_envsetup_testthat_null.yml diff --git a/DESCRIPTION b/DESCRIPTION index c0de556..014be4e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -17,7 +17,7 @@ Description: The purpose of this package is to support the setup the R environme License: Apache License 2.0 Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Imports: config, fs, diff --git a/R/autos.R b/R/autos.R index 37b30b8..4be213d 100644 --- a/R/autos.R +++ b/R/autos.R @@ -24,6 +24,11 @@ set_autos <- function(autos, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON")) stop("Paths for autos in your envsetup configuration file must be named", call.=FALSE) } + # remove NULL before further processing + # NULL is expected for hierarchical paths when running in an environment + # after the first level of the hierarchy + autos <- autos[!vapply(autos, is.null, FALSE)] + for (i in seq_along(autos)) { cur_autos <- autos[[i]] @@ -291,4 +296,4 @@ library <- function(..., pos = NULL) { pos <- min(grep("^package:", search())) } base::library(..., pos = pos) -} \ No newline at end of file +} diff --git a/tests/testthat/_snaps/R4.4/autos.md b/tests/testthat/_snaps/R4.4/autos.md new file mode 100644 index 0000000..018ac22 --- /dev/null +++ b/tests/testthat/_snaps/R4.4/autos.md @@ -0,0 +1,8 @@ +# Autos warns user when ENVSETUP_ENVIRON does not match named environments in autos + + Code + suppressMessages(rprofile(custom_name)) + Condition + Warning: + The projects autos has named environments DEV, QA, PROD that do not match with the envsetup_environ parameter or ENVSETUP_ENVIRON environment variable bad_name + diff --git a/tests/testthat/_snaps/R4.4/init.md b/tests/testthat/_snaps/R4.4/init.md new file mode 100644 index 0000000..55cdbd6 --- /dev/null +++ b/tests/testthat/_snaps/R4.4/init.md @@ -0,0 +1,57 @@ +# init creates a .Rprofile + + Code + init(init_tmpdir, config_path, create_paths = FALSE) + Message + v Configuration file found! + i The following paths in your configuration do not exist: + /DEV/username/project1/data + /PROD/project1/data + /DEV/username/project1/programs + /PROD/project1/programs + /DEV/username/project1/functions + /PROD/project1/functions + /DEV/username/project1/output + /PROD/project1/output + i All path objects will not work since directories are missing. + v .Rprofile created + v envsetup initialization complete + +# init initializes an .Rprofile correcty when one does not exist + + Code + init(init_tmpdir, config_path, create_paths = FALSE) + Message + v Configuration file found! + i The following paths in your configuration do not exist: + /DEV/username/project1/data + /PROD/project1/data + /DEV/username/project1/programs + /PROD/project1/programs + /DEV/username/project1/functions + /PROD/project1/functions + /DEV/username/project1/output + /PROD/project1/output + i All path objects will not work since directories are missing. + v .Rprofile created + v envsetup initialization complete + +# init initializes an .Rprofile correcty when one does exist + + Code + init(init_tmpdir, config_path, create_paths = FALSE) + Message + v Configuration file found! + i The following paths in your configuration do not exist: + /DEV/username/project1/data + /PROD/project1/data + /DEV/username/project1/programs + /PROD/project1/programs + /DEV/username/project1/functions + /PROD/project1/functions + /DEV/username/project1/output + /PROD/project1/output + i All path objects will not work since directories are missing. + v .Rprofile updated + v envsetup initialization complete + diff --git a/tests/testthat/man/_envsetup_testthat_null.yml b/tests/testthat/man/_envsetup_testthat_null.yml new file mode 100644 index 0000000..8a2cb1d --- /dev/null +++ b/tests/testthat/man/_envsetup_testthat_null.yml @@ -0,0 +1,33 @@ +default: + project_path: !expr Sys.setenv(ENVSETUP_PROJECT_PATH = Sys.getenv("testpath")); + Sys.getenv("testpath") + paths: + data: !expr list( + DEV = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "DEV", "data"), + QA = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "QA", "data"), + PROD = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "PROD", "data") + ) + programs: !expr list( + DEV = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "DEV", "programs"), + QA = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "QA", "programs"), + PROD = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "PROD", "programs") + ) + functions: !expr list( + DEV = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "DEV", "functions"), + QA = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "QA", "functions"), + PROD = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "PROD", "functions") + ) + output: !expr list( + DEV = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "DEV", "output"), + QA = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "QA", "output"), + PROD = file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "PROD", "output") + ) + autos: + projects: !expr NULL + global: !expr file.path(Sys.getenv("ENVSETUP_PROJECT_PATH"), "global", "functions") + envre: !expr file.path( + Sys.getenv("ENVSETUP_PROJECT_PATH"), + "PROD", + "functions", + "envre.R" + ) diff --git a/tests/testthat/test-autos.R b/tests/testthat/test-autos.R index 52ea3bb..93b7581 100644 --- a/tests/testthat/test-autos.R +++ b/tests/testthat/test-autos.R @@ -8,6 +8,7 @@ file.copy(testthat::test_path("man/testdir/DEV"), tmpdir, recursive = TRUE) file.copy(testthat::test_path("man/testdir/global"), tmpdir, recursive = TRUE) file.copy(testthat::test_path("man/testdir/PROD"), tmpdir, recursive = TRUE) file.copy(testthat::test_path("man/testdir/QA"), tmpdir, recursive = TRUE) +dir.create(file.path(tmpdir, "returns_null")) custom_name <- config::get( file = testthat::test_path("man/_envsetup_testthat.yml") @@ -125,3 +126,15 @@ test_that("Autos warns user when ENVSETUP_ENVIRON does not match named environme expect_snapshot(suppressMessages(rprofile(custom_name)), variant = r_version()) }) + + +#' @editor Nick Masel +#' @editDate 2024-10-24 +detach_autos() +Sys.setenv(ENVSETUP_ENVIRON = "QA") +null_test <- config::get( + file = testthat::test_path("man/_envsetup_testthat_null.yml") +) +test_that("NULL paths do not throw an error", { + expect_no_error(set_autos(null_test$autos)) +}) From 007e4de258a4a36765abc7ab4be9234e4e07f36d Mon Sep 17 00:00:00 2001 From: Nicholas Masel Date: Wed, 9 Oct 2024 13:46:24 +0000 Subject: [PATCH 2/8] bump version, add news --- DESCRIPTION | 2 +- NEWS.md | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 014be4e..ac3bde6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: envsetup Title: Support the Setup of the R Environment for Clinical Trial Programming Workflows -Version: 0.2.0 +Version: 0.2.1 Authors@R: c( person("Nicholas", "Masel", email = "nmasel@its.jnj.com", role = c("aut", "cre")), person("Mike", "Stackhouse", email = "mike.stackhouse@atorusresearch.com", role = c("aut"), comment = c(ORCID = "0000-0001-6030-723X")), diff --git a/NEWS.md b/NEWS.md index b681d68..fc32219 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,8 +1,11 @@ +# envsetup 0.2.1 + +- `set_autos()` will how handle NULL hierarchical paths (#66) + # envsetup 0.2.0 - `library()` will no longer actively reset autos, instead placing newly attached packages in the correct position that respects existing autos (#59) - # envsetup 0.1.0 - Minor updates to prepare for initial CRAN release (#55) From 3b52da76b6433114c9c1de3007f83939023b580b Mon Sep 17 00:00:00 2001 From: Nicholas Masel <61123199+nicholas-masel@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:58:25 -0400 Subject: [PATCH 3/8] update devel w/main (#68) * initial updates * update documentation and snapshots * Update cran-comments.md --------- Co-authored-by: Michael Stackhouse --- DESCRIPTION | 6 +++--- LICENSE | 13 ------------- R/init.R | 4 ++-- cran-comments.md | 7 +++++++ man/init.Rd | 4 ++-- tests/testthat/_snaps/R4.2/autos.md | 3 ++- tests/testthat/_snaps/R4.2/init.md | 6 +++--- tests/testthat/_snaps/utils.md | 8 ++++---- 8 files changed, 23 insertions(+), 28 deletions(-) delete mode 100644 LICENSE diff --git a/DESCRIPTION b/DESCRIPTION index cfaf315..c0de556 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -9,12 +9,12 @@ Authors@R: c( person("Atorus Research LLC", role = "cph") ) Description: The purpose of this package is to support the setup the R environment. - The two main features are `autos`, to automatically source files and/or - directories into your environment, and `paths` to consistently set path objects + The two main features are 'autos', to automatically source files and/or + directories into your environment, and 'paths' to consistently set path objects across projects for input and output. Both are implemented using a configuration file to allow easy, custom configurations that can be used for multiple or all projects. -License: Apache License 2.0 | file LICENSE +License: Apache License 2.0 Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.1 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 223c83b..0000000 --- a/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2022 Janssen R&D - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/R/init.R b/R/init.R index b12bdfa..f701308 100644 --- a/R/init.R +++ b/R/init.R @@ -1,6 +1,6 @@ #' Initialize the R environment with envsetup #' -#' @param project Character. The path to the project directory. Defaults to the current working directory. +#' @param project Character. The path to the project directory. #' @param config_path Character. The path of the config file. Defaults to NULL. #' @param create_paths Logical indicating if missing paths should be created. Defaults to NULL. #' @export @@ -36,7 +36,7 @@ #' init(project = tmpdir, #' config_path = file.path(tmpdir, "hierarchy.yml"), #' create_paths = TRUE) -init <- function(project = getwd(), config_path = NULL, create_paths = NULL) { +init <- function(project, config_path = NULL, create_paths = NULL) { create_config <- FALSE config_found <- FALSE diff --git a/cran-comments.md b/cran-comments.md index 368ba59..4587b05 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,3 +1,10 @@ +## Resubmission +This is a resubmission. In this version I have: + +* Corrected quotations in the description. +* Removed the LICENSE file, as there are no additional restrictions. +* Removed the default write path in R/init.R. + ## envsetup 0.1.0 Tested on RHEL 7, RHEL 8, GitHub Action and RHub. diff --git a/man/init.Rd b/man/init.Rd index 4595308..293f5e0 100644 --- a/man/init.Rd +++ b/man/init.Rd @@ -4,10 +4,10 @@ \alias{init} \title{Initialize the R environment with envsetup} \usage{ -init(project = getwd(), config_path = NULL, create_paths = NULL) +init(project, config_path = NULL, create_paths = NULL) } \arguments{ -\item{project}{Character. The path to the project directory. Defaults to the current working directory.} +\item{project}{Character. The path to the project directory.} \item{config_path}{Character. The path of the config file. Defaults to NULL.} diff --git a/tests/testthat/_snaps/R4.2/autos.md b/tests/testthat/_snaps/R4.2/autos.md index 8797947..018ac22 100644 --- a/tests/testthat/_snaps/R4.2/autos.md +++ b/tests/testthat/_snaps/R4.2/autos.md @@ -2,6 +2,7 @@ Code suppressMessages(rprofile(custom_name)) - Warning + Condition + Warning: The projects autos has named environments DEV, QA, PROD that do not match with the envsetup_environ parameter or ENVSETUP_ENVIRON environment variable bad_name diff --git a/tests/testthat/_snaps/R4.2/init.md b/tests/testthat/_snaps/R4.2/init.md index 8773ae3..55cdbd6 100644 --- a/tests/testthat/_snaps/R4.2/init.md +++ b/tests/testthat/_snaps/R4.2/init.md @@ -2,7 +2,7 @@ Code init(init_tmpdir, config_path, create_paths = FALSE) - Message + Message v Configuration file found! i The following paths in your configuration do not exist: /DEV/username/project1/data @@ -21,7 +21,7 @@ Code init(init_tmpdir, config_path, create_paths = FALSE) - Message + Message v Configuration file found! i The following paths in your configuration do not exist: /DEV/username/project1/data @@ -40,7 +40,7 @@ Code init(init_tmpdir, config_path, create_paths = FALSE) - Message + Message v Configuration file found! i The following paths in your configuration do not exist: /DEV/username/project1/data diff --git a/tests/testthat/_snaps/utils.md b/tests/testthat/_snaps/utils.md index a86bffa..ff7f94e 100644 --- a/tests/testthat/_snaps/utils.md +++ b/tests/testthat/_snaps/utils.md @@ -2,7 +2,7 @@ Code validate_config(config::get(file = path)) - Message + Message v paths are specified as part of your configuration i no hierarchical paths found @@ -10,7 +10,7 @@ Code validate_config(config::get(file = path)) - Message + Message v paths are specified as part of your configuration v hierarchal paths found for: data @@ -21,7 +21,7 @@ Code validate_config(config::get(file = path)) - Message + Message v paths are specified as part of your configuration v hierarchal paths found for: data @@ -35,6 +35,6 @@ Code validate_config(config::get(file = path)) - Message + Message i no paths are specified as part of your configuration, skipping path valiation From c5d808438ac83ae884670b1a932bb68bf7aff2dd Mon Sep 17 00:00:00 2001 From: Nicholas Masel Date: Wed, 9 Oct 2024 14:44:31 +0000 Subject: [PATCH 4/8] fixed linter config and findings --- .lintr | 2 +- R/autos.R | 24 ++++++++++++------------ R/init.R | 7 ++++--- R/paths.R | 2 +- R/utils.R | 2 -- tests/testthat/ref/envre.R | 6 +++--- tests/testthat/ref/envre_preprod.R | 6 +++--- tests/testthat/ref/envre_prod.R | 6 +++--- tests/testthat/ref/func.R | 2 +- tests/testthat/test-autos.R | 24 ++++++++++++++---------- tests/testthat/test-paths.R | 15 ++++++++++----- tests/testthat/test-rprofile.R | 2 +- vignettes/config.Rmd | 8 ++++---- 13 files changed, 57 insertions(+), 49 deletions(-) diff --git a/.lintr b/.lintr index 976fcdd..65a862b 100644 --- a/.lintr +++ b/.lintr @@ -1,2 +1,2 @@ -linters: with_defaults(line_length_linter(125), object_usage_linter=NULL, cyclocomp_linter(complexity_limit = 20), object_name_linter(styles = c("snake_case", "symbols", "dotted.case")), single_quotes_linter=NULL) +linters: linters_with_defaults(line_length_linter(125), object_usage_linter=NULL, cyclocomp_linter(complexity_limit = 20), object_name_linter(styles = c("snake_case", "symbols", "dotted.case"))) exclusions: list("R/data.R") diff --git a/R/autos.R b/R/autos.R index 37b30b8..da932f7 100644 --- a/R/autos.R +++ b/R/autos.R @@ -21,7 +21,7 @@ set_autos <- function(autos, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON")) # Must be named list if (!is_named(autos)) { - stop("Paths for autos in your envsetup configuration file must be named", call.=FALSE) + stop("Paths for autos in your envsetup configuration file must be named", call. = FALSE) } for (i in seq_along(autos)) { @@ -30,7 +30,7 @@ set_autos <- function(autos, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON")) if (length(cur_autos) > 1) { # Hierarchical paths must be named if (!is_named(cur_autos)) { - stop("Hierarchical autos paths in your envsetup configuration file must be named", call.=FALSE) + stop("Hierarchical autos paths in your envsetup configuration file must be named", call. = FALSE) } # envsetup_environ must be used if using hierarchical paths @@ -43,7 +43,7 @@ set_autos <- function(autos, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON")) } if (!is.null(names(cur_autos)) && !envsetup_environ %in% names(cur_autos) - && envsetup_environ != ""){ + && envsetup_environ != "") { warning(paste( "The", ui_field(names(autos[i])), "autos has named", "environments", ui_field(names(cur_autos)), @@ -105,7 +105,7 @@ attach_auto <- function(path, name) { if (!(dir.exists(path) || file.exists(path))) { # Check if the auto actually exists warning(sprintf("An autos path specified in your envsetup configuration file does not exist: %s = %s", name, path), - call.=FALSE) + call. = FALSE) } else if (file.exists(path) && !dir.exists(path)) { # if file, source it sys.source(path, envir = attach(NULL, name = name_with_prefix)) @@ -282,13 +282,13 @@ detach_autos <- function() { #' # see autos are still above purrr in the search path #' search() library <- function(..., pos = NULL) { - if(is.null(pos)) { - ## we have at least one package loaded (envsetup itself) - ## use earliest current package position as place to - ## attach all future packages, regardless of what - ## envsetup, devtools, or anything else has put - ## in front of them - pos <- min(grep("^package:", search())) + if (is.null(pos)) { + ## we have at least one package loaded (envsetup itself) + ## use earliest current package position as place to + ## attach all future packages, regardless of what + ## envsetup, devtools, or anything else has put + ## in front of them + pos <- min(grep("^package:", search())) } base::library(..., pos = pos) -} \ No newline at end of file +} diff --git a/R/init.R b/R/init.R index f701308..a659141 100644 --- a/R/init.R +++ b/R/init.R @@ -68,7 +68,7 @@ init <- function(project, config_path = NULL, create_paths = NULL) { ui_info( c("The following paths in your configuration do not exist:", paths[missing_directories]) - ) + ) # if not, ask if user would like them built if (is.null(create_paths)) { @@ -76,7 +76,7 @@ init <- function(project, config_path = NULL, create_paths = NULL) { usethis::ui_yeah( "Would you like us to create your directories to match your configuration?", n_no = 1 - ) + ) } if (!create_paths) { @@ -134,7 +134,8 @@ envsetup_write_rprofile <- function(add, file) { # if there is a call to `rprofile()` in the .Rprofile, assume setup was already done and exit if (any(grepl("rprofile\\(", before))) { - warning("It looks like your project has already been initialized to use envsetup. Manually adjust your .Rprofile if you need to change the environment setup.", + warning("It looks like your project has already been initialized to use envsetup. + Manually adjust your .Rprofile if you need to change the environment setup.", call. = FALSE ) return(invisible()) diff --git a/R/paths.R b/R/paths.R index 25063cf..241cca3 100644 --- a/R/paths.R +++ b/R/paths.R @@ -218,7 +218,7 @@ object_in_path <- function(path, object) { #' Build directory structure from a configuration file #' -#' @param config configuration object from config::get() containing paths#' +#' @param config configuration object from config::get() containing paths #' @param root root directory to build from. #' Leave as NULL if using absolute paths. Set to working directory if using relative paths. #' diff --git a/R/utils.R b/R/utils.R index c4055bd..6a2e92c 100644 --- a/R/utils.R +++ b/R/utils.R @@ -63,8 +63,6 @@ #' validate_config(config::get(file = file.path(tmpdir, "no_paths.yml"))) validate_config <- function(config) { validate_paths(config) - - # validate_autos(config) } diff --git a/tests/testthat/ref/envre.R b/tests/testthat/ref/envre.R index 66013a1..5e8ad79 100644 --- a/tests/testthat/ref/envre.R +++ b/tests/testthat/ref/envre.R @@ -2,14 +2,14 @@ test_envre <- list() test_envre$PDEV <- get_path( topdrv, "PDEV", username, compound, protocol, dbrelease, rpteff, "analysis" - ) +) test_envre$PREPROD <- get_path( topdrv, "PREPROD", NA, compound, protocol, dbrelease, rpteff, "analysis" - ) +) test_envre$PROD <- get_path( topdrv, "PROD", NA, compound, protocol, dbrelease, rpteff, "analysis" - ) +) envre_loc <- "pdev" diff --git a/tests/testthat/ref/envre_preprod.R b/tests/testthat/ref/envre_preprod.R index c9a8db6..ac7450b 100644 --- a/tests/testthat/ref/envre_preprod.R +++ b/tests/testthat/ref/envre_preprod.R @@ -2,14 +2,14 @@ test_envre <- list() test_envre$PDEV <- get_path( topdrv, "PDEV", username, compound, protocol, dbrelease, rpteff, "analysis" - ) +) test_envre$PREPROD <- get_path( topdrv, "PREPROD", NA, compound, protocol, dbrelease, rpteff, "analysis" - ) +) test_envre$PROD <- get_path( topdrv, "PROD", NA, compound, protocol, dbrelease, rpteff, "analysis" - ) +) envre_loc <- "preprod" diff --git a/tests/testthat/ref/envre_prod.R b/tests/testthat/ref/envre_prod.R index 054316e..dbf3f1e 100644 --- a/tests/testthat/ref/envre_prod.R +++ b/tests/testthat/ref/envre_prod.R @@ -2,14 +2,14 @@ test_envre <- list() test_envre$PDEV <- get_path( topdrv, "PDEV", username, compound, protocol, dbrelease, rpteff, "analysis" - ) +) test_envre$PREPROD <- get_path( topdrv, "PREPROD", NA, compound, protocol, dbrelease, rpteff, "analysis" - ) +) test_envre$PROD <- get_path( topdrv, "PROD", NA, compound, protocol, dbrelease, rpteff, "analysis" - ) +) envre_loc <- "prod" diff --git a/tests/testthat/ref/func.R b/tests/testthat/ref/func.R index 652f88e..2748a13 100644 --- a/tests/testthat/ref/func.R +++ b/tests/testthat/ref/func.R @@ -1,3 +1,3 @@ func <- function() { print(rlang::env_parent()) - } +} diff --git a/tests/testthat/test-autos.R b/tests/testthat/test-autos.R index 52ea3bb..d47bfee 100644 --- a/tests/testthat/test-autos.R +++ b/tests/testthat/test-autos.R @@ -45,13 +45,16 @@ test_that("Autos validation from yml happens correctly", { # Hierarchical list is named expect_error( - set_autos(list(project = c("path1", "path2"))), "Hierarchical autos paths in your envsetup configuration file must be named" + set_autos(list(project = c("path1", "path2"))), + "Hierarchical autos paths in your envsetup configuration file must be named" ) # Paths are characters - expect_error(set_autos(list(global = 1)), "Paths provided for autos must be directories") + expect_error(set_autos(list(global = 1)), + "Paths provided for autos must be directories") - expect_warning(set_autos(list(x = "/bad/path/")), "An autos path specified in your envsetup configuration file does not exist") + expect_warning(set_autos(list(x = "/bad/path/")), + "An autos path specified in your envsetup configuration file does not exist") }) # Detatch and re-setup for QA now @@ -108,16 +111,17 @@ test_that("Autos no longer exist when detached", { test_that("the configuration can be named anything and library will reattach the autos correctly", { - suppressMessages(rprofile(custom_name)) + suppressMessages(rprofile(custom_name)) - expect_invisible(suppressPackageStartupMessages(library("purrr"))) + expect_invisible(suppressPackageStartupMessages(library("purrr"))) - purrr_location <- which(search() == "package:purrr") - autos_locatios <- which(grepl("^autos:", search())) + purrr_location <- which(search() == "package:purrr") + autos_locatios <- which(grepl("^autos:", search())) - expect_true(all(purrr_location > autos_locatios)) - detach("package:purrr") -}) + expect_true(all(purrr_location > autos_locatios)) + detach("package:purrr") + } +) test_that("Autos warns user when ENVSETUP_ENVIRON does not match named environments in autos", { diff --git a/tests/testthat/test-paths.R b/tests/testthat/test-paths.R index 51b9805..1231a0a 100644 --- a/tests/testthat/test-paths.R +++ b/tests/testthat/test-paths.R @@ -86,11 +86,16 @@ test_that("1.1", { #' @editor Aidan Ceney #' @editDate 2022-05-12 test_that("1.2", { - expect_error(readr::read_csv(read_path(data, - "iris.csv", - full.path = TRUE, - envsetup_environ = "PROD" - ))) + expect_error( + readr::read_csv( + read_path( + data, + "iris.csv", + full.path = TRUE, + envsetup_environ = "PROD" + ) + ) + ) }) #' @editor Aidan Ceney diff --git a/tests/testthat/test-rprofile.R b/tests/testthat/test-rprofile.R index d156b13..1011f40 100644 --- a/tests/testthat/test-rprofile.R +++ b/tests/testthat/test-rprofile.R @@ -41,7 +41,7 @@ test_that("rprofile stores the configuration", { stored_config <- base::get( "auto_stored_envsetup_config", pos = which(search() == "envsetup:paths") - ) + ) expect_equal(custom_name, stored_config) }) diff --git a/vignettes/config.Rmd b/vignettes/config.Rmd index d58a407..6639130 100644 --- a/vignettes/config.Rmd +++ b/vignettes/config.Rmd @@ -155,11 +155,11 @@ writeLines( paste0( "default: paths: - data: !expr list(DEV = '",dir,"/demo/DEV/username/project1/data', PROD = '",dir,"/demo/PROD/project1/data') - output: '",dir,"/demo/DEV/username/project1/output' - programs: '",dir,"/demo/DEV/username/project1/programs' + data: !expr list(DEV = '", dir,"/demo/DEV/username/project1/data', PROD = '", dir, "/demo/PROD/project1/data') + output: '", dir, "/demo/DEV/username/project1/output' + programs: '", dir, "/demo/DEV/username/project1/programs' envsetup_environ: !expr Sys.setenv(ENVSETUP_ENVIRON = 'DEV'); 'DEV'" - ), file_conn) + ), file_conn) close(file_conn) ``` From ef32d1c2491199b9b358b73b1d196a9f26999405 Mon Sep 17 00:00:00 2001 From: Nicholas Masel Date: Mon, 30 Dec 2024 16:37:01 +0000 Subject: [PATCH 5/8] closes #70 --- DESCRIPTION | 3 +- NEWS.md | 3 +- R/autos.R | 51 ++++++++++++++++--- man/build_from_config.Rd | 2 +- .../testthat/man/testdir/DEV/functions/inc1.R | 3 ++ .../testthat/man/testdir/DEV/functions/inc2.R | 3 ++ .../testthat/man/testdir/DEV/functions/inc3.R | 3 ++ .../testthat/man/testdir/QA/functions/inc1.R | 2 + .../testthat/man/testdir/QA/functions/inc2.R | 3 ++ .../testthat/man/testdir/QA/functions/inc3.R | 3 ++ tests/testthat/test-autos.R | 28 ++++++++++ 11 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 tests/testthat/man/testdir/DEV/functions/inc1.R create mode 100644 tests/testthat/man/testdir/DEV/functions/inc2.R create mode 100644 tests/testthat/man/testdir/DEV/functions/inc3.R create mode 100644 tests/testthat/man/testdir/QA/functions/inc1.R create mode 100644 tests/testthat/man/testdir/QA/functions/inc2.R create mode 100644 tests/testthat/man/testdir/QA/functions/inc3.R diff --git a/DESCRIPTION b/DESCRIPTION index ac3bde6..e6dfa5a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,7 +23,8 @@ Imports: fs, purrr, rlang, - usethis + usethis, + roxygen2 Suggests: rmarkdown, testthat, diff --git a/NEWS.md b/NEWS.md index fc32219..23caa15 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ # envsetup 0.2.1 -- `set_autos()` will how handle NULL hierarchical paths (#66) +- `set_autos()` will now handle NULL hierarchical paths (#66) +- `set_autos()` will account for using `@include` to define function dependencies (#70) # envsetup 0.2.0 diff --git a/R/autos.R b/R/autos.R index 384abed..bf56602 100644 --- a/R/autos.R +++ b/R/autos.R @@ -90,6 +90,30 @@ set_autos <- function(autos, envsetup_environ = Sys.getenv("ENVSETUP_ENVIRON")) ) } +#' Source order of functions +#' +#' This function is used to define the sorting order of functions if +#' `@include` is used to define function dependencies. +#' +#' @param path Directory path +#' @noRd +collate_func <- function(path){ + r_scripts <- list.files(path, + pattern = ".r$", + ignore.case = TRUE, + full.names = TRUE + ) + + collated_func <- roxygen2:::generate_collate(path) + + if (is.null(collated_func)) { + r_scripts + } else { + sapply(1:length(collated_func), function(x) file.path(path, collated_func[[x]])) + } + +} + #' Attach a function directory #' @@ -117,15 +141,26 @@ attach_auto <- function(path, name) { message("Attaching functions from ", path, " to ", name_with_prefix) } else { - # Find all the R files in the given path - r_scripts <- list.files(path, - pattern = ".r$", - ignore.case = TRUE, - full.names = TRUE - ) + # # Find all the R files in the given path + # r_scripts <- list.files(path, + # pattern = ".r$", + # ignore.case = TRUE, + # full.names = TRUE + # ) + # + # # check if functions used @include to define function dependencies + # # if so, collate functions prior to sourcing + # collated_func <- roxygen2:::generate_collate(path) + # + # if (is.null(collated_func)) { + # collated_r_scripts <- r_scripts + # } else { + # collated_r_scripts <- sapply(1:length(collated_func), function(x) file.path(path, collated_func[[x]])) + # } + collated_r_scripts <- collate_func(path) - if (!identical(r_scripts, character(0))) { - walk(r_scripts, + if (!identical(collated_r_scripts, character(0))) { + walk(collated_r_scripts, sys.source, envir = attach(NULL, name = name_with_prefix) ) diff --git a/man/build_from_config.Rd b/man/build_from_config.Rd index 798d83e..8dd39ca 100644 --- a/man/build_from_config.Rd +++ b/man/build_from_config.Rd @@ -7,7 +7,7 @@ build_from_config(config, root = NULL) } \arguments{ -\item{config}{configuration object from config::get() containing paths#'} +\item{config}{configuration object from config::get() containing paths} \item{root}{root directory to build from. Leave as NULL if using absolute paths. Set to working directory if using relative paths.} diff --git a/tests/testthat/man/testdir/DEV/functions/inc1.R b/tests/testthat/man/testdir/DEV/functions/inc1.R new file mode 100644 index 0000000..25714da --- /dev/null +++ b/tests/testthat/man/testdir/DEV/functions/inc1.R @@ -0,0 +1,3 @@ +#' @include inc2.R inc3.R +inc1 <- function(){ +} diff --git a/tests/testthat/man/testdir/DEV/functions/inc2.R b/tests/testthat/man/testdir/DEV/functions/inc2.R new file mode 100644 index 0000000..8eceb1b --- /dev/null +++ b/tests/testthat/man/testdir/DEV/functions/inc2.R @@ -0,0 +1,3 @@ +inc2 <- function(){ + print("inc2") +} diff --git a/tests/testthat/man/testdir/DEV/functions/inc3.R b/tests/testthat/man/testdir/DEV/functions/inc3.R new file mode 100644 index 0000000..7acd3fa --- /dev/null +++ b/tests/testthat/man/testdir/DEV/functions/inc3.R @@ -0,0 +1,3 @@ +inc3 <- function(){ + print("inc3") +} diff --git a/tests/testthat/man/testdir/QA/functions/inc1.R b/tests/testthat/man/testdir/QA/functions/inc1.R new file mode 100644 index 0000000..69d9d41 --- /dev/null +++ b/tests/testthat/man/testdir/QA/functions/inc1.R @@ -0,0 +1,2 @@ +inc1 <- function(){ +} diff --git a/tests/testthat/man/testdir/QA/functions/inc2.R b/tests/testthat/man/testdir/QA/functions/inc2.R new file mode 100644 index 0000000..8eceb1b --- /dev/null +++ b/tests/testthat/man/testdir/QA/functions/inc2.R @@ -0,0 +1,3 @@ +inc2 <- function(){ + print("inc2") +} diff --git a/tests/testthat/man/testdir/QA/functions/inc3.R b/tests/testthat/man/testdir/QA/functions/inc3.R new file mode 100644 index 0000000..7acd3fa --- /dev/null +++ b/tests/testthat/man/testdir/QA/functions/inc3.R @@ -0,0 +1,3 @@ +inc3 <- function(){ + print("inc3") +} diff --git a/tests/testthat/test-autos.R b/tests/testthat/test-autos.R index 5196fc1..7597ad2 100644 --- a/tests/testthat/test-autos.R +++ b/tests/testthat/test-autos.R @@ -25,6 +25,34 @@ test_that("Autos set and test_dev from highest level appears correctly", { expect_equal(c(test_global()), c("Test of global autos")) }) + +#' @editor Nick Masel +#' @editDate 2024-12-30 +test_that("Order of functions appears correctly when @include is used", { + dev_order <- collate_func(custom_name$autos$projects$DEV) + expect_equal(dev_order, + c(file.path(tmpdir, "DEV/functions/TestDev.R"), + file.path(tmpdir, "DEV/functions/inc3.R"), + file.path(tmpdir, "DEV/functions/inc2.R"), + file.path(tmpdir, "DEV/functions/inc1.R") + ) + ) +}) + + +#' @editor Nick Masel +#' @editDate 2024-12-30 +test_that("Order of functions appears correctly when @include is not used", { + qa_order <- collate_func(custom_name$autos$projects$QA) + expect_equal(qa_order, + c(file.path(tmpdir, "QA/functions/QATest.R"), + file.path(tmpdir, "QA/functions/inc1.R"), + file.path(tmpdir, "QA/functions/inc2.R"), + file.path(tmpdir, "QA/functions/inc3.R") + ) + ) +}) + #' @editor Gabe Becker #' @editDate 2023-11-22 test_that("library returns invisibly", { From 79dd212f289ddfb71df4f0623e04c454652e6c08 Mon Sep 17 00:00:00 2001 From: Nicholas Masel Date: Mon, 30 Dec 2024 20:00:56 +0000 Subject: [PATCH 6/8] cleaned up --- R/autos.R | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/R/autos.R b/R/autos.R index bf56602..286b79b 100644 --- a/R/autos.R +++ b/R/autos.R @@ -141,22 +141,6 @@ attach_auto <- function(path, name) { message("Attaching functions from ", path, " to ", name_with_prefix) } else { - # # Find all the R files in the given path - # r_scripts <- list.files(path, - # pattern = ".r$", - # ignore.case = TRUE, - # full.names = TRUE - # ) - # - # # check if functions used @include to define function dependencies - # # if so, collate functions prior to sourcing - # collated_func <- roxygen2:::generate_collate(path) - # - # if (is.null(collated_func)) { - # collated_r_scripts <- r_scripts - # } else { - # collated_r_scripts <- sapply(1:length(collated_func), function(x) file.path(path, collated_func[[x]])) - # } collated_r_scripts <- collate_func(path) if (!identical(collated_r_scripts, character(0))) { From 4b9f580d6925c040e1d928d2f3b5747b16f956fd Mon Sep 17 00:00:00 2001 From: Nicholas Masel <61123199+nicholas-masel@users.noreply.github.com> Date: Fri, 2 May 2025 08:20:23 -0400 Subject: [PATCH 7/8] add vignette (#76) --- vignettes/tips.Rmd | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 vignettes/tips.Rmd diff --git a/vignettes/tips.Rmd b/vignettes/tips.Rmd new file mode 100644 index 0000000..a7e6299 --- /dev/null +++ b/vignettes/tips.Rmd @@ -0,0 +1,90 @@ +--- +title: "Tips" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Tips} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +# 1: Safely set autos + +If you would like to account for potential syntax errors when sourcing in your `autos`, you can wrap `rprofile()` in `purrr::safely()`. This function will attempt to set the autos and return a list containing the result and any error that occurred. + +Let's show an example. First we'll make an example configuration file that will automatically source your autos. We'll intentionally add a syntax error to show how `safely()` works. + +Here is our configuration file, which will automatically source the autos from the `DEV` and `PROD` directories: + +```{r eval = FALSE} +default: + autos: + projects: !expr list( + "DEV" = file.path("demo", "DEV", "username", "project1", "functions"), + "PROD" = file.path("demo", "PROD", "project1", "functions") + ) +``` + +We will do a little work here to create the directory, place a script into the directory. We'll add a syntax error by leaving off a closing `}` in `test_error.R` script in the PROD folder. + + +```{r} +# create the temp directory +dir <- fs::file_temp() +dir.create(dir) +dir.create(file.path(dir, "/demo/PROD/project1/functions"), recursive = TRUE) + +# write a function to the folder with an error +file_conn <- file(file.path(dir, "/demo/PROD/project1/functions/test_error.R")) +writeLines( +"test <- function(){print('test')", file_conn) +close(file_conn) + +# write the config +config_path <- file.path(dir, "_envsetup.yml") +file_conn <- file(config_path) +writeLines( + paste0( +"default: + autos: + PROD: '", dir,"/demo/PROD/project1/functions'" + ), file_conn) +close(file_conn) +``` + +So if we call `rprofile()` passing in this config file, we will get an error because of the syntax error in `test_error.R`: + +```{r error = TRUE} +library(envsetup) + +envsetup_config <- config::get(file = config_path) + +rprofile(envsetup_config) +``` + +To handle this error, we can use `purrr::safely()` to wrap the `rprofile()` function. This will allow us to catch the error and handle it gracefully. + +```{r setup} +safely_rprofile <- purrr::safely(rprofile) + +ret <- safely_rprofile(envsetup_config) +``` + +We still have an error, but safely allow the setup to continue. We can check the result of the `safely_rprofile()` function to see if there was an error, identify the issue and correct the syntax error in the function. + +```{r check} +# check for errors and return if any occurred +if(!is.null(ret$error)) { + print(ret$error) +} +``` + +```{r echo = FALSE} +unlink(dir, recursive=TRUE) +``` From 1d414e8ec41da2983e7e567dcddae73a12893a66 Mon Sep 17 00:00:00 2001 From: Nicholas Masel <61123199+nicholas-masel@users.noreply.github.com> Date: Fri, 2 May 2025 10:56:04 -0400 Subject: [PATCH 8/8] new actions (#77) --- .github/CODEOWNERS | 1 - .github/ISSUE_TEMPLATE/01_bug_report.yml | 35 ------ .github/ISSUE_TEMPLATE/02_feature_request.yml | 43 ------- .github/ISSUE_TEMPLATE/03_docs_update.yml | 30 ----- .github/ISSUE_TEMPLATE/06_general_issue.yml | 27 ----- .github/pull_request_template.md | 17 --- .github/workflows/R-CMD-check.yaml | 59 ++++++++++ .github/workflows/common.yml | 107 ------------------ .github/workflows/pkgdown.yaml | 49 ++++++++ .github/workflows/test-coverage.yaml | 62 ++++++++++ 10 files changed, 170 insertions(+), 260 deletions(-) delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/ISSUE_TEMPLATE/01_bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/02_feature_request.yml delete mode 100644 .github/ISSUE_TEMPLATE/03_docs_update.yml delete mode 100644 .github/ISSUE_TEMPLATE/06_general_issue.yml delete mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/R-CMD-check.yaml delete mode 100644 .github/workflows/common.yml create mode 100644 .github/workflows/pkgdown.yaml create mode 100644 .github/workflows/test-coverage.yaml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index f16b098..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -.github/workflows/* @cicdguy diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml deleted file mode 100644 index 5789012..0000000 --- a/.github/ISSUE_TEMPLATE/01_bug_report.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Bug Report -description: Something is not working correctly or is not working at all! -title: "Bug: " -labels: ["bug", "programming"] -assignees: - - octocat -body: - - type: markdown - attributes: - value: | - **Example:** Bug: rprofile() is returning NA values when using the config argument - - type: textarea - id: what-happened - attributes: - label: What happened? - description: Also tell us what were you expecting to happen before the bug? - placeholder: "A bug happened!" - validations: - required: true - - type: textarea - id: session-info - attributes: - label: Session Information - description: Use `sessionInfo()` in the R console to gather all the details of your environment when the bug happened. - placeholder: "Place the console output here" - validations: - required: false - - type: textarea - id: logs - attributes: - label: Reproducible Example - description: We love code that can reproduce the example. Check out [reprex](https://reprex.tidyverse.org/articles/reprex-dos-and-donts.html) - placeholder: "Please give us as many details as you can! The faster we can recreate the bug, the faster we can get a fix in the works. Warning, Error Messages and Screenshots are also great." - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/02_feature_request.yml b/.github/ISSUE_TEMPLATE/02_feature_request.yml deleted file mode 100644 index 896e4dc..0000000 --- a/.github/ISSUE_TEMPLATE/02_feature_request.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Feature Request -description: Enchancement to admiral functionality -title: "Feature Request: " -labels: ["enhancement", "programming"] -assignees: - - octocat -body: - - type: markdown - attributes: - value: | - Thanks for taking the time to fill out this feature request! We love keeping envsetup fresh! - - type: textarea - id: feature - attributes: - label: Feature Idea - description: Tell us your idea in as few words as possible - placeholder: "`rprofile()` should do x, y and z" - validations: - required: true - - type: textarea - id: input - attributes: - label: Relevant Input - description: Can you provide what the inputs should look like? - placeholder: "What should the input look like? REMINDER: no patient level data or company sensitive information should be shared via this open public issue" - validations: - required: false - - type: textarea - id: output - attributes: - label: Relevant Output - description: Can you provide what the final output should look like? - placeholder: "What should the output look like? REMINDER: no patient level data or company sensitive information should be shared via this open public issue" - validations: - required: false - - type: textarea - id: code - attributes: - label: Reproducible Example/Pseudo Code - description: Can you provide a working example or a sketch of how the code should work? - placeholder: "We love example code and it will speed up the process! REMINDER: no patient level data or company sensitive information should be shared via this open public issue" - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/03_docs_update.yml b/.github/ISSUE_TEMPLATE/03_docs_update.yml deleted file mode 100644 index 6241879..0000000 --- a/.github/ISSUE_TEMPLATE/03_docs_update.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Updates or Enhancements for Documentation -description: Documents out of date? Examples need reworking? Got an idea for a new article? -title: "Documentation: " -labels: ["vignettes", "website", "documentation"] -assignees: - - octocat -body: - - type: markdown - attributes: - value: | - The envsetup team loves documentation! Help us keep it up to date and fresh! - - type: dropdown - id: browsers - attributes: - label: Please select a category the issue is focused on? - multiple: true - options: - - Function Documentation - - User Guides - - Developer Guides - - Other - - I have a new documentation idea! Yay! - - type: textarea - id: docs-out-if-sync - attributes: - label: Let us know where something needs a refresh or put your idea here! - description: Screen shots are super helpful here! You can do a screenshot and cut and paste it here right in here. - placeholder: "Something is out of sync or needs a refresh" - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/06_general_issue.yml b/.github/ISSUE_TEMPLATE/06_general_issue.yml deleted file mode 100644 index ece0b2d..0000000 --- a/.github/ISSUE_TEMPLATE/06_general_issue.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: General Issue -description: Issue that is difficult to fit into bug, feature or documentation issue. -title: "General Issue: " -labels: ["general issue"] -assignees: - - octocat -body: - - type: markdown - attributes: - value: | - **Example:** General Issue: Linked In Blog Post for updates on the latest release? - - type: textarea - id: background - attributes: - label: Background Information - description: Please provide the context and purpose of this piece of work. Links and screenshots are encouraged. - placeholder: "Example: Use changelog/news.md file to gather relevant changes and create into a nice post for Linked In. The more information the better and the faster we can get this issue completed." - validations: - required: true - - type: textarea - id: done - attributes: - label: Definition of Done - description: Please define the deliverable or the desired outcome. - placeholder: "Example: All changes since last release are highlighted in Blog Post and posted to Linked In" - validations: - required: false diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index c911d69..0000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,17 +0,0 @@ -Thank you for your Pull Request! Completing the below tasks helps to ensure our reviewers can maximize their time on your code as well as making sure the codebase remains robust and consistent. - -Please check off each taskbox as an acknowledgment that you completed the task or check off that it is not relevant to your Pull Request. This checklist is part of the Github Action workflows and the Pull Request will not be merged into the `devel` branch until you have checked off each task. - -- [ ] Place Closes # into the beginning of your Pull Request Title (Use Edit button in top-right if you need to update) -- [ ] Code is formatted according to the [tidyverse style guide](https://style.tidyverse.org/). Run `styler::style_file()` to style R and Rmd files -- [ ] Updated relevant unit tests or have written new unit tests -- [ ] Update to all relevant roxygen headers and examples. -- [ ] Run `devtools::document()` so all `.Rd` files in the `man` folder and the `NAMESPACE` file in the project root are updated appropriately -- [ ] Address any updates needed for vignettes and/or templates -- [ ] Update `NEWS.md` if the changes pertain to a user-facing function (i.e. it has an `@export` tag) or documentation aimed at users (rather than developers) -- [ ] Build site `pkgdown::build_site()` and check that all affected examples are displayed correctly and that all new functions occur on the reference page. -- [ ] Address or fix all lintr warnings and errors - `lintr::lint_package()` -- [ ] Run `R CMD check` locally and address all errors and warnings - `devtools::check()` -- [ ] Link the issue so that it closes after successful merging. -- [ ] Address all merge conflicts and resolve appropriately. -- [ ] Pat yourself on the back for a job well done! Much love to your accomplishment! diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml new file mode 100644 index 0000000..e67cd75 --- /dev/null +++ b/.github/workflows/R-CMD-check.yaml @@ -0,0 +1,59 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: + - main + - master + - dev + pull_request: + branches: + - main + - master + - dev + +name: R-CMD-check.yaml + +permissions: read-all + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: windows-latest, r: 'release'} + - {os: macOS-latest, r: 'release'} + - {os: ubuntu-22.04, r: 'release', rspm: "https://packagemanager.posit.co/cran/__linux__/jammy/latest"} + - {os: ubuntu-22.04, r: 'devel', rspm: "https://packagemanager.posit.co/cran/__linux__/jammy/latest"} + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} + - {os: ubuntu-latest, r: 'release'} + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::rcmdcheck + needs: check + + - uses: r-lib/actions/check-r-package@v2 + with: + upload-snapshots: true + build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' \ No newline at end of file diff --git a/.github/workflows/common.yml b/.github/workflows/common.yml deleted file mode 100644 index 334d3f2..0000000 --- a/.github/workflows/common.yml +++ /dev/null @@ -1,107 +0,0 @@ ---- -# Source: https://github.com/pharmaverse/admiralci -# Common workflows designed for Admiral -# but can be easily used by any other R package -name: Admiral Workflows - -on: - # 'workflow_dispatch' gives you the ability - # to run this workflow on demand, anytime - workflow_dispatch: - # 'push' events are triggered when commits - # are pushed to one of these branches - push: - branches: - - main - - devel - - pre-release - - test - # 'pull_request' events are triggered when PRs are - # created against one of these target branches. - pull_request: - branches: - - main - - devel - - pre-release - - test - # 'release' events are triggered when... - # you guessed it - when releases are made. - release: - types: [published] - schedule: - - cron: '21 13 * * 1,3,5' - -env: - # R version to use for the workflows - R_VERSION: "3.6" - -# Docs on concurrency: -# https://docs.github.com/en/actions/using-jobs/using-concurrency -concurrency: - group: admiral-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - style: - name: Code Style - uses: pharmaverse/admiralci/.github/workflows/style.yml@main - if: github.event_name == 'pull_request' - with: - r-version: $R_VERSION - spellcheck: - name: Spelling - uses: pharmaverse/admiralci/.github/workflows/spellcheck.yml@main - if: github.event_name == 'pull_request' - with: - r-version: $R_VERSION - readme: - name: Render README - uses: pharmaverse/admiralci/.github/workflows/readme-render.yml@main - if: github.event_name == 'push' - with: - r-version: $R_VERSION - # This workflow autoformats the README.md file after - # it has been rendered. If you want to skip that, - # set the following value to 'true' - skip-md-formatting: false - check: - name: Check - uses: pharmaverse/admiralci/.github/workflows/r-cmd-check.yml@main - if: github.event_name == 'pull_request' - with: - # Control how you want the errors to manifest - # by supplying the 'error_on' parameter to - # rcmdcheck::rcmdcheck() here. - error-on: error - docs: - name: Documentation - uses: pharmaverse/admiralci/.github/workflows/pkgdown.yml@main - if: github.event_name == 'push' - with: - r-version: $R_VERSION - # Whether to skip multiversion docs - # Note that if you have multiple versions of docs, - # your URL links are likely to break due to path changes - skip-multiversion-docs: false - coverage: - name: Code Coverage - uses: pharmaverse/admiralci/.github/workflows/code-coverage.yml@main - if: > - github.event_name == 'push' || github.event_name == 'pull_request' - with: - r-version: $R_VERSION - # Whether to skip code coverage badge creation - # Setting to 'false' will require you to create - # an orphan branch called 'badges' in your repository - skip-coverage-badges: false - links: - name: Links - uses: pharmaverse/admiralci/.github/workflows/links.yml@main - if: > - github.event_name == 'push' || github.event_name == 'pull_request' - man-pages: - name: Man Pages - uses: pharmaverse/admiralci/.github/workflows/man-pages.yml@main - if: github.event_name == 'pull_request' - with: - r-version: $R_VERSION diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml new file mode 100644 index 0000000..bfc9f4d --- /dev/null +++ b/.github/workflows/pkgdown.yaml @@ -0,0 +1,49 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + release: + types: [published] + workflow_dispatch: + +name: pkgdown.yaml + +permissions: read-all + +jobs: + pkgdown: + runs-on: ubuntu-latest + # Only restrict concurrency for non-PR jobs + concurrency: + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.5.0 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000..5e9a7e5 --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,62 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + +name: test-coverage.yaml + +permissions: read-all + +jobs: + test-coverage: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::covr, any::xml2 + needs: coverage + + - name: Test coverage + run: | + cov <- covr::package_coverage( + quiet = FALSE, + clean = FALSE, + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") + ) + print(cov) + covr::to_cobertura(cov) + shell: Rscript {0} + + - uses: codecov/codecov-action@v4 + with: + # Fail if error if not on PR, or if on PR and token is given + fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }} + file: ./cobertura.xml + plugin: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Show testthat output + if: always() + run: | + ## -------------------------------------------------------------------- + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash + + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package