diff --git a/DESCRIPTION b/DESCRIPTION index e752150..a840713 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,7 +23,6 @@ Imports: haven, httr2, purrr, - qs, readr, readxl, remotes, @@ -32,7 +31,8 @@ Imports: rlang, jsonlite, lifecycle, - stamp (>= 0.0.9) + stamp (>= 0.0.9), + qs2 Suggests: covr, knitr, @@ -49,5 +49,5 @@ URL: https://pip-technical-team.github.io/pipfun, https://pip-technical-team.git VignetteBuilder: knitr Depends: R (>= 3.5) -Remotes: +Remotes: randrescastaneda/stamp diff --git a/R/log_helpers.R b/R/log_helpers.R index 3fc2158..b00040a 100644 --- a/R/log_helpers.R +++ b/R/log_helpers.R @@ -21,15 +21,16 @@ ##' ##' @examples ##' # Inside a function: +##' \dontrun{ ##' my_fun <- function(x, y = 1, ...) { -##' capture_log_args(log_info, environment()) +##' pipfun:::capture_log_args(log_info, environment()) ##' } ##' my_fun(3, z = 9) ##' ##' # Interactive use: ##' a <- 1; b <- 2 -##' capture_log_args(log_info, environment()) -##' +##' pipfun:::capture_log_args(log_info, environment()) +##' } ##' @keywords internal capture_log_args <- function(helper_name, .env) { # Get the parent function and call (one level up from the helper) diff --git a/R/pip_sign_save.R b/R/pip_sign_save.R index 835f65b..06cd69a 100644 --- a/R/pip_sign_save.R +++ b/R/pip_sign_save.R @@ -73,7 +73,7 @@ pip_sign_save <- function(x, } } - qs::qsave( + qs2::qs_save( x = x, file = fs::path(msrdir, measure, ext = "qs") ) @@ -88,9 +88,14 @@ pip_sign_save <- function(x, } } - qs::qsave( + qs2::qsave( x = x, - file = fs::path(msrdir, "_vintage/", paste0(measure, "_", time), ext = "qs") + file = fs::path( + msrdir, + "_vintage/", + paste0(measure, "_", time), + ext = "qs" + ) ) # Write new signature diff --git a/R/utils.R b/R/utils.R index 9082a6d..bc2e40e 100644 --- a/R/utils.R +++ b/R/utils.R @@ -87,7 +87,7 @@ get_latest_ppp_versions <- function(ppps = getOption("pipfun.ppps")) { #' @export #' #' @examples -#' y <- new_secrete("284092sdhfjsld") +#' y <- new_secret("284092sdhfjsld") #' y new_secret <- function(x = double()) { structure(x, class = "secret") @@ -119,8 +119,10 @@ print.secret <- function(x, ...) { ##' @return Invisibly returns the input `pip_boards` object. ##' ##' @examples +##' \dontrun{ ##' boards <- set_pip_boards() ##' print(boards) +##' } ##' ##' @export print.pip_boards <- function(x, ...) { diff --git a/R/working_release.R b/R/working_release.R index fe1b111..1dd4c6e 100644 --- a/R/working_release.R +++ b/R/working_release.R @@ -143,7 +143,8 @@ setup_working_release <- function(release = NULL, aliases <- init_pip_aliases( folder_paths, include_release = alias_include_release, - release = pr[, release] + release = pr[, release], + verbose = verbose ) # ------------------------------------------------------------------ @@ -186,6 +187,7 @@ setup_working_release <- function(release = NULL, #' `NULL`, the latest release is resolved via `get_latest_pip_release()`. #' @param identity character: identity token used as suffix. Default comes #' from `getOption("pipfun.identities")` and is validated with `match.arg()`. +#' @param verbose logical: print progress messages when `TRUE`. #' #' @return A named list of paths (class `pip_folder_paths`) containing #' `stamp_root`, `aux_data`, `aux_metadata`, `dlw_data`, `dlw_inventory`, @@ -193,16 +195,18 @@ setup_working_release <- function(release = NULL, #' `pip_master_inventory`. #' #' @examples -#' +#' #' \dontrun{ #' set_pip_folders(main_dir = "~/pip_data", release = "20251211") #' } #' #' @export -set_pip_folders <- function(main_dir = getOption("pipfun.main_dir"), - release = NULL, - identity = getOption("pipfun.identities")) { - +set_pip_folders <- function( + main_dir = getOption("pipfun.main_dir"), + release = NULL, + identity = getOption("pipfun.identities"), + verbose = getOption("pipfun.verbose") +) { # Validate inputs identity <- match.arg(identity) if (is.null(release)) { @@ -224,27 +228,31 @@ set_pip_folders <- function(main_dir = getOption("pipfun.main_dir"), # DLW (data-lake/work) repository layout # - create top-level DLW directory and subfolders used by pipeline # ------------------------------------------------------------------ - dlw_dir <- fs::path(main_dir, "dlw_repository") |> + dlw_dir <- fs::path(main_dir, "dlw_repository") |> fs::dir_create(recurse = TRUE) - dlw_data_dir <- fs::path(dlw_dir, "dlw_data") |> + dlw_data_dir <- fs::path(dlw_dir, "dlw_data") |> fs::dir_create(recurse = TRUE) dlw_inventory_dir <- fs::path(dlw_dir, "dlw_inventory") |> fs::dir_create(recurse = TRUE) - dlw_metadata_dir <- fs::path(dlw_dir, "dlw_metadata", rt) |> + dlw_metadata_dir <- fs::path(dlw_dir, "dlw_metadata", rt) |> fs::dir_create(recurse = TRUE) # ------------------------------------------------------------------ # PIP repository layout (surveys, metadata, inventories) # ------------------------------------------------------------------ - pip_dir <- fs::path(main_dir, "pip_repository") |> + pip_dir <- fs::path(main_dir, "pip_repository") |> fs::dir_create(recurse = TRUE) - pip_data_dir <- fs::path(pip_dir, "pip_data", "surveys") |> + pip_data_dir <- fs::path(pip_dir, "pip_data", "surveys") |> fs::dir_create(recurse = TRUE) - pip_master_inventory_dir <- fs::path(pip_dir, "pip_data", "master_inventory") |> + pip_master_inventory_dir <- fs::path( + pip_dir, + "pip_data", + "master_inventory" + ) |> fs::dir_create(recurse = TRUE) - pip_metadata_dir <- fs::path(pip_dir, "pip_data", "surveys_metadata", rt) |> + pip_metadata_dir <- fs::path(pip_dir, "pip_data", "surveys_metadata", rt) |> fs::dir_create(recurse = TRUE) - pip_inventory_dir <- fs::path(pip_dir, "pip_inventory", rt) |> + pip_inventory_dir <- fs::path(pip_dir, "pip_inventory", rt) |> fs::dir_create(recurse = TRUE) # The stamp project root is the top-level main_dir; stamp is used to @@ -253,19 +261,19 @@ set_pip_folders <- function(main_dir = getOption("pipfun.main_dir"), # Initialize stamp if needed. This creates `.stamp` under `stamp_root`. if (!fs::dir_exists(fs::path(stamp_root, ".stamp"))) { - stamp::st_init(root = stamp_root) + stamp::st_init(root = stamp_root, verbose = verbose) } # Return named list of canonical repository paths folder_paths <- list( - stamp_root = stamp_root, - aux_data = aux_dir[1], - aux_metadata = aux_dir[2], - dlw_data = dlw_data_dir, + stamp_root = stamp_root, + aux_data = aux_dir[1], + aux_metadata = aux_dir[2], + dlw_data = dlw_data_dir, dlw_inventory = dlw_inventory_dir, - dlw_metadata = dlw_metadata_dir, - pip_data = pip_data_dir, - pip_metadata = pip_metadata_dir, + dlw_metadata = dlw_metadata_dir, + pip_data = pip_data_dir, + pip_metadata = pip_metadata_dir, pip_inventory = pip_inventory_dir, pip_master_inventory = pip_master_inventory_dir ) @@ -339,16 +347,20 @@ get_wrk_release <- function(name = "wrk_release", #' provided, returns the single path (invisibly) for that folder. #' #' @export -get_pip_folders <- function(folder = NULL, - name = "pip_folders", - verbose = FALSE) { - +get_pip_folders <- function( + folder = NULL, + name = "pip_folders", + verbose = getOption("pipfun.verbose") +) { pip_folders <- get_from_pipenv("folder_paths") if (is.null(pip_folders)) { cli::cli_abort( - c(x = "PIP folder paths have not been set up", - i = "You need to set a working release with {.code pipfun::setup_working_release()}")) + c( + x = "PIP folder paths have not been set up", + i = "You need to set a working release with {.code pipfun::setup_working_release()}" + ) + ) } if (verbose) { @@ -357,11 +369,11 @@ get_pip_folders <- function(folder = NULL, } # Assign to calling environment for convenience (so devs can access `pip_folders`) - assign(name, - pip_folders, - envir = parent.frame()) + assign(name, pip_folders, envir = parent.frame()) - if (is.null(folder)) return(invisible(pip_folders)) + if (is.null(folder)) { + return(invisible(pip_folders)) + } if (!(folder %in% names(pip_folders))) { cli::cli_abort("{.field {folder}} is not available in {.field pip_folders}") @@ -390,24 +402,27 @@ get_pip_folders <- function(folder = NULL, #' is provided, returns the single alias string (invisibly). #' #' @examples -#' -#' \\dontrun{ +#' +#' \dontrun{ #' setup_working_release() #' get_pip_aliases() # returns all aliases #' get_pip_aliases("aux_data") # returns alias for aux_data #' } #' #' @export -get_pip_aliases <- function(folder = NULL, - name = "pip_aliases", - verbose = FALSE) { - +get_pip_aliases <- function( + folder = NULL, + name = "pip_aliases", + verbose = getOption("pipfun.verbose") +) { pip_aliases <- get_from_pipenv("pip_aliases") if (is.null(pip_aliases)) { cli::cli_abort( - c(x = "PIP aliases have not been set up", - i = "Run {.code pipfun::setup_working_release()} to register aliases") + c( + x = "PIP aliases have not been set up", + i = "Run {.code pipfun::setup_working_release()} to register aliases" + ) ) } @@ -416,7 +431,9 @@ get_pip_aliases <- function(folder = NULL, print(pip_aliases) } - if (is.null(folder)) return(invisible(pip_aliases)) + if (is.null(folder)) { + return(invisible(pip_aliases)) + } if (!(folder %in% names(pip_aliases))) { cli::cli_abort("{.field {folder}} is not available in {.field pip_aliases}") @@ -443,20 +460,21 @@ get_pip_aliases <- function(folder = NULL, #' The vector's names correspond to the keys of `folder_paths`. #' #' @keywords internal -init_pip_aliases <- function(folder_paths, - verbose = getOption("pipfun.verbose"), - include_release = FALSE, - release = NULL) { - +init_pip_aliases <- function( + folder_paths, + verbose = getOption("pipfun.verbose"), + include_release = FALSE, + release = NULL +) { # Map from folder key -> short base alias alias_map <- c( - aux_data = "aux", - aux_metadata = "aux_meta", - dlw_data = "dlw", + aux_data = "aux", + aux_metadata = "aux_meta", + dlw_data = "dlw", dlw_inventory = "dlw_inv", - dlw_metadata = "dlw_meta", - pip_data = "pip", - pip_metadata = "pip_meta", + dlw_metadata = "dlw_meta", + pip_data = "pip", + pip_metadata = "pip_meta", pip_inventory = "pip_inv", pip_master_inventory = "pip_master" ) @@ -475,25 +493,29 @@ init_pip_aliases <- function(folder_paths, } # Build the final alias names (append release suffix for specific folders) - final_aliases <- vapply(names(alias_map), function(nm) { - base <- alias_map[[nm]] - if (include_release && (nm %in% release_specific)) { - paste0(base, "_", release) - } else { - base - } - }, FUN.VALUE = character(1)) + final_aliases <- vapply( + names(alias_map), + function(nm) { + base <- alias_map[[nm]] + if (include_release && (nm %in% release_specific)) { + paste0(base, "_", release) + } else { + base + } + }, + FUN.VALUE = character(1) + ) # Register aliases with stamp for each folder; stamp will report # conflicts or errors as appropriate. for (nm in names(final_aliases)) { - alias <- final_aliases[[nm]] - root <- fs::path_norm(folder_paths[[nm]]) + root <- fs::path_norm(folder_paths[[nm]]) stamp::st_init( - root = root, - alias = alias + root = root, + alias = alias, + verbose = verbose ) if (verbose) { diff --git a/man/capture_log_args.Rd b/man/capture_log_args.Rd index 5c6f9d6..1d44936 100644 --- a/man/capture_log_args.Rd +++ b/man/capture_log_args.Rd @@ -32,14 +32,15 @@ hidden variables (those starting with a dot). } \examples{ # Inside a function: +\dontrun{ my_fun <- function(x, y = 1, ...) { - capture_log_args(log_info, environment()) + pipfun:::capture_log_args(log_info, environment()) } my_fun(3, z = 9) # Interactive use: a <- 1; b <- 2 -capture_log_args(log_info, environment()) - +pipfun:::capture_log_args(log_info, environment()) +} } \keyword{internal} diff --git a/man/get_pip_aliases.Rd b/man/get_pip_aliases.Rd index 878aee7..56a0e4d 100644 --- a/man/get_pip_aliases.Rd +++ b/man/get_pip_aliases.Rd @@ -4,16 +4,20 @@ \alias{get_pip_aliases} \title{Retrieve stamp aliases registered for PIP folders} \usage{ -get_pip_aliases(name = NULL, verbose = TRUE) +get_pip_aliases( + folder = NULL, + name = "pip_aliases", + verbose = getOption("pipfun.verbose") +) } \arguments{ +\item{folder}{character|null: optional folder name (key of aliases) to return. +If \code{NULL}, returns the full named character vector of aliases.} + \item{name}{character: variable name to assign the aliases to in the calling environment. Defaults to \code{"pip_aliases"}.} \item{verbose}{logical: if \code{TRUE}, prints a summary of aliases retrieved.} - -\item{folder}{character|null: optional folder name (key of aliases) to return. -If \code{NULL}, returns the full named character vector of aliases.} } \value{ Invisibly returns a named character vector of aliases. If \code{folder} @@ -26,7 +30,7 @@ actual folder paths registered with \code{stamp}. } \examples{ -\\dontrun{ +\dontrun{ setup_working_release() get_pip_aliases() # returns all aliases get_pip_aliases("aux_data") # returns alias for aux_data diff --git a/man/get_pip_folders.Rd b/man/get_pip_folders.Rd index 70432d0..65b990d 100644 --- a/man/get_pip_folders.Rd +++ b/man/get_pip_folders.Rd @@ -4,16 +4,20 @@ \alias{get_pip_folders} \title{Retrieve folder paths registered for the active PIP working release} \usage{ -get_pip_folders(name = NULL, verbose = TRUE) +get_pip_folders( + folder = NULL, + name = "pip_folders", + verbose = getOption("pipfun.verbose") +) } \arguments{ +\item{folder}{character|null: optional specific folder name to return +(e.g. \code{"aux_data"}). If \code{NULL} (default) the full named list is returned invisibly.} + \item{name}{character: variable name to assign the full folder list to in the calling environment. Defaults to \code{"pip_folders"}.} \item{verbose}{logical: if \code{TRUE}, prints information about the retrieved paths.} - -\item{folder}{character|null: optional specific folder name to return -(e.g. \code{"aux_data"}). If \code{NULL} (default) the full named list is returned invisibly.} } \value{ Invisibly returns the named list of folder paths. If \code{folder} is diff --git a/man/get_wrk_release.Rd b/man/get_wrk_release.Rd index 6f6da11..0c49295 100644 --- a/man/get_wrk_release.Rd +++ b/man/get_wrk_release.Rd @@ -4,7 +4,7 @@ \alias{get_wrk_release} \title{Retrieve and assign the active working release} \usage{ -get_wrk_release(name = NULL, verbose = TRUE) +get_wrk_release(name = "wrk_release", verbose = getOption("pipfun.verbose")) } \arguments{ \item{name}{character: name to assign the working release object to in diff --git a/man/new_secret.Rd b/man/new_secret.Rd index 1d0110d..84eed06 100644 --- a/man/new_secret.Rd +++ b/man/new_secret.Rd @@ -16,6 +16,6 @@ x with class "secrete" Right from the Advanced R Book } \examples{ -y <- new_secrete("284092sdhfjsld") +y <- new_secret("284092sdhfjsld") y } diff --git a/man/print.pip_boards.Rd b/man/print.pip_boards.Rd index 6e45203..ee05dc3 100644 --- a/man/print.pip_boards.Rd +++ b/man/print.pip_boards.Rd @@ -19,7 +19,9 @@ Displays a summary of PIP pins boards in a beautiful cli output. Shows the common directory path, each board's name, its relative path, and cache size. } \examples{ +\dontrun{ boards <- set_pip_boards() print(boards) +} } diff --git a/man/set_pip_folders.Rd b/man/set_pip_folders.Rd index 40db74b..a341b3a 100644 --- a/man/set_pip_folders.Rd +++ b/man/set_pip_folders.Rd @@ -7,7 +7,8 @@ set_pip_folders( main_dir = getOption("pipfun.main_dir"), release = NULL, - identity = getOption("pipfun.identities") + identity = getOption("pipfun.identities"), + verbose = getOption("pipfun.verbose") ) } \arguments{ @@ -18,6 +19,8 @@ set_pip_folders( \item{identity}{character: identity token used as suffix. Default comes from \code{getOption("pipfun.identities")} and is validated with \code{match.arg()}.} + +\item{verbose}{logical: print progress messages when \code{TRUE}.} } \value{ A named list of paths (class \code{pip_folder_paths}) containing diff --git a/tests/testthat/test-working_release.R b/tests/testthat/test-working_release.R index 51e9e50..f1e5be9 100644 --- a/tests/testthat/test-working_release.R +++ b/tests/testthat/test-working_release.R @@ -11,11 +11,8 @@ create_temp_main_dir <- function() { } clear_pipenv <- function() { - if (exists(".pipenv", envir = globalenv())) { - rm(list = ls(envir = .pipenv), envir = .pipenv) - } else { - return(NULL) - } + env <- get_pipenv() + rm(list = ls(envir = env), envir = env) } restore_pipenv <- function() { @@ -117,7 +114,7 @@ test_that("get_wrk_release errors if working release not set", { expect_error( get_wrk_release(verbose = FALSE), - "Working release" + "Working release has not been set up" ) }) @@ -135,7 +132,7 @@ test_that("get_pip_folders errors if folder_paths not set", { expect_error( get_pip_folders(verbose = FALSE), - "folder paths" + "PIP folder paths have not been set up" ) }) @@ -154,6 +151,6 @@ test_that("get_pip_aliases errors if pip_aliases not set", { expect_error( get_pip_aliases(verbose = FALSE), - "aliases" + "PIP aliases have not been set up" ) }) \ No newline at end of file