#' Initialize New Environment
#'
#' Functions to help init new R environment
#'
#' @param chk_pwd Some settings are stored as encrypted objects. Password is required to decrypt and set
#' @param prof_config optional config object (return value of \code{decrypt_profile}) If not provided, \code{decrypt_profile} will be called
#' @param show_file boolean. If true, and \code{interactive() == TRUE} then will use rstudioapi to show .Rprofile once written
#'
#' @importFrom utils install.packages installed.packages
#' @importFrom rstudioapi askForPassword navigateToFile
#' @importFrom sodium data_decrypt sha256 password_verify
#'
#' @name setup_package
NULL
#' @describeIn setup_package Retrieves the internally stored encrypted config list. Requires password used to encrypt object
#' @export
decrypt_profile <- function(chk_pwd = ""){
# read in stored hashed password
hash_path <- system.file("temp", "hash_pwd", package = "ninjar")
hash_pwd <- readRDS(hash_path)
# read in hashed config file
# config_path <- "inst/temp/config_ciph"
config_path <- system.file("temp", "config_ciph", package = "ninjar")
config_ciph <- readRDS(config_path)
#if password provided then check. Error if wrong (if provided, likely not desirable to go into interactive mode)
if(chk_pwd != ""){
if(sodium::password_verify(hash_pwd, chk_pwd)){
prof_config <- unserialize(sodium::data_decrypt(config_ciph, sodium::sha256(charToRaw(chk_pwd))))
}else{
stop("incorrect password provided", call. = FALSE)
}
}
## Ask user for password to verify. if match then decrypt the settings
while(!sodium::password_verify(hash_pwd, chk_pwd)){
chk_pwd <- rstudioapi::askForPassword("Enter password to decrypt")
if(is.null(chk_pwd))
stop("No password given. Canceled decryption", call. = FALSE)
prof_config <- try(
unserialize(sodium::data_decrypt(config_ciph, sodium::sha256(charToRaw(chk_pwd)))),
silent = TRUE
)
}
if(class(prof_config) == "try-error")
stop("Unable able to decrypt", call. = FALSE)
return(prof_config)
}
#' @describeIn setup_package Takes in the config object (return value of \code{decrypt_config} and updates .Rprofile and settings)
#' @export
set_profile <- function(prof_config = NULL, show_file = TRUE){
if(is.null(prof_config))
prof_config <- decrypt_profile()
# set system env
envs <- prof_config$env_vars
envs$R_PROFILE_USER <- paste0(Sys.getenv("R_USER"), "/.Rprofile")
# install.default cran packages and set default in .Rprofile
cran_pkg <- prof_config$default_cran
cran_inst <- cran_pkg[!cran_pkg %in% row.names(utils::installed.packages())]
bool <- FALSE
if(length(cran_inst) > 0){
bool <- sapply(cran_inst, function(pk){
tryCatch({
utils::install.packages(pk) #Ncpus = parallel::detectCores())
return(TRUE)
}, error=function(c){
return(FALSE)
})
})
}
packages <- unique(c(
cran_pkg[!cran_pkg %in% names(bool)],
cran_inst[bool],
getOption("defaultPackages")
))
# form deparsed code to write into .Rprofile. Also, need to set .Rprofile now so on restart it runs the rest
txt <- c(
deparse(call("options", defaultPackages = packages)), "",
paste0("Sys.setenv(", paste0(names(envs), ' = "', envs, '"'), ")")
)
Sys.setenv(R_PROFILE_USER = envs$R_PROFILE_USER)
writeLines(txt, envs$R_PROFILE_USER)
#if interactive AND show_file then use rstudioapi to focus file
if(interactive() & show_file)
rstudioapi::navigateToFile(envs$R_PROFILE_USER)
return(TRUE)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.