From 6539710d8e76964169f0f8c2ad73236de073e49b Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Sun, 20 Oct 2024 13:22:55 -0400 Subject: [PATCH 01/11] add first draft of render_report --- NAMESPACE | 1 + R/reporting.R | 72 +++++++++++++++++++ man/render_report.Rd | 39 ++++++++++ report/output/.gitignore | 4 ++ report/render_report.R | 64 +++++------------ report/sample_report.Rmd | 5 +- report/sample_report.qmd | 1 + study_template/report/quarto_html_example.qmd | 1 + study_template/report/render_report.R | 64 +++++------------ ...{sample_report.Rmd => rmd_pdf_example.Rmd} | 0 10 files changed, 157 insertions(+), 94 deletions(-) create mode 100644 R/reporting.R create mode 100644 man/render_report.Rd create mode 100644 report/output/.gitignore rename study_template/report/{sample_report.Rmd => rmd_pdf_example.Rmd} (100%) diff --git a/NAMESPACE b/NAMESPACE index e3b9518..1736a95 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -44,6 +44,7 @@ export(log_job_failure) export(log_job_success) export(mutate_columns_to_posixct) export(quit_non_interactive_run) +export(render_report) export(scrape_user_api_tokens) export(send_email) export(set_package_scope_var) diff --git a/R/reporting.R b/R/reporting.R new file mode 100644 index 0000000..fd3751c --- /dev/null +++ b/R/reporting.R @@ -0,0 +1,72 @@ +#' Render a Markdown Report from Rmd or Qmd Files +#' +#' This function renders a report from a R Markdown (.Rmd) or Quarto Markdown (.Qmd) script. +#' It is designed to be invoked from `render_report.R`. The rendered report is saved in either PDF or HTML format with a +#' timestamp appended to the filename. +#' +#' @param script_path The full path of the script to render +# +#' @return A list containing details about the operation's outcome: +#' +#' If rendering is successful, the list includes: +#' \itemize{ +#' \item `success`: TRUE +#' \item `report_name`: The name of the report file +#' \item `filepath`: The full path to where the report is saved +#' } +#' If rendering fails, the list includes: +#' \itemize{ +#' \item `success`: FALSE +#' \item `error`: A string describing the error message +#' } +#' +#' @export + +#' @examples +#' \dontrun{ +#' script_path <- here::here("report", "quarto_html_example.qmd") +#' report_metadata <- render_report(script_path) +#' } +#' +#' +render_report <- function(script_path) { + + script_path_without_extension <- tools::file_path_sans_ext(script_path) + base_script_name <- basename(script_path_without_extension) + + result <- tryCatch({ + quarto::quarto_render(script_path) + # Return a success indicator if no error occurs + list(success = TRUE) + }, error = function(e) { + # Return failure and error message + list(success = FALSE, error = e$message) + }) + + if (!result$success) { + return(result) + stop("Report rendering failed: ", result$error) + } + + default_filenames <- paste0(script_path_without_extension, c(".pdf", ".html")) + + for (default_filename in default_filenames) { + if (file.exists(default_filename)) { + file_extension <- tools::file_ext(default_filename) + + report_name <- paste0( + base_script_name, + "_", + format(redcapcustodian::get_script_run_time(), "%Y-%m-%d_%H%M%S"), + ".", + file_extension + ) + + report_filepath <- here::here("report", "output", report_name) + + file.rename(default_filename, report_filepath) + + return(list(success = result$success, report_name = report_name, filepath = report_filepath)) + } + } +} diff --git a/man/render_report.Rd b/man/render_report.Rd new file mode 100644 index 0000000..4a58a77 --- /dev/null +++ b/man/render_report.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reporting.R +\name{render_report} +\alias{render_report} +\title{Render a Markdown Report from Rmd or Qmd Files} +\usage{ +render_report(script_path) +} +\arguments{ +\item{script_path}{The full path of the script to render} +} +\value{ +A list containing details about the operation's outcome: + + If rendering is successful, the list includes: + \itemize{ + \item `success`: TRUE + \item `report_name`: The name of the report file + \item `filepath`: The full path to where the report is saved + } + If rendering fails, the list includes: + \itemize{ + \item `success`: FALSE + \item `error`: A string describing the error message + } +} +\description{ +This function renders a report from a R Markdown (.Rmd) or Quarto Markdown (.Qmd) script. +It is designed to be invoked from `render_report.R`. The rendered report is saved in either PDF or HTML format with a +timestamp appended to the filename. +} +\examples{ +\dontrun{ +script_path <- here::here("report", "quarto_html_example.qmd") +report_metadata <- render_report(script_path) +} + + +} diff --git a/report/output/.gitignore b/report/output/.gitignore new file mode 100644 index 0000000..848bcb4 --- /dev/null +++ b/report/output/.gitignore @@ -0,0 +1,4 @@ +*.csv +*.xlsx +*.html +*.pdf diff --git a/report/render_report.R b/report/render_report.R index e41a08e..c134df1 100644 --- a/report/render_report.R +++ b/report/render_report.R @@ -1,8 +1,5 @@ library(tidyverse) library(dotenv) -library(REDCapR) -library(lubridate) -library(rmarkdown) library(sendmailR) library(redcapcustodian) library(argparse) @@ -10,58 +7,33 @@ library(argparse) init_etl("render_report") parser <- ArgumentParser() -parser$add_argument("script_name", nargs=1, help="Script to be run") +parser$add_argument("script_path", nargs=1, help="The full path of the script to be run") if (!interactive()) { args <- parser$parse_args() - script_name <- args$script_name - if(!fs::file_exists(script_name)) { - stop(sprintf("Specified file, %s, does not exist", script_name)) + script_path <- args$script_path + if(!fs::file_exists(script_path)) { + stop(sprintf("Specified file, %s, does not exist", script_path)) } } else { - script_name <- "report/sample_report.qmd" - if(!fs::file_exists(script_name)) { - stop(sprintf("Specified file, %s, does not exist", script_name)) + script_path <- "report/sample_report.Rmd" + if(!fs::file_exists(script_path)) { + stop(sprintf("Specified file, %s, does not exist", script_path)) } } -report_name <- word(script_name, 1, sep = "\\.") -report_type <- word(script_name, 2, sep = "\\.") +render_results <- render_report(script_path) -script_run_time <- set_script_run_time() -output_filename <- - paste0( - str_replace(report_name, ".*/", ""), - "_", - format(script_run_time, "%Y%m%d%H%M%S") - ) +if (render_results$success) { + email_subject <- paste(render_results$report_name) + attachment_object <- mime_part(render_results$filepath) + body <- "Please see the attached report." + email_body <- list(body, attachment_object) -if (report_type == "qmd") { - full_path_to_output_file <- quarto::quarto_render( - script_name, - output_file = paste0(output_filename, ".pdf"), - output_format = "pdf" - ) + send_email(email_body, email_subject) - attachment_object <- mime_part(paste0(output_filename, ".pdf")) + # log_job_success(jsonlite::toJSON(basename(script_path))) } else { - full_path_to_output_file <- render( - script_name, - output_file = output_filename - ) - - attachment_object <- mime_part( - full_path_to_output_file, - basename(full_path_to_output_file) - ) + email_body <- "Report failed to render." + email_subject <- paste0("Failed | ", here::here(script_path), " | ", format(get_script_run_time(), "%Y-%m-%d")) + send_email(email_body, email_subject) } - -email_subject <- paste(basename(report_name), "|", script_run_time) -body <- "Please see the attached report." - -email_body <- list(body, attachment_object) - -# send the email with the attached output file -send_email(email_body, email_subject) - -set_script_name("render_report") -log_job_success(jsonlite::toJSON(script_name)) diff --git a/report/sample_report.Rmd b/report/sample_report.Rmd index c786624..40b4352 100644 --- a/report/sample_report.Rmd +++ b/report/sample_report.Rmd @@ -1,5 +1,5 @@ --- -title: "Sample Report" +title: "Fail Sample Report" output: pdf_document --- @@ -14,7 +14,8 @@ This is an R Markdown document. Markdown is a simple formatting syntax for autho When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this: ```{r cars} -summary(cars) +# This will fail as failure_test does not exist +summary(failure_test) ``` ## Including Plots diff --git a/report/sample_report.qmd b/report/sample_report.qmd index 9f3d18f..9352842 100644 --- a/report/sample_report.qmd +++ b/report/sample_report.qmd @@ -3,6 +3,7 @@ title: "sample_report" format: html: toc: true + embed-resources: true pdf: toc: true --- diff --git a/study_template/report/quarto_html_example.qmd b/study_template/report/quarto_html_example.qmd index 1a89e4b..dd43229 100644 --- a/study_template/report/quarto_html_example.qmd +++ b/study_template/report/quarto_html_example.qmd @@ -2,6 +2,7 @@ title: "Quarto HTML example" author: "John Doe" format: html +embed-resources: true editor: visual --- diff --git a/study_template/report/render_report.R b/study_template/report/render_report.R index e41a08e..fe96812 100644 --- a/study_template/report/render_report.R +++ b/study_template/report/render_report.R @@ -1,8 +1,5 @@ library(tidyverse) library(dotenv) -library(REDCapR) -library(lubridate) -library(rmarkdown) library(sendmailR) library(redcapcustodian) library(argparse) @@ -10,58 +7,33 @@ library(argparse) init_etl("render_report") parser <- ArgumentParser() -parser$add_argument("script_name", nargs=1, help="Script to be run") +parser$add_argument("script_path", nargs=1, help="The full path of the script to be run") if (!interactive()) { args <- parser$parse_args() - script_name <- args$script_name - if(!fs::file_exists(script_name)) { - stop(sprintf("Specified file, %s, does not exist", script_name)) + script_path <- args$script_path + if(!fs::file_exists(script_path)) { + stop(sprintf("Specified file, %s, does not exist", script_path)) } } else { - script_name <- "report/sample_report.qmd" - if(!fs::file_exists(script_name)) { - stop(sprintf("Specified file, %s, does not exist", script_name)) + script_path <- "report/study_template/rmd_pdf_example.Rmd" + if(!fs::file_exists(script_path)) { + stop(sprintf("Specified file, %s, does not exist", script_path)) } } -report_name <- word(script_name, 1, sep = "\\.") -report_type <- word(script_name, 2, sep = "\\.") +render_results <- render_report(script_path) -script_run_time <- set_script_run_time() -output_filename <- - paste0( - str_replace(report_name, ".*/", ""), - "_", - format(script_run_time, "%Y%m%d%H%M%S") - ) +if (render_results$success) { + email_subject <- paste(render_results$report_name) + attachment_object <- mime_part(render_results$filepath) + body <- "Please see the attached report." + email_body <- list(body, attachment_object) -if (report_type == "qmd") { - full_path_to_output_file <- quarto::quarto_render( - script_name, - output_file = paste0(output_filename, ".pdf"), - output_format = "pdf" - ) + send_email(email_body, email_subject) - attachment_object <- mime_part(paste0(output_filename, ".pdf")) + # log_job_success(jsonlite::toJSON(basename(script_path))) } else { - full_path_to_output_file <- render( - script_name, - output_file = output_filename - ) - - attachment_object <- mime_part( - full_path_to_output_file, - basename(full_path_to_output_file) - ) + email_body <- "Report failed to render." + email_subject <- paste0("Failed | ", here::here(script_path), " | ", format(get_script_run_time(), "%Y-%m-%d")) + send_email(email_body, email_subject) } - -email_subject <- paste(basename(report_name), "|", script_run_time) -body <- "Please see the attached report." - -email_body <- list(body, attachment_object) - -# send the email with the attached output file -send_email(email_body, email_subject) - -set_script_name("render_report") -log_job_success(jsonlite::toJSON(script_name)) diff --git a/study_template/report/sample_report.Rmd b/study_template/report/rmd_pdf_example.Rmd similarity index 100% rename from study_template/report/sample_report.Rmd rename to study_template/report/rmd_pdf_example.Rmd From 84f26f51b6db17c9e7696ccc7dbda9ba2c8746a9 Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Mon, 21 Oct 2024 18:55:01 -0400 Subject: [PATCH 02/11] add logging --- R/reporting.R | 15 +++++----- man/render_report.Rd | 8 ++--- report/render_report.R | 10 ++++--- report/sample_report.Rmd | 2 +- study_template/report/quarto_html_example.qmd | 2 +- .../report/quarto_html_fail_example.qmd | 18 +++++++++++ study_template/report/quarto_pdf_example.qmd | 2 +- study_template/report/render_report.R | 10 ++++--- study_template/report/rmd_html_example.Rmd | 30 +++++++++++++++++++ study_template/report/rmd_pdf_example.Rmd | 6 ++-- 10 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 study_template/report/quarto_html_fail_example.qmd create mode 100644 study_template/report/rmd_html_example.Rmd diff --git a/R/reporting.R b/R/reporting.R index fd3751c..d021094 100644 --- a/R/reporting.R +++ b/R/reporting.R @@ -11,13 +11,13 @@ #' If rendering is successful, the list includes: #' \itemize{ #' \item `success`: TRUE -#' \item `report_name`: The name of the report file -#' \item `filepath`: The full path to where the report is saved +#' \item `report_name`: The name of the report file. +#' \item `filepath`: The full path to the report. #' } #' If rendering fails, the list includes: #' \itemize{ #' \item `success`: FALSE -#' \item `error`: A string describing the error message +#' \item `logfile`: The full path to the log file. #' } #' #' @export @@ -25,7 +25,7 @@ #' @examples #' \dontrun{ #' script_path <- here::here("report", "quarto_html_example.qmd") -#' report_metadata <- render_report(script_path) +#' render_results <- render_report(script_path) #' } #' #' @@ -33,14 +33,13 @@ render_report <- function(script_path) { script_path_without_extension <- tools::file_path_sans_ext(script_path) base_script_name <- basename(script_path_without_extension) + logfile <- paste0(script_path_without_extension, "_log.txt") result <- tryCatch({ - quarto::quarto_render(script_path) - # Return a success indicator if no error occurs + capture.output(quarto::quarto_render(script_path), file = logfile) list(success = TRUE) }, error = function(e) { - # Return failure and error message - list(success = FALSE, error = e$message) + list(success = FALSE, logfile = logfile) }) if (!result$success) { diff --git a/man/render_report.Rd b/man/render_report.Rd index 4a58a77..ac5d308 100644 --- a/man/render_report.Rd +++ b/man/render_report.Rd @@ -15,13 +15,13 @@ A list containing details about the operation's outcome: If rendering is successful, the list includes: \itemize{ \item `success`: TRUE - \item `report_name`: The name of the report file - \item `filepath`: The full path to where the report is saved + \item `report_name`: The name of the report file. + \item `filepath`: The full path to the report. } If rendering fails, the list includes: \itemize{ \item `success`: FALSE - \item `error`: A string describing the error message + \item `logfile`: The full path to the log file. } } \description{ @@ -32,7 +32,7 @@ timestamp appended to the filename. \examples{ \dontrun{ script_path <- here::here("report", "quarto_html_example.qmd") -report_metadata <- render_report(script_path) +render_results <- render_report(script_path) } diff --git a/report/render_report.R b/report/render_report.R index c134df1..0f0d1d0 100644 --- a/report/render_report.R +++ b/report/render_report.R @@ -8,6 +8,7 @@ init_etl("render_report") parser <- ArgumentParser() parser$add_argument("script_path", nargs=1, help="The full path of the script to be run") + if (!interactive()) { args <- parser$parse_args() script_path <- args$script_path @@ -15,7 +16,7 @@ if (!interactive()) { stop(sprintf("Specified file, %s, does not exist", script_path)) } } else { - script_path <- "report/sample_report.Rmd" + script_path <- "study_template/report/quarto_html_example.qmd" if(!fs::file_exists(script_path)) { stop(sprintf("Specified file, %s, does not exist", script_path)) } @@ -28,12 +29,13 @@ if (render_results$success) { attachment_object <- mime_part(render_results$filepath) body <- "Please see the attached report." email_body <- list(body, attachment_object) - send_email(email_body, email_subject) - # log_job_success(jsonlite::toJSON(basename(script_path))) + log_job_success(jsonlite::toJSON(basename(script_path))) } else { - email_body <- "Report failed to render." email_subject <- paste0("Failed | ", here::here(script_path), " | ", format(get_script_run_time(), "%Y-%m-%d")) + attachment_object <- mime_part(render_results$logfile) + body <- "Report failed to render." + email_body <- list(body, attachment_object) send_email(email_body, email_subject) } diff --git a/report/sample_report.Rmd b/report/sample_report.Rmd index 40b4352..192a6f6 100644 --- a/report/sample_report.Rmd +++ b/report/sample_report.Rmd @@ -15,7 +15,7 @@ When you click the **Knit** button a document will be generated that includes bo ```{r cars} # This will fail as failure_test does not exist -summary(failure_test) +summary(cars) ``` ## Including Plots diff --git a/study_template/report/quarto_html_example.qmd b/study_template/report/quarto_html_example.qmd index dd43229..f9af276 100644 --- a/study_template/report/quarto_html_example.qmd +++ b/study_template/report/quarto_html_example.qmd @@ -1,5 +1,5 @@ --- -title: "Quarto HTML example" +title: "Quarto HTML Example" author: "John Doe" format: html embed-resources: true diff --git a/study_template/report/quarto_html_fail_example.qmd b/study_template/report/quarto_html_fail_example.qmd new file mode 100644 index 0000000..9786981 --- /dev/null +++ b/study_template/report/quarto_html_fail_example.qmd @@ -0,0 +1,18 @@ +--- +title: "Quarto HTML Fail Example" +format: html +embed-resources: true +editor: visual +--- + +## Quarto + +Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see . + +## Running Code + +When you click the **Render** button a document will be generated that includes both content and the output of embedded code. You can embed code like this: + +```{r} +1 + a +``` diff --git a/study_template/report/quarto_pdf_example.qmd b/study_template/report/quarto_pdf_example.qmd index cf09dd6..a7c9240 100644 --- a/study_template/report/quarto_pdf_example.qmd +++ b/study_template/report/quarto_pdf_example.qmd @@ -1,5 +1,5 @@ --- -title: "Quarto PDF example" +title: "Quarto PDF Example" format: pdf editor: visual --- diff --git a/study_template/report/render_report.R b/study_template/report/render_report.R index fe96812..0f0d1d0 100644 --- a/study_template/report/render_report.R +++ b/study_template/report/render_report.R @@ -8,6 +8,7 @@ init_etl("render_report") parser <- ArgumentParser() parser$add_argument("script_path", nargs=1, help="The full path of the script to be run") + if (!interactive()) { args <- parser$parse_args() script_path <- args$script_path @@ -15,7 +16,7 @@ if (!interactive()) { stop(sprintf("Specified file, %s, does not exist", script_path)) } } else { - script_path <- "report/study_template/rmd_pdf_example.Rmd" + script_path <- "study_template/report/quarto_html_example.qmd" if(!fs::file_exists(script_path)) { stop(sprintf("Specified file, %s, does not exist", script_path)) } @@ -28,12 +29,13 @@ if (render_results$success) { attachment_object <- mime_part(render_results$filepath) body <- "Please see the attached report." email_body <- list(body, attachment_object) - send_email(email_body, email_subject) - # log_job_success(jsonlite::toJSON(basename(script_path))) + log_job_success(jsonlite::toJSON(basename(script_path))) } else { - email_body <- "Report failed to render." email_subject <- paste0("Failed | ", here::here(script_path), " | ", format(get_script_run_time(), "%Y-%m-%d")) + attachment_object <- mime_part(render_results$logfile) + body <- "Report failed to render." + email_body <- list(body, attachment_object) send_email(email_body, email_subject) } diff --git a/study_template/report/rmd_html_example.Rmd b/study_template/report/rmd_html_example.Rmd new file mode 100644 index 0000000..fb7d9a9 --- /dev/null +++ b/study_template/report/rmd_html_example.Rmd @@ -0,0 +1,30 @@ +--- +title: "Rmd HTML Example" +format: + html: + self-contained: true +--- + +```{r setup, include=FALSE} +knitr::opts_chunk$set(echo = TRUE) +``` + +## R Markdown + +This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see . + +When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this: + +```{r cars} +summary(cars) +``` + +## Including Plots + +You can also embed plots, for example: + +```{r pressure, echo=FALSE} +plot(pressure) +``` + +Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot. diff --git a/study_template/report/rmd_pdf_example.Rmd b/study_template/report/rmd_pdf_example.Rmd index c786624..c74d6e8 100644 --- a/study_template/report/rmd_pdf_example.Rmd +++ b/study_template/report/rmd_pdf_example.Rmd @@ -1,6 +1,8 @@ --- -title: "Sample Report" -output: pdf_document +title: "Rmd PDF Example" +format: + pdf: + self-contained: true --- ```{r setup, include=FALSE} From 9c9ab35a80fb04ee1f9050334f67bf984742b933 Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Mon, 21 Oct 2024 19:00:39 -0400 Subject: [PATCH 03/11] revert report --- report/sample_report.Rmd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/report/sample_report.Rmd b/report/sample_report.Rmd index 192a6f6..c786624 100644 --- a/report/sample_report.Rmd +++ b/report/sample_report.Rmd @@ -1,5 +1,5 @@ --- -title: "Fail Sample Report" +title: "Sample Report" output: pdf_document --- @@ -14,7 +14,6 @@ This is an R Markdown document. Markdown is a simple formatting syntax for autho When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this: ```{r cars} -# This will fail as failure_test does not exist summary(cars) ``` From c5d81cb1db2dba34e540e380e0132e2ac0e969a7 Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Mon, 21 Oct 2024 19:04:18 -0400 Subject: [PATCH 04/11] switch to self contained report --- report/sample_report.Rmd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/report/sample_report.Rmd b/report/sample_report.Rmd index c786624..003db79 100644 --- a/report/sample_report.Rmd +++ b/report/sample_report.Rmd @@ -1,6 +1,8 @@ --- title: "Sample Report" -output: pdf_document +format: + pdf: + self-contained: true --- ```{r setup, include=FALSE} From c9ad3be6a30053d6789753a83b2207690103e09c Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Mon, 21 Oct 2024 19:13:01 -0400 Subject: [PATCH 05/11] add output folder --- study_template/report/output/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 study_template/report/output/.gitignore diff --git a/study_template/report/output/.gitignore b/study_template/report/output/.gitignore new file mode 100644 index 0000000..848bcb4 --- /dev/null +++ b/study_template/report/output/.gitignore @@ -0,0 +1,4 @@ +*.csv +*.xlsx +*.html +*.pdf From 81023d56202b0761d6bb7020f154c2ad7c111f01 Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Mon, 21 Oct 2024 19:19:15 -0400 Subject: [PATCH 06/11] ad generic error msg --- R/reporting.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/reporting.R b/R/reporting.R index d021094..b8e5107 100644 --- a/R/reporting.R +++ b/R/reporting.R @@ -39,7 +39,7 @@ render_report <- function(script_path) { capture.output(quarto::quarto_render(script_path), file = logfile) list(success = TRUE) }, error = function(e) { - list(success = FALSE, logfile = logfile) + list(success = FALSE, logfile = logfile, error = e$message) }) if (!result$success) { From 643b07e384d14b711d5a247daadb303a64327066 Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Mon, 21 Oct 2024 19:20:35 -0400 Subject: [PATCH 07/11] update docs --- R/reporting.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/reporting.R b/R/reporting.R index b8e5107..6ddaec9 100644 --- a/R/reporting.R +++ b/R/reporting.R @@ -18,6 +18,7 @@ #' \itemize{ #' \item `success`: FALSE #' \item `logfile`: The full path to the log file. +#' \item `error`: Error message returned from quarto_render. #' } #' #' @export From 87231be1b4aa5dc886f457489c41841a524d73c5 Mon Sep 17 00:00:00 2001 From: Philip Chase Date: Tue, 22 Oct 2024 14:01:49 -0400 Subject: [PATCH 08/11] Ignore output files from render_report.R --- .gitignore | 2 ++ study_template/.gitignore | 1 + 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index c9e7bd9..a3bb104 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ *.zip site !inst/testdata/*.csv +report/*log.txt +report/*.html # env file *.env diff --git a/study_template/.gitignore b/study_template/.gitignore index 0b9e3e5..34f76c7 100644 --- a/study_template/.gitignore +++ b/study_template/.gitignore @@ -6,3 +6,4 @@ *.env !examples/testing.env output/ +report/*log.txt From 90ecf839efb020f0f683a9afca94e76476ae5d59 Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Wed, 23 Oct 2024 17:37:36 -0400 Subject: [PATCH 09/11] ignore log and output folders ad add timestamp to logfile --- .gitignore | 4 ++-- R/reporting.R | 5 +++-- man/render_report.Rd | 1 + report/log/.gitignore | 2 ++ report/output/.gitignore | 6 ++---- report/render_report.R | 14 ++++++-------- study_template/.gitignore | 3 ++- study_template/report/log/.gitignore | 2 ++ study_template/report/render_report.R | 14 ++++++-------- 9 files changed, 26 insertions(+), 25 deletions(-) create mode 100644 report/log/.gitignore create mode 100644 study_template/report/log/.gitignore diff --git a/.gitignore b/.gitignore index a3bb104..a626013 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,8 @@ *.zip site !inst/testdata/*.csv -report/*log.txt -report/*.html +report/output/* +report/log/* # env file *.env diff --git a/R/reporting.R b/R/reporting.R index 6ddaec9..10368ec 100644 --- a/R/reporting.R +++ b/R/reporting.R @@ -34,7 +34,8 @@ render_report <- function(script_path) { script_path_without_extension <- tools::file_path_sans_ext(script_path) base_script_name <- basename(script_path_without_extension) - logfile <- paste0(script_path_without_extension, "_log.txt") + run_time <- format(redcapcustodian::get_script_run_time(), "%Y-%m-%d_%H%M%S") + logfile <- here::here("report", "log", paste0(base_script_name, "_", run_time, ".txt")) result <- tryCatch({ capture.output(quarto::quarto_render(script_path), file = logfile) @@ -57,7 +58,7 @@ render_report <- function(script_path) { report_name <- paste0( base_script_name, "_", - format(redcapcustodian::get_script_run_time(), "%Y-%m-%d_%H%M%S"), + run_time, ".", file_extension ) diff --git a/man/render_report.Rd b/man/render_report.Rd index ac5d308..3db8200 100644 --- a/man/render_report.Rd +++ b/man/render_report.Rd @@ -22,6 +22,7 @@ A list containing details about the operation's outcome: \itemize{ \item `success`: FALSE \item `logfile`: The full path to the log file. + \item `error`: Error message returned from quarto_render. } } \description{ diff --git a/report/log/.gitignore b/report/log/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/report/log/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/report/output/.gitignore b/report/output/.gitignore index 848bcb4..d6b7ef3 100644 --- a/report/output/.gitignore +++ b/report/output/.gitignore @@ -1,4 +1,2 @@ -*.csv -*.xlsx -*.html -*.pdf +* +!.gitignore diff --git a/report/render_report.R b/report/render_report.R index 0f0d1d0..5e09088 100644 --- a/report/render_report.R +++ b/report/render_report.R @@ -7,19 +7,17 @@ library(argparse) init_etl("render_report") parser <- ArgumentParser() -parser$add_argument("script_path", nargs=1, help="The full path of the script to be run") +parser$add_argument("script_path", nargs=1, help="The path of the script to be run") if (!interactive()) { args <- parser$parse_args() script_path <- args$script_path - if(!fs::file_exists(script_path)) { - stop(sprintf("Specified file, %s, does not exist", script_path)) - } } else { - script_path <- "study_template/report/quarto_html_example.qmd" - if(!fs::file_exists(script_path)) { - stop(sprintf("Specified file, %s, does not exist", script_path)) - } + script_path <- here::here("report", "sample_report.Rmd") +} + +if(!fs::file_exists(script_path)) { + stop(sprintf("Specified file, %s, does not exist", script_path)) } render_results <- render_report(script_path) diff --git a/study_template/.gitignore b/study_template/.gitignore index 34f76c7..1f1d324 100644 --- a/study_template/.gitignore +++ b/study_template/.gitignore @@ -6,4 +6,5 @@ *.env !examples/testing.env output/ -report/*log.txt +report/output/* +report/log/* diff --git a/study_template/report/log/.gitignore b/study_template/report/log/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/study_template/report/log/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/study_template/report/render_report.R b/study_template/report/render_report.R index 0f0d1d0..18283a6 100644 --- a/study_template/report/render_report.R +++ b/study_template/report/render_report.R @@ -7,19 +7,17 @@ library(argparse) init_etl("render_report") parser <- ArgumentParser() -parser$add_argument("script_path", nargs=1, help="The full path of the script to be run") +parser$add_argument("script_path", nargs=1, help="The path of the script to be run") if (!interactive()) { args <- parser$parse_args() script_path <- args$script_path - if(!fs::file_exists(script_path)) { - stop(sprintf("Specified file, %s, does not exist", script_path)) - } } else { - script_path <- "study_template/report/quarto_html_example.qmd" - if(!fs::file_exists(script_path)) { - stop(sprintf("Specified file, %s, does not exist", script_path)) - } + script_path <- here::here("report", "quarto_html_example.qmd") +} + +if(!fs::file_exists(script_path)) { + stop(sprintf("Specified file, %s, does not exist", script_path)) } render_results <- render_report(script_path) From 25a6345bb69a00cb41219384879b8c59b6f01343 Mon Sep 17 00:00:00 2001 From: Laurence James-Woodley Date: Thu, 24 Oct 2024 07:11:50 -0400 Subject: [PATCH 10/11] ignore files created outside of render_report --- .gitignore | 7 +++++-- study_template/.gitignore | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index a626013..aa6ca1d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,11 @@ *.zip site !inst/testdata/*.csv -report/output/* -report/log/* +report/*.html +report/*.pdf +report/*.txt + + # env file *.env diff --git a/study_template/.gitignore b/study_template/.gitignore index 1f1d324..ff81c3e 100644 --- a/study_template/.gitignore +++ b/study_template/.gitignore @@ -6,5 +6,7 @@ *.env !examples/testing.env output/ -report/output/* -report/log/* +report/*.html +report/*.pdf +report/*.txt + From a618c56a6291fdd474a02641fa2bfeb4fc1e6305 Mon Sep 17 00:00:00 2001 From: Philip Chase Date: Thu, 24 Oct 2024 13:50:17 -0400 Subject: [PATCH 11/11] Bump VERSION and update NEWS.md for release 1.25.0 --- DESCRIPTION | 2 +- NEWS.md | 5 +++++ VERSION | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f4df7b4..3a05942 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: redcapcustodian Type: Package Title: Data automation for R-centric workflows with a nod towards REDCap -Version: 1.24.0 +Version: 1.25.0 Authors@R: c( person("Philip", "Chase", email = "pbc@ufl.edu", diff --git a/NEWS.md b/NEWS.md index 6b3fedc..37ccdf9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# redcapcustodian 1.25.0 (released 2024-10-24) +- Add report crash logging to render_report.R (@ljwoodley, #166) +- Update render_report.R to use render_report() function (@ljwoodley, #166) +- Add render_report() (@ljwoodley, #166) + # redcapcustodian 1.24.0 (released 2024-10-17) - Add job failure alerts with run_etl.R and updates to send_mail() (@ljwoodley, #100, #165) - Add Sai as author in DESCRIPTION (@pbchase) diff --git a/VERSION b/VERSION index 53cc1a6..ad21919 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.24.0 +1.25.0