|
| 1 | +in_debug_mode <- function() { |
| 2 | + in_ci_with_debug() || quarto_log_level("DEBUG") || is_quarto_r_debug() |
| 3 | +} |
| 4 | + |
| 5 | +in_ci_with_debug <- function() { |
| 6 | + # check for GitHub Actions debug mode |
| 7 | + # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables |
| 8 | + gha_debug <- Sys.getenv("ACTIONS_RUNNER_DEBUG", "") == "true" || |
| 9 | + Sys.getenv("ACTIONS_STEP_DEBUG", "") == "true" |
| 10 | + return(gha_debug) |
| 11 | +} |
| 12 | + |
| 13 | +# Return the current log level for Quarto |
| 14 | +# unless level is provided, in which case |
| 15 | +# it checks if the current log level matches the provided level. |
| 16 | +quarto_log_level <- function(level = NULL) { |
| 17 | + log_level <- Sys.getenv("QUARTO_LOG_LEVEL", NA) |
| 18 | + if (is.null(level)) { |
| 19 | + return(log_level) |
| 20 | + } |
| 21 | + return(identical(tolower(log_level), tolower(level))) |
| 22 | +} |
| 23 | + |
| 24 | +#' @importFrom xfun env_option |
| 25 | +is_quarto_r_debug <- function() { |
| 26 | + # check option first, then environment variable |
| 27 | + # to allow setting in the R session |
| 28 | + # env var R_QUARTO_LOG_DEBUG |
| 29 | + isTRUE(as.logical(xfun::env_option('quarto.log.debug', FALSE))) |
| 30 | +} |
| 31 | + |
| 32 | +# Get the configured log file path |
| 33 | +# Uses xfun::env_option to check for log file configuration |
| 34 | +# with option 'quarto.log.file' and env var 'R_QUARTO_LOG_FILE' |
| 35 | +#' @importFrom xfun env_option |
| 36 | +get_log_file <- function() { |
| 37 | + xfun::env_option('quarto.log.file', default = "./quarto-r-debug.log") |
| 38 | +} |
| 39 | + |
| 40 | +#' Log debug information to a configurable file |
| 41 | +#' |
| 42 | +#' This function logs messages to a file only when in debug mode to help diagnose |
| 43 | +#' issues with Quarto vignettes in **pkgdown** and other contexts. |
| 44 | +#' |
| 45 | +#' Debug mode will be enabled automatically when debugging Github Actions workflows, |
| 46 | +#' or when Quarto CLI's environment variable `QUARTO_LOG_LEVEL` is set to `DEBUG`. |
| 47 | +#' |
| 48 | +#' @param ... Messages to log (will be concatenated) |
| 49 | +#' @param file Path to log file. If NULL, uses `get_log_file()` to determine the file. |
| 50 | +#' Default will be `./quarto-r-debug.log` if no configuration is found. |
| 51 | +#' @param append Logical. Should the messages be appended to the file? Default TRUE. |
| 52 | +#' @param timestamp Logical. Should a timestamp be added? Default TRUE. |
| 53 | +#' @param prefix Character. Prefix to add before each log entry. Default "DEBUG: ". |
| 54 | +#' |
| 55 | +#' @return Invisibly returns TRUE if logging occurred, FALSE otherwise |
| 56 | +#' @keywords internal |
| 57 | +#' |
| 58 | +#' @section Configuration: |
| 59 | +#' |
| 60 | +#' **Enable debugging messages:** |
| 61 | +#' - Set `quarto.log.debug = TRUE` (or `R_QUARTO_LOG_DEBUG = TRUE` environment variable) |
| 62 | +#' |
| 63 | +#' **Change log file path:** |
| 64 | +#' - Set `quarto.log.file` to change the file path (or `R_QUARTO_LOG_FILE` environment variable) |
| 65 | +#' - Default will be `./quarto-r-debug.log` |
| 66 | +#' |
| 67 | +#' **Automatic debug mode:** |
| 68 | +#' - Debug mode will be on automatically when debugging Github Actions workflows |
| 69 | +#' - When Quarto CLI's environment variable `QUARTO_LOG_LEVEL` is set to `DEBUG` |
| 70 | +#' |
| 71 | +#' @examples |
| 72 | +#' \dontrun{ |
| 73 | +#' # Set log file via environment variable |
| 74 | +#' Sys.setenv(R_QUARTO_LOG_FILE = "~/quarto-debug.log") |
| 75 | +#' |
| 76 | +#' # Or via option |
| 77 | +#' options(quarto.log.file = "~/quarto-debug.log") |
| 78 | +#' |
| 79 | +#' # Enable debug mode |
| 80 | +#' options(quarto.log.debug = TRUE) |
| 81 | +#' |
| 82 | +#' # Log some information |
| 83 | +#' quarto_log("Starting process") |
| 84 | +#' quarto_log("R_LIBS:", Sys.getenv("R_LIBS")) |
| 85 | +#' quarto_log(".libPaths():", paste0(.libPaths(), collapse = ":")) |
| 86 | +#' } |
| 87 | +quarto_log <- function( |
| 88 | + ..., |
| 89 | + file = NULL, |
| 90 | + append = TRUE, |
| 91 | + timestamp = TRUE, |
| 92 | + prefix = "DEBUG: " |
| 93 | +) { |
| 94 | + if (!in_debug_mode()) { |
| 95 | + return(invisible(FALSE)) |
| 96 | + } |
| 97 | + |
| 98 | + if (is.null(file)) { |
| 99 | + file <- get_log_file() |
| 100 | + } |
| 101 | + |
| 102 | + # get_log_file() now returns the default, so no need for additional fallback |
| 103 | + |
| 104 | + # Construct the message |
| 105 | + msg_parts <- list(...) |
| 106 | + msg <- paste(msg_parts, collapse = "") |
| 107 | + |
| 108 | + # Add prefix if provided |
| 109 | + if (!is.null(prefix) && nchar(prefix) > 0) { |
| 110 | + msg <- paste0(prefix, msg) |
| 111 | + } |
| 112 | + |
| 113 | + # Add timestamp if requested |
| 114 | + if (timestamp) { |
| 115 | + ts <- format(Sys.time(), "[%Y-%m-%d %H:%M:%S] ") |
| 116 | + msg <- paste0(ts, msg) |
| 117 | + } |
| 118 | + |
| 119 | + # Ensure message ends with newline |
| 120 | + if (!grepl("\n$", msg)) { |
| 121 | + msg <- paste0(msg, "\n") |
| 122 | + } |
| 123 | + |
| 124 | + # Write to file |
| 125 | + tryCatch( |
| 126 | + { |
| 127 | + cat(msg, file = file, append = append) |
| 128 | + return(invisible(TRUE)) |
| 129 | + }, |
| 130 | + error = function(e) { |
| 131 | + # If we can't write to the file, fail silently in debug logging |
| 132 | + return(invisible(FALSE)) |
| 133 | + } |
| 134 | + ) |
| 135 | +} |
0 commit comments