diff --git a/DESCRIPTION b/DESCRIPTION index 922e722c..59daad12 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: raveio Type: Package Title: File-System Toolbox for RAVE Project -Version: 0.9.0.62 +Version: 0.9.0.63 Language: en-US Authors@R: c( person("Zhengjia", "Wang", email = "dipterix.wang@gmail.com", role = c("aut", "cre", "cph")), diff --git a/NAMESPACE b/NAMESPACE index 671f0496..cc7ba6c8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -152,7 +152,6 @@ export(get_module_description) export(get_modules_registries) export(get_projects) export(get_val2) -export(global_preferences) export(glue) export(h5_names) export(h5_valid) @@ -202,6 +201,8 @@ export(pipeline_eval) export(pipeline_find) export(pipeline_fork) export(pipeline_from_path) +export(pipeline_get_preferences) +export(pipeline_has_preferences) export(pipeline_hasname) export(pipeline_install_github) export(pipeline_install_local) @@ -213,6 +214,7 @@ export(pipeline_root) export(pipeline_run) export(pipeline_run_bare) export(pipeline_save_extdata) +export(pipeline_set_preferences) export(pipeline_settings_get) export(pipeline_settings_set) export(pipeline_setup_rmd) @@ -264,7 +266,6 @@ export(test_hdspeed) export(time_diff2) export(update_local_snippet) export(url_neurosynth) -export(use_global_preferences) export(validate_raw_file) export(validate_subject) export(validate_time_window) diff --git a/R/class-pipeline_tools.R b/R/class-pipeline_tools.R index 6b800a9c..ccd2e06e 100644 --- a/R/class-pipeline_tools.R +++ b/R/class-pipeline_tools.R @@ -37,7 +37,11 @@ PipelineTools <- R6::R6Class( private$.pipeline_path <- pipeline_find(pipeline_name, root_path = pipeline_root(paths, temporary = temporary)) private$.pipeline_name <- attr(private$.pipeline_path, "target_name") private$.settings_file <- settings_file - private$.preferences <- dipsaus::fastmap2() + private$.preferences <- global_preferences( + .prefix_whitelist = c("global", self$pipeline_name), + # TODO: add type-explicit + .type_whitelist = NULL + ) pipeline_settings_path <- file.path( private$.pipeline_path, @@ -496,60 +500,78 @@ PipelineTools <- R6::R6Class( pipe_dir = self$pipeline_path, ...) }, - #' @description load persistent preference settings from the pipeline. + #' @description set persistent preferences from the pipeline. #' The preferences should not affect how pipeline is working, hence usually #' stores minor variables such as graphic options. Changing preferences #' will not invalidate pipeline cache. #' @param name preference name, must contain only letters, digits, #' underscore, and hyphen, will be coerced to lower case (case-insensitive) - #' @param ...,.initial_prefs key-value pairs of initial preference values - #' @param .overwrite whether to overwrite the initial preference values - #' if they exist. - #' @param .verbose whether to verbose the preferences to be saved; default - #' is false; turn on for debug use - #' @returns A persistent map, see \code{\link[dipsaus]{rds_map}} - load_preferences = function(name, ..., .initial_prefs = list(), .overwrite = FALSE, .verbose = FALSE) { - stopifnot2( - grepl(pattern = "^[a-zA-Z0-9_-]+$", - x = name), - msg = "preference `name` must only contain letters (a-z), digits (0-9), underscore (_), and hyphen (-)" - ) - name <- tolower(name) - - pref_path <- file.path(self$preference_path, name) - - if(name %in% names(private$.preferences)) { - preference <- private$.preferences[[name]] - } else { - preference <- dipsaus::rds_map(pref_path) - private$.preferences[[name]] <- preference - } - - # avoid evaluating dots - dot_names <- ...names() - list_names <- names(.initial_prefs) - nms <- c(dot_names, list_names) - nms <- nms[!nms %in% ""] - if(!length(nms)) { return( preference ) } - if(!.overwrite) { - nms <- nms[ !nms %in% preference$keys() ] - if(!length(nms)) { return( preference ) } - } - - if( .verbose ) { - catgl("Initializing the following preference(s): \n{ paste(nms, collapse = '\n') }", level = "DEBUG") - } + #' @param ...,.list key-value pairs of initial preference values. The keys + #' must start with 'global' or the module ID, followed by dot and preference + #' type and names. For example \code{'global.graphics.continuous_palette'} + #' for setting palette colors for continuous heat-map; "global" means the + #' settings should be applied to all 'RAVE' modules. The module-level + #' preference, \code{'power_explorer.export.default_format'} sets the + #' default format for power-explorer export dialogue. + #' @returns A list of key-value pairs + set_preferences = function(..., .list = NULL) { + pipeline_set_preferences(..., .list = .list, + .preference_instance = private$.preferences) + }, - default_vals <- as.list(.initial_prefs[list_names %in% nms]) - nms <- nms[nms %in% dot_names] - if(length(nms)) { - for(nm in nms) { - default_vals[[nm]] <- ...elt(which(dot_names == nm)) - } - } + #' @description get persistent preferences from the pipeline. + #' @param keys characters to get the preferences + #' @param simplify whether to simplify the results when length of key is 1; + #' default is true; set to false to always return a list of preferences + #' @param ifnotfound default value when the key is missing + #' @param validator \code{NULL} or function to validate the values; see + #' 'Examples' + #' @param ... passed to \code{validator} if \code{validator} is a function + #' @returns A list of the preferences. If \code{simplify} is true and length + #' if keys is 1, then returns the value of that preference + #' @examples + #' + #' library(raveio) + #' if(interactive() && length(pipeline_list()) > 0) { + #' pipeline <- pipeline("power_explorer") + #' + #' # set dummy preference + #' pipeline$set_preferences("global.example.dummy_preference" = 1:3) + #' + #' # get preference + #' pipeline$get_preferences("global.example.dummy_preference") + #' + #' # get preference with validator to ensure the value length to be 1 + #' pipeline$get_preferences( + #' "global.example.dummy_preference", + #' validator = function(value) { + #' stopifnot(length(value) == 1) + #' }, + #' ifnotfound = 100 + #' ) + #' + #' pipeline$has_preferences("global.example.dummy_preference") + #' } + #' + get_preferences = function(keys, simplify = TRUE, ifnotfound = NULL, + validator = NULL, ...) { + pipeline_get_preferences( + keys = keys, + simplify = simplify, + ifnotfound = ifnotfound, + validator = validator, + ..., + .preference_instance = private$.preferences + ) + }, - preference$mset(.list = default_vals) - preference + #' @description whether pipeline has preference keys + #' @param keys characters name of the preferences + #' @param ... passed to internal methods + #' @returns logical whether the keys exist + has_preferences = function(keys, ...) { + pipeline_has_preferences(keys = keys, ..., + .preference_instance = private$.preferences) } ), diff --git a/R/pipeline-docs.R b/R/pipeline-docs.R index 55fd677e..b08cfef8 100644 --- a/R/pipeline-docs.R +++ b/R/pipeline-docs.R @@ -4,8 +4,8 @@ #' internal development use. The infrastructure will be deployed to 'RAVE' in #' the future to facilitate the "self-expanding" aim. Please check the official #' 'RAVE' website. -#' @param pipe_dir where the pipeline directory is; can be set via system -#' environment \code{Sys.setenv("RAVE_PIPELINE"=...)} +#' @param pipe_dir,.pipe_dir where the pipeline directory is; can be set via +#' system environment \code{Sys.setenv("RAVE_PIPELINE"=...)} #' @param quick whether to skip finished targets to save time #' @param skip_names hint of target names to fast skip provided they are #' up-to-date; only used when \code{quick=TRUE}. If missing, then @@ -27,6 +27,8 @@ #' @param names the names of pipeline targets that are to be executed; default #' is \code{NULL}, which runs all targets; use \code{pipeline_target_names} #' to check all your available target names. +#' @param keys preference keys +#' @param validator \code{NULL} or function to validate values #' @param return_values whether to return pipeline target values; default is #' true; only works in \code{pipeline_run_bare} and will be ignored by #' \code{pipeline_run} @@ -84,7 +86,8 @@ #' @param error_if_missing,default_if_missing what to do if the extended data #' is not found #' @param data extended data to be saved -#' @param ... other parameters, targets, etc. +#' @param ...,.list other parameters, targets, etc. +#' @param .preference_instance internally used #' @returns \describe{ #' \item{\code{pipeline_root}}{the root directories of the pipelines} #' \item{\code{pipeline_list}}{the available pipeline names under \code{pipeline_root}} diff --git a/R/pipeline-tools.R b/R/pipeline-tools.R index 4efeaf44..dfcbb5df 100644 --- a/R/pipeline-tools.R +++ b/R/pipeline-tools.R @@ -1387,3 +1387,85 @@ pipeline_py_module <- function( py_module } + + +#' @rdname rave-pipeline +#' @export +pipeline_set_preferences <- function( + ..., .list = NULL, + .pipe_dir = Sys.getenv("RAVE_PIPELINE", "."), + .preference_instance = NULL) { + prefs <- c(list(...), .list) + if(!length(prefs)) { return(invisible()) } + # preferences must be `global/module_id`.`type (graphics, ...)`.`key`.dtype + nms <- names(prefs) + if(length(nms) != length(prefs) || any(nms == "")) { + stop("All preferences must be named") + } + + if(missing(.preference_instance) || is.null(.preference_instance)) { + pipe_dir <- activate_pipeline(.pipe_dir) + pipeline_name <- attr(pipe_dir, "target_name") + instance <- global_preferences(.prefix_whitelist = c("global", pipeline_name)) + } else { + instance <- .preference_instance + } + + instance$mset(.list = prefs) + + invisible(prefs) + +} + +#' @rdname rave-pipeline +#' @export +pipeline_get_preferences <- function( + keys, simplify = TRUE, ifnotfound = NULL, validator = NULL, ..., + .preference_instance = NULL) { + + if(missing(.preference_instance) || is.null(.preference_instance)) { + instance <- global_preferences() + } else { + instance <- .preference_instance + } + + + if(is.function(validator)) { + args <- list(...) + force(ifnotfound) + re <- structure( + names = keys, + lapply(keys, function(key) { + if(instance$has(key)) { + value <- instance$get(key, missing_default = ifnotfound) + tryCatch({ + do.call(validator, c(list(value), args)) + return(value) + }, error = function(e) { + ifnotfound + }) + } else { + ifnotfound + } + }) + ) + } else { + re <- instance$mget(keys, missing_default = ifnotfound) + } + if(simplify && length(keys) == 1) { + re <- re[[1]] + } + return(re) +} + +#' @rdname rave-pipeline +#' @export +pipeline_has_preferences <- function(keys, ..., .preference_instance = NULL) { + if(missing(.preference_instance) || is.null(.preference_instance)) { + instance <- global_preferences() + } else { + instance <- .preference_instance + } + instance$has(keys, ...) +} + diff --git a/R/zzz.R b/R/zzz.R index 87d2ef5f..0aeaabc1 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -783,77 +783,26 @@ install_modules <- function(modules, dependencies = FALSE) { } -#' Global preferences for pipelines and modules -#' @description load persistent global preference settings that can be -#' accessed across modules, pipelines, and R sessions. -#' @details -#' The preferences should not affect how pipeline is working, hence usually -#' stores minor variables such as graphic options. Changing preferences -#' will not invalidate pipeline cache. -#' -#' Developers should maintain and check the preferences at their own risks. -#' For example, the preferences may not be available. In case of broken files, -#' please use try-catch clause when trying to access the items. -#' -#' To avoid performance hit, please do not save functions, environments, only -#' save atomic items within \code{1 MB}. Though not implemented at this moment, -#' this restriction will be rigidly enforced in the future. -#' -#' @param name preference name, must contain only letters, digits, -#' underscore, and hyphen, will be coerced to lower case (case-insensitive) -#' @param ...,.initial_prefs key-value pairs of initial preference values -#' @param .overwrite whether to overwrite the initial preference values -#' if they exist. -#' @param .verbose whether to verbose the preferences to be saved; default -#' is false; turn on for debug use -#' @returns A persistent map, see \code{\link[dipsaus]{rds_map}} -#' -#' @examples -#' -#' if( interactive() ) { -#' -#' -#' # high-level method -#' get_my_preference <- use_global_preferences( -#' name = "my_list", -#' item1 = "A" -#' ) -#' get_my_preference("item1", "missing") -#' get_my_preference("item2", "missing") -#' -#' # Low-level implementation -#' preference <- global_preferences( -#' name = "my_list", -#' item1 = "A" -#' ) -#' -#' # get items wrapped in tryCatch -#' get_my_preference <- function(name, default = NULL) { -#' tryCatch({ -#' preference$get(name, missing_default = default) -#' }, error = function(e) { -#' default -#' }) -#' } -#' -#' get_my_preference("item1", "missing") -#' get_my_preference("item2", "missing") -#' -#' } -#' -#' @export -global_preferences = function(name, ..., .initial_prefs = list(), .overwrite = FALSE, .verbose = FALSE) { +global_preferences = function(name = "default", ..., .initial_prefs = list(), + .prefix_whitelist = NULL, .type_whitelist = NULL, + .overwrite = FALSE, .verbose = FALSE) { stopifnot2( grepl(pattern = "^[a-zA-Z0-9_-]+$", x = name), msg = "preference `name` must only contain letters (a-z), digits (0-9), underscore (_), and hyphen (-)" ) - name <- tolower(name) + name <- trimws(tolower(name)) + + if(length(name) != 1 || is.na(name) || !nzchar(name) || grepl("(^\\.|[/\\\\])", name)) { + stop("Invalid preference name [", name, "]. Must be non-hidden file name") + } - pref_path <- file.path(R_user_dir("raveio", which = "config"), "pipeline_global_preferences", name) + pref_path <- file.path(R_user_dir("raveio", which = "config"), "preferences", name) preference <- tryCatch({ - dipsaus::rds_map(pref_path) + preference <- dipsaus::rds_map(pref_path) + stopifnot(preference$is_valid) + preference }, error = function(e) { if(file.exists(pref_path)) { unlink(pref_path, unlink(TRUE)) @@ -861,46 +810,107 @@ global_preferences = function(name, ..., .initial_prefs = list(), .overwrite = F dipsaus::rds_map(pref_path) }) + prefix_whitelist <- unlist(.prefix_whitelist) + type_whitelist <- unlist(.type_whitelist) + + validate_names <- function(nms, expected_length) { + if(length(nms) != expected_length) { + stop("Preference names cannot be blank") + } + if(expected_length == 0) { return() } + if(any(nms == "")) { + stop("Preference names cannot be blank") + } + # nms <- c("global.graphics.cex", "power_explorer.graphics.cex", "global.graphics.use_ggplot", "power_explorer.export.default_format") + + parsed <- t(sapply(nms, function(nm) { + item <- strsplit(nm, ".", fixed = TRUE)[[1]] + if(length(item) < 3) { + stop("Invalid preference name `", nm, "`. \nPreference must have syntax [global/].[type].[key]. \nFor example: `global.graphics.use_ggplot`, `power_explorer.export.default_format`, ...") + } + item <- c(item[c(1, 2)], paste(item[-c(1, 2)], collapse = ".")) + + if(length(prefix_whitelist)) { + if(!item[[1]] %in% prefix_whitelist) { + stop( + "Cannot set preference `", + nm, + "`: invalid prefix. Allowed prefix choices are: ", + paste(sprintf("`%s`", prefix_whitelist), collapse = ", ") + ) + } + } + + if(length(type_whitelist)) { + if(!item[[2]] %in% type_whitelist) { + stop( + "Cannot set preference `", + nm, + "`: invalid type. Allowed type choices are: ", + paste(sprintf("`%s`", type_whitelist), collapse = ", ") + ) + } + } + + item + })) + + } + + re <- list( + get = preference$get, + mget = preference$mget, + + set = function(key, value, signature) { + validate_names(key, 1) + if( missing(signature) ) { + preference$set(key, value) + } else { + preference$set(key, value, signature) + } + }, + mset = function(..., .list = NULL) { + .list <- c(list(...), .list) + nms <- names(.list) + validate_names(nms, length(.list)) + preference$mset(.list = .list) + }, + + keys = preference$keys, + has = preference$has, + + size = preference$size, + remove = preference$remove, + + reset = preference$reset, + destroy = preference$destroy + ) + + # avoid evaluating dots dot_names <- ...names() list_names <- names(.initial_prefs) nms <- c(dot_names, list_names) nms <- nms[!nms %in% ""] - if(!length(nms)) { return( preference ) } - if(!.overwrite) { - nms <- nms[ !nms %in% preference$keys() ] - if(!length(nms)) { return( preference ) } - } + if(length(nms)) { + if( !.overwrite ) { + nms <- nms[ !nms %in% preference$keys() ] + } + if(length(nms)) { + if( .verbose ) { + catgl("Initializing the following preference(s): \n{ paste(nms, collapse = '\n') }", level = "DEBUG") + } - if( .verbose ) { - catgl("Initializing the following preference(s): \n{ paste(nms, collapse = '\n') }", level = "DEBUG") - } + default_vals <- as.list(.initial_prefs[list_names %in% nms]) + nms <- nms[nms %in% dot_names] - default_vals <- as.list(.initial_prefs[list_names %in% nms]) - nms <- nms[nms %in% dot_names] - if(length(nms)) { - for(nm in nms) { - default_vals[[nm]] <- ...elt(which(dot_names == nm)) + for(nm in nms) { + default_vals[[nm]] <- ...elt(which(dot_names == nm)) + } + re$mset(.list = default_vals) } } - preference$mset(.list = default_vals) - preference + re } -#' @rdname global_preferences -#' @export -use_global_preferences <- function(name, ...) { - - preference <- raveio::global_preferences( - name = name, - ... - ) - function(key, default = NULL) { - tryCatch({ - preference$get(key, missing_default = default) - }, error = function(e) { - default - }) - } -} diff --git a/man/PipelineTools.Rd b/man/PipelineTools.Rd index 6bcbe873..e2eef712 100644 --- a/man/PipelineTools.Rd +++ b/man/PipelineTools.Rd @@ -27,12 +27,47 @@ the saved file path the data if file is found or a default value -A persistent map, see \code{\link[dipsaus]{rds_map}} +A list of key-value pairs + +A list of the preferences. If \code{simplify} is true and length +if keys is 1, then returns the value of that preference + +logical whether the keys exist } \description{ Class definition for pipeline tools Class definition for pipeline tools +} +\examples{ + +## ------------------------------------------------ +## Method `PipelineTools$get_preferences` +## ------------------------------------------------ + + +library(raveio) +if(interactive() && length(pipeline_list()) > 0) { + pipeline <- pipeline("power_explorer") + + # set dummy preference + pipeline$set_preferences("global.example.dummy_preference" = 1:3) + + # get preference + pipeline$get_preferences("global.example.dummy_preference") + + # get preference with validator to ensure the value length to be 1 + pipeline$get_preferences( + "global.example.dummy_preference", + validator = function(value) { + stopifnot(length(value) == 1) + }, + ifnotfound = 100 + ) + + pipeline$has_preferences("global.example.dummy_preference") +} + } \seealso{ \code{\link{pipeline}} @@ -77,7 +112,9 @@ signatures of data and commands} \item \href{#method-PipelineTools-clean}{\code{PipelineTools$clean()}} \item \href{#method-PipelineTools-save_data}{\code{PipelineTools$save_data()}} \item \href{#method-PipelineTools-load_data}{\code{PipelineTools$load_data()}} -\item \href{#method-PipelineTools-load_preferences}{\code{PipelineTools$load_preferences()}} +\item \href{#method-PipelineTools-set_preferences}{\code{PipelineTools$set_preferences()}} +\item \href{#method-PipelineTools-get_preferences}{\code{PipelineTools$get_preferences()}} +\item \href{#method-PipelineTools-has_preferences}{\code{PipelineTools$has_preferences()}} \item \href{#method-PipelineTools-clone}{\code{PipelineTools$clone()}} } } @@ -522,36 +559,112 @@ from the file extension} } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-PipelineTools-load_preferences}{}}} -\subsection{Method \code{load_preferences()}}{ -load persistent preference settings from the pipeline. +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-PipelineTools-set_preferences}{}}} +\subsection{Method \code{set_preferences()}}{ +set persistent preferences from the pipeline. The preferences should not affect how pipeline is working, hence usually stores minor variables such as graphic options. Changing preferences will not invalidate pipeline cache. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{PipelineTools$load_preferences( - name, - ..., - .initial_prefs = list(), - .overwrite = FALSE, - .verbose = FALSE -)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{PipelineTools$set_preferences(..., .list = NULL)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ +\item{\code{..., .list}}{key-value pairs of initial preference values. The keys +must start with 'global' or the module ID, followed by dot and preference +type and names. For example \code{'global.graphics.continuous_palette'} +for setting palette colors for continuous heat-map; "global" means the +settings should be applied to all 'RAVE' modules. The module-level +preference, \code{'power_explorer.export.default_format'} sets the +default format for power-explorer export dialogue.} + \item{\code{name}}{preference name, must contain only letters, digits, underscore, and hyphen, will be coerced to lower case (case-insensitive)} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-PipelineTools-get_preferences}{}}} +\subsection{Method \code{get_preferences()}}{ +get persistent preferences from the pipeline. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{PipelineTools$get_preferences( + keys, + simplify = TRUE, + ifnotfound = NULL, + validator = NULL, + ... +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{keys}}{characters to get the preferences} + +\item{\code{simplify}}{whether to simplify the results when length of key is 1; +default is true; set to false to always return a list of preferences} + +\item{\code{ifnotfound}}{default value when the key is missing} + +\item{\code{validator}}{\code{NULL} or function to validate the values; see +'Examples'} + +\item{\code{...}}{passed to \code{validator} if \code{validator} is a function} +} +\if{html}{\out{
}} +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{ +library(raveio) +if(interactive() && length(pipeline_list()) > 0) { + pipeline <- pipeline("power_explorer") + + # set dummy preference + pipeline$set_preferences("global.example.dummy_preference" = 1:3) + + # get preference + pipeline$get_preferences("global.example.dummy_preference") + + # get preference with validator to ensure the value length to be 1 + pipeline$get_preferences( + "global.example.dummy_preference", + validator = function(value) { + stopifnot(length(value) == 1) + }, + ifnotfound = 100 + ) + + pipeline$has_preferences("global.example.dummy_preference") +} -\item{\code{..., .initial_prefs}}{key-value pairs of initial preference values} +} +\if{html}{\out{
}} -\item{\code{.overwrite}}{whether to overwrite the initial preference values -if they exist.} +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-PipelineTools-has_preferences}{}}} +\subsection{Method \code{has_preferences()}}{ +whether pipeline has preference keys +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{PipelineTools$has_preferences(keys, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{keys}}{characters name of the preferences} -\item{\code{.verbose}}{whether to verbose the preferences to be saved; default -is false; turn on for debug use} +\item{\code{...}}{passed to internal methods} } \if{html}{\out{
}} } diff --git a/man/global_preferences.Rd b/man/global_preferences.Rd deleted file mode 100644 index 141d45f5..00000000 --- a/man/global_preferences.Rd +++ /dev/null @@ -1,83 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/zzz.R -\name{global_preferences} -\alias{global_preferences} -\alias{use_global_preferences} -\title{Global preferences for pipelines and modules} -\usage{ -global_preferences( - name, - ..., - .initial_prefs = list(), - .overwrite = FALSE, - .verbose = FALSE -) - -use_global_preferences(name, ...) -} -\arguments{ -\item{name}{preference name, must contain only letters, digits, -underscore, and hyphen, will be coerced to lower case (case-insensitive)} - -\item{..., .initial_prefs}{key-value pairs of initial preference values} - -\item{.overwrite}{whether to overwrite the initial preference values -if they exist.} - -\item{.verbose}{whether to verbose the preferences to be saved; default -is false; turn on for debug use} -} -\value{ -A persistent map, see \code{\link[dipsaus]{rds_map}} -} -\description{ -load persistent global preference settings that can be -accessed across modules, pipelines, and R sessions. -} -\details{ -The preferences should not affect how pipeline is working, hence usually -stores minor variables such as graphic options. Changing preferences -will not invalidate pipeline cache. - -Developers should maintain and check the preferences at their own risks. -For example, the preferences may not be available. In case of broken files, -please use try-catch clause when trying to access the items. - -To avoid performance hit, please do not save functions, environments, only -save atomic items within \code{1 MB}. Though not implemented at this moment, -this restriction will be rigidly enforced in the future. -} -\examples{ - -if( interactive() ) { - - -# high-level method -get_my_preference <- use_global_preferences( - name = "my_list", - item1 = "A" -) -get_my_preference("item1", "missing") -get_my_preference("item2", "missing") - -# Low-level implementation -preference <- global_preferences( - name = "my_list", - item1 = "A" -) - -# get items wrapped in tryCatch -get_my_preference <- function(name, default = NULL) { - tryCatch({ - preference$get(name, missing_default = default) - }, error = function(e) { - default - }) -} - -get_my_preference("item1", "missing") -get_my_preference("item2", "missing") - -} - -} diff --git a/man/rave-pipeline.Rd b/man/rave-pipeline.Rd index 8453870f..fbf61043 100644 --- a/man/rave-pipeline.Rd +++ b/man/rave-pipeline.Rd @@ -29,6 +29,9 @@ \alias{pipeline_load_extdata} \alias{pipeline_save_extdata} \alias{pipeline_shared} +\alias{pipeline_set_preferences} +\alias{pipeline_get_preferences} +\alias{pipeline_has_preferences} \title{'RAVE' pipeline functions} \usage{ pipeline_root(root_path, temporary = FALSE) @@ -188,6 +191,24 @@ pipeline_shared( pipe_dir = Sys.getenv("RAVE_PIPELINE", "."), callr_function = callr::r ) + +pipeline_set_preferences( + ..., + .list = NULL, + .pipe_dir = Sys.getenv("RAVE_PIPELINE", "."), + .preference_instance = NULL +) + +pipeline_get_preferences( + keys, + simplify = TRUE, + ifnotfound = NULL, + validator = NULL, + ..., + .preference_instance = NULL +) + +pipeline_has_preferences(keys, ..., .preference_instance = NULL) } \arguments{ \item{root_path}{the root directory for pipeline templates} @@ -198,8 +219,8 @@ from subject pipeline folders} \item{name, pipeline_name}{the pipeline name to create; usually also the folder} -\item{pipe_dir}{where the pipeline directory is; can be set via system -environment \code{Sys.setenv("RAVE_PIPELINE"=...)}} +\item{pipe_dir, .pipe_dir}{where the pipeline directory is; can be set via +system environment \code{Sys.setenv("RAVE_PIPELINE"=...)}} \item{scheduler}{how to schedule the target jobs: default is \code{'none'}, which is sequential. If you have multiple heavy-weighted jobs that can be @@ -232,7 +253,7 @@ see \code{\link[dipsaus]{progress2}}.} true; only works in \code{pipeline_run_bare} and will be ignored by \code{pipeline_run}} -\item{...}{other parameters, targets, etc.} +\item{..., .list}{other parameters, targets, etc.} \item{destroy}{what part of data repository needs to be cleaned} @@ -311,6 +332,12 @@ choices are \code{'yaml'}, \code{'fst'}, \code{'csv'}, \code{'rds'}} is not found} \item{data}{extended data to be saved} + +\item{.preference_instance}{internally used} + +\item{keys}{preference keys} + +\item{validator}{\code{NULL} or function to validate values} } \value{ \describe{