From 2bdfdae761ea245b55b03252970b06d95a7238d5 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Tue, 14 Feb 2023 14:06:42 -0600 Subject: [PATCH 01/12] add rds saving option --- R/log.R | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/R/log.R b/R/log.R index 7e10223..2c6fb58 100644 --- a/R/log.R +++ b/R/log.R @@ -284,9 +284,16 @@ log_write <- function(file = NA, write_log_element("log_name", "Log name: "), write_log_element("log_path", "Log path: ")) - writeLines(cleaned_log_vec, - con = file.path(get_log_element("log_path"), - get_log_element("log_name"))) + if (tools::file_ext(get_log_element("log_name")) %in% c("log", "txt")){ + writeLines(cleaned_log_vec, + con = file.path(get_log_element("log_path"), + get_log_element("log_name"))) + } else if ( tolower(tools::file_ext(get_log_element("log_name"))) == "rds") { + saveRDS(cleaned_log_vec, + file = file.path(get_log_element("log_path"), + get_log_element("log_name"))) + } + if (remove_log_object) { log_remove() } From 055c7413b04cf4b4f33dda0649e11d32dfe453b2 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Tue, 14 Feb 2023 16:37:42 -0600 Subject: [PATCH 02/12] add arg to include nested Rds export --- R/log.R | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/R/log.R b/R/log.R index 2c6fb58..5e0b194 100644 --- a/R/log.R +++ b/R/log.R @@ -177,6 +177,7 @@ log_cleanup <- function() { #' log_write(file) log_write <- function(file = NA, remove_log_object = TRUE, + include_rds = TRUE, to_report = c("messages", "output", "result")){ # Set end time and run time set_log_element("end_time", strftime(Sys.time(), usetz = TRUE)) @@ -284,14 +285,22 @@ log_write <- function(file = NA, write_log_element("log_name", "Log name: "), write_log_element("log_path", "Log path: ")) - if (tools::file_ext(get_log_element("log_name")) %in% c("log", "txt")){ - writeLines(cleaned_log_vec, + writeLines(cleaned_log_vec, con = file.path(get_log_element("log_path"), get_log_element("log_name"))) - } else if ( tolower(tools::file_ext(get_log_element("log_name"))) == "rds") { - saveRDS(cleaned_log_vec, - file = file.path(get_log_element("log_path"), - get_log_element("log_name"))) + if (include_rds) { + cleaned_log_list <- lapply( + getOption('log.rx'), + function(i) i + ) + saveRDS(cleaned_log_list, + file = file.path( + get_log_element("log_path"), + paste0(tools::file_path_sans_ext( + get_log_element("log_name") + ),".Rds") + ) + ) } if (remove_log_object) { From 29867bb7cd3446e04510ad9087522421ad1ec80a Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Tue, 14 Feb 2023 16:46:38 -0600 Subject: [PATCH 03/12] update session_info element in log_list to original output --- R/log.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/log.R b/R/log.R index 5e0b194..44f60e9 100644 --- a/R/log.R +++ b/R/log.R @@ -293,6 +293,7 @@ log_write <- function(file = NA, getOption('log.rx'), function(i) i ) + cleaned_log_list$session_info <- session_info(info = "all") saveRDS(cleaned_log_list, file = file.path( get_log_element("log_path"), From fe6c61cd857610d1ed8286d88f7873a1dc2c691b Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Tue, 14 Feb 2023 16:55:18 -0600 Subject: [PATCH 04/12] fix roxygen and update documentation --- R/log.R | 3 ++- man/log_write.Rd | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/R/log.R b/R/log.R index 44f60e9..4d80fd2 100644 --- a/R/log.R +++ b/R/log.R @@ -150,6 +150,7 @@ log_cleanup <- function() { #' to a log file #' #' @param file String. Path to file executed +#' @param include_rds Boolean. Option to export log object as Rds file #' @param remove_log_object Boolean. Should the log object be removed after #' writing the log file? Defaults to TRUE #' @param to_report String vector. Objects to optionally report; additional @@ -177,7 +178,7 @@ log_cleanup <- function() { #' log_write(file) log_write <- function(file = NA, remove_log_object = TRUE, - include_rds = TRUE, + include_rds = FALSE, to_report = c("messages", "output", "result")){ # Set end time and run time set_log_element("end_time", strftime(Sys.time(), usetz = TRUE)) diff --git a/man/log_write.Rd b/man/log_write.Rd index d269420..b535c8f 100644 --- a/man/log_write.Rd +++ b/man/log_write.Rd @@ -7,6 +7,7 @@ log_write( file = NA, remove_log_object = TRUE, + include_rds = FALSE, to_report = c("messages", "output", "result") ) } @@ -16,6 +17,8 @@ log_write( \item{remove_log_object}{Boolean. Should the log object be removed after writing the log file? Defaults to TRUE} +\item{include_rds}{Boolean. Option to export log object as Rds file} + \item{to_report}{String vector. Objects to optionally report; additional information in \code{\link{axecute}}} } From 8ac8cb4044a055f0721e6a1ec73731dbebc7d419 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:41:29 -0600 Subject: [PATCH 05/12] filter rds fields based on log_cleanup() and to_report --- R/log.R | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/R/log.R b/R/log.R index 4d80fd2..3b6b7f1 100644 --- a/R/log.R +++ b/R/log.R @@ -289,10 +289,25 @@ log_write <- function(file = NA, writeLines(cleaned_log_vec, con = file.path(get_log_element("log_path"), get_log_element("log_name"))) - if (include_rds) { - cleaned_log_list <- lapply( - getOption('log.rx'), - function(i) i + if (include_rds){ + rds_fields <- c( + "end_time", "start_time", "run_time", "user", "hash_sum", + "log_path", "log_name", "file_path", "file_name", + "unapproved_packages_functions", "errors", "warnings" + ) + log_options <- as.list(getOption('log.rx')) + cleaned_log_list <- Map( + function(i, x){ + if(x %in% c("messages", "output", "result")){ + if(x %in% to_report){ + return(i) + } + } else if(x %in% c(names(log_cleanup()), rds_fields)){ + return(i) + } + }, + log_options, + names(log_options) ) cleaned_log_list$session_info <- session_info(info = "all") saveRDS(cleaned_log_list, From 8f7f9bc40ce6ca1380e83a3b8642e76f8df52e9e Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Wed, 15 Feb 2023 12:34:44 -0600 Subject: [PATCH 06/12] add unit test for include_rds --- tests/testthat/test-axecute.R | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/testthat/test-axecute.R b/tests/testthat/test-axecute.R index 8f2dca2..60a6016 100644 --- a/tests/testthat/test-axecute.R +++ b/tests/testthat/test-axecute.R @@ -66,3 +66,35 @@ test_that("to_report works to control log output elements", { rm(flines, con, scriptPath, logDir) log_remove() }) + +test_that("include_rds works to output log as rds", { + options("log.rx" = NULL) + scriptPath <- tempfile() + logDir <- tempdir() + writeLines( + c("message('hello logrx')", + "cat('this is output')", + "data.frame(c(8, 6, 7, 5, 3, 0, 9))"), + con = scriptPath) + + # check no log is currently written out + expect_warning(expect_error(file(file.path(logDir, "log_out_nested"), "r"), "cannot open the connection")) + + axecute(scriptPath, + log_name = "log_out_nested", + log_path = logDir, + remove_log_object = FALSE, + include_rds = TRUE, + to_report = c("messages", "result")) + con <- file(file.path(logDir, "log_out_nested.Rds"), "r") + logRDS <- readRDS(file.path(logDir, "log_out_nested.Rds")) + + expect_type(logRDS, "list") + expect_true("messages" %in% names(logRDS)) + expect_true(all(is.na(logRDS$output))) + expect_true("result" %in% names(logRDS)) + expect_true("start_time" %in% names(logRDS)) + + rm(con, scriptPath, logDir, logRDS) + log_remove() +}) From 2bf9ed8fdf6a459594938d960b678a29afc6548b Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Wed, 15 Feb 2023 12:42:56 -0600 Subject: [PATCH 07/12] add include_rds arg to axecute and update doc --- R/axecute.R | 8 +++++++- R/log.R | 3 ++- man/axecute.Rd | 4 ++++ man/log_write.Rd | 3 ++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/R/axecute.R b/R/axecute.R index 7af7930..9b52e75 100644 --- a/R/axecute.R +++ b/R/axecute.R @@ -10,6 +10,8 @@ #' @param log_path String. Path to log file #' @param remove_log_object Boolean. Should the log object be removed after #' writing the log file? Defaults to TRUE +#' @param include_rds Boolean. Option to export log object as Rds file. +#' Defaults to FALSE #' @param quit_on_error Boolean. Should the session quit with status 1 on error? #' Defaults to TRUE #' @param to_report String vector. Objects to optionally report, may include as @@ -34,6 +36,7 @@ axecute <- function(file, log_name = NA, log_path = NA, remove_log_object = TRUE, + include_rds = FALSE, quit_on_error = TRUE, to_report = c("messages", "output", "result")){ @@ -51,7 +54,10 @@ axecute <- function(file, log_name = NA, any_errors <- get_log_element("errors") # write log - log_write(file = file, remove_log_object = remove_log_object, to_report = to_report) + log_write(file = file, + remove_log_object = remove_log_object, + include_rds = include_rds, + to_report = to_report) # if error, quit with status = 1 if not interactive if(!interactive() & !is.null(any_errors) & quit_on_error) { diff --git a/R/log.R b/R/log.R index 3b6b7f1..25bf1d5 100644 --- a/R/log.R +++ b/R/log.R @@ -150,7 +150,8 @@ log_cleanup <- function() { #' to a log file #' #' @param file String. Path to file executed -#' @param include_rds Boolean. Option to export log object as Rds file +#' @param include_rds Boolean. Option to export log object as Rds file. +#' Defaults to TRUE #' @param remove_log_object Boolean. Should the log object be removed after #' writing the log file? Defaults to TRUE #' @param to_report String vector. Objects to optionally report; additional diff --git a/man/axecute.Rd b/man/axecute.Rd index 89e8e67..9784fd5 100644 --- a/man/axecute.Rd +++ b/man/axecute.Rd @@ -9,6 +9,7 @@ axecute( log_name = NA, log_path = NA, remove_log_object = TRUE, + include_rds = FALSE, quit_on_error = TRUE, to_report = c("messages", "output", "result") ) @@ -23,6 +24,9 @@ axecute( \item{remove_log_object}{Boolean. Should the log object be removed after writing the log file? Defaults to TRUE} +\item{include_rds}{Boolean. Option to export log object as Rds file. +Defaults to FALSE} + \item{quit_on_error}{Boolean. Should the session quit with status 1 on error? Defaults to TRUE} diff --git a/man/log_write.Rd b/man/log_write.Rd index b535c8f..db67039 100644 --- a/man/log_write.Rd +++ b/man/log_write.Rd @@ -17,7 +17,8 @@ log_write( \item{remove_log_object}{Boolean. Should the log object be removed after writing the log file? Defaults to TRUE} -\item{include_rds}{Boolean. Option to export log object as Rds file} +\item{include_rds}{Boolean. Option to export log object as Rds file. +Defaults to TRUE} \item{to_report}{String vector. Objects to optionally report; additional information in \code{\link{axecute}}} From 317f9ce347c5590707e746e45f4e2efe88901879 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Wed, 15 Feb 2023 12:58:28 -0600 Subject: [PATCH 08/12] update newsmd --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index 46a8d26..c116ddf 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# logrx 0.2.2 + +- Add `include_rds` argument to `axecute()` to export log as rds file + # logrx 0.2.1 - non-function objects are no longer returned as functions by `get_used_functions` (#154) From 5fa319fc8575d115d2bb8df9b52cf381099709d9 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Tue, 21 Feb 2023 15:48:28 -0600 Subject: [PATCH 09/12] update include_rds roxygen2 default --- R/log.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/log.R b/R/log.R index 25bf1d5..89b5d84 100644 --- a/R/log.R +++ b/R/log.R @@ -151,7 +151,7 @@ log_cleanup <- function() { #' #' @param file String. Path to file executed #' @param include_rds Boolean. Option to export log object as Rds file. -#' Defaults to TRUE +#' Defaults to FALSE #' @param remove_log_object Boolean. Should the log object be removed after #' writing the log file? Defaults to TRUE #' @param to_report String vector. Objects to optionally report; additional From 80152b4806bef80e380ca0d67b408c2758fff372 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Tue, 21 Feb 2023 15:59:56 -0600 Subject: [PATCH 10/12] use purrr::map2 instead of Map --- R/log.R | 8 ++++---- man/log_write.Rd | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/R/log.R b/R/log.R index 89b5d84..863d500 100644 --- a/R/log.R +++ b/R/log.R @@ -297,7 +297,9 @@ log_write <- function(file = NA, "unapproved_packages_functions", "errors", "warnings" ) log_options <- as.list(getOption('log.rx')) - cleaned_log_list <- Map( + cleaned_log_list <- purrr::map2( + log_options, + names(log_options), function(i, x){ if(x %in% c("messages", "output", "result")){ if(x %in% to_report){ @@ -306,9 +308,7 @@ log_write <- function(file = NA, } else if(x %in% c(names(log_cleanup()), rds_fields)){ return(i) } - }, - log_options, - names(log_options) + } ) cleaned_log_list$session_info <- session_info(info = "all") saveRDS(cleaned_log_list, diff --git a/man/log_write.Rd b/man/log_write.Rd index db67039..aa4f657 100644 --- a/man/log_write.Rd +++ b/man/log_write.Rd @@ -18,7 +18,7 @@ log_write( writing the log file? Defaults to TRUE} \item{include_rds}{Boolean. Option to export log object as Rds file. -Defaults to TRUE} +Defaults to FALSE} \item{to_report}{String vector. Objects to optionally report; additional information in \code{\link{axecute}}} From 8dccc88caee2bb2f943dfaf19d04f44c346c05f3 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Mon, 27 Feb 2023 14:56:25 -0600 Subject: [PATCH 11/12] Move the capture output to the write function --- R/get.R | 2 +- R/log.R | 4 ++-- R/writer.R | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/R/get.R b/R/get.R index 9870557..728fc52 100644 --- a/R/get.R +++ b/R/get.R @@ -96,7 +96,7 @@ get_file_path <- function(file = NA, normalize = TRUE){ #' @noRd #' get_session_info <- function(){ - return(capture.output(session_info(info = "all"))) + return(session_info(info = "all")) } diff --git a/R/log.R b/R/log.R index 863d500..ff80c3f 100644 --- a/R/log.R +++ b/R/log.R @@ -294,7 +294,8 @@ log_write <- function(file = NA, rds_fields <- c( "end_time", "start_time", "run_time", "user", "hash_sum", "log_path", "log_name", "file_path", "file_name", - "unapproved_packages_functions", "errors", "warnings" + "unapproved_packages_functions", "errors", "warnings", + "session_info" ) log_options <- as.list(getOption('log.rx')) cleaned_log_list <- purrr::map2( @@ -310,7 +311,6 @@ log_write <- function(file = NA, } } ) - cleaned_log_list$session_info <- session_info(info = "all") saveRDS(cleaned_log_list, file = file.path( get_log_element("log_path"), diff --git a/R/writer.R b/R/writer.R index f10ac82..b114546 100644 --- a/R/writer.R +++ b/R/writer.R @@ -50,6 +50,7 @@ write_metadata <- function(){ #' write_session_info <- function(){ session_info <- get_log_element("session_info") %>% + capture.output() %>% # remove extra dashes on title lines map_chr(~ ifelse(nchar(.x) > 80 & grepl("\u2500\u2500\u2500\u2500", .x), substring(.x, 1, 80), From 03a516218fefe72564aa4a658db9695e5d7cdf07 Mon Sep 17 00:00:00 2001 From: Sam Parmar <107635309+parmsam-pfizer@users.noreply.github.com> Date: Mon, 27 Feb 2023 14:58:12 -0600 Subject: [PATCH 12/12] update session info capture test to capture.output of session info obj --- tests/testthat/test-get.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-get.R b/tests/testthat/test-get.R index b477174..ac09c5f 100644 --- a/tests/testthat/test-get.R +++ b/tests/testthat/test-get.R @@ -22,7 +22,7 @@ test_that("when given a file as an argument a non-normalized file path to that f }) test_that("session info is captured", { - expect_identical(get_session_info(), capture.output(session_info(info = "all"))) + expect_identical(capture.output(get_session_info()), capture.output(session_info(info = "all"))) }) test_that("all functions that are masked are found and returned", {