diff --git a/DESCRIPTION b/DESCRIPTION index 080f9e0..14e7fc7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: quarto Title: R Interface to 'Quarto' Markdown Publishing System -Version: 1.3.10 +Version: 1.3.11 Authors@R: c( person("JJ", "Allaire", , "jj@rstudio.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-0174-9868")), diff --git a/NAMESPACE b/NAMESPACE index 843072b..1c1fcb6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,6 +2,7 @@ export(is_using_quarto) export(quarto_add_extension) +export(quarto_binary_sitrep) export(quarto_create_project) export(quarto_inspect) export(quarto_path) diff --git a/NEWS.md b/NEWS.md index 65aac55..e30be26 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # quarto (development version) +- Add `quarto_binary_sitrep()` to check possible difference in Quarto binary used by this package, and the one used by RStudio IDE (thanks, @jthomasmock, #12). + - Add `quarto_create_project()` function that calls `quarto create project ` (thanks, @maelle, #87). - Add `is_using_quarto()` to check if a directory requires using Quarto (i.e. it has a `_quarto.yml` or at least one `*.qmd` file) (thanks, @hadley, #103). diff --git a/R/quarto.R b/R/quarto.R index ec92c5c..b2c59d4 100644 --- a/R/quarto.R +++ b/R/quarto.R @@ -7,7 +7,7 @@ #' #' @export quarto_path <- function() { - path_env <- Sys.getenv("QUARTO_PATH", unset = NA) + path_env <- get_quarto_path_env() if (is.na(path_env)) { path <- unname(Sys.which("quarto")) if (nzchar(path)) path else NULL @@ -16,10 +16,19 @@ quarto_path <- function() { } } +get_quarto_path_env <- function() { + Sys.getenv("QUARTO_PATH", unset = NA_character_) +} + +quarto_not_found_msg <- c( + "Quarto command-line tools path not found! ", + "Please make sure you have installed and added Quarto to your PATH or set the QUARTO_PATH environment variable." +) + find_quarto <- function() { path <- quarto_path() if (is.null(path)) { - stop("Quarto command-line tools path not found! Please make sure you have installed and added Quarto to your PATH or set the QUARTO_PATH environment variable.") + cli::cli_abort(quarto_not_found_msg) } else { return(path) } @@ -95,3 +104,83 @@ check_quarto_version <- function(ver, what, url) { ) } } + +#' Check configurations for quarto binary used +#' +#' This function check the configuration for the quarto package R package to +#' detect a possible difference with version used by RStudio IDE. +#' +#' @param verbose if `FALSE`, only return the result of the check. +#' @param debug if `TRUE`, print more information about value set in configurations. +#' +#' @returns `TRUE` if this package should be using the same quarto binary as the +#' RStudio IDE. `FALSE` otherwise if a difference is detected or quarto is not +#' found. Use `verbose = TRUE` or`debug = TRUE` to get detailed information. +#' @examples +#' quarto_binary_sitrep(verbose = FALSE) +#' quarto_binary_sitrep(verbose = TRUE) +#' quarto_binary_sitrep(debug = TRUE) +#' +#' @export +quarto_binary_sitrep <- function(verbose = TRUE, debug = FALSE) { + + quarto_found <- normalizePath(quarto_path(), mustWork = FALSE) + if (is.null(quarto_found)) { + if (verbose) { + cli::cli_alert_danger(quarto_not_found_msg) + } + return(FALSE) + } + + same_config <- TRUE + if (debug) verbose <- TRUE + + + # Quarto R package situation ---- + if (verbose) { + cli::cli_alert_success(c("i" = "quarto R package will use {.path {quarto_found}}")) + } + + quarto_r_env <- normalizePath(get_quarto_path_env(), mustWork = FALSE) + quarto_system <- normalizePath(unname(Sys.which("quarto")), mustWork = FALSE) + # quarto R package will use QUARTO_PATH env var with higher priority than latest version on path $PATH + # and RStudio IDE does not use this environment variable + if (!is.na(quarto_r_env) && identical(quarto_r_env, quarto_found)) { + same_config <- FALSE + if (verbose) { + cli::cli_alert_warning(c( + "It is configured through {.envvar QUARTO_PATH} environment variable. ", + "RStudio IDE will likely use another binary." + )) + } + } else if (nzchar(quarto_system) && identical(quarto_system, quarto_found)) { + if (debug) { + cli::cli_alert_info(c( + " It is configured to use the latest version found in the {.emph PATH} environment variable." + )) + } + } + + # RStudio IDE known situation ---- + + # RStudio IDE > Render button will use RSTUDIO_QUARTO env var with higher priority than latest version on path $PATH + rstudio_env <- Sys.getenv("RSTUDIO_QUARTO", unset = NA) + if (!is.na(rstudio_env)) { + rstudio_env <- normalizePath(rstudio_env, mustWork = FALSE) + if (!identical(rstudio_env, quarto_found)) { + same_config <- FALSE + if (verbose) { + cli::cli_alert_danger(c( + "RStudio IDE render button seems configured to use {.path {rstudio_env}}." + )) + if (debug) { + cli::cli_alert_warning(c( + " It is configured through {.envvar RSTUDIO_QUARTO} environment variable." + )) + } + } + } + } + + return(same_config) +} diff --git a/_pkgdown.yml b/_pkgdown.yml index be0a8d8..20134e5 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -53,4 +53,5 @@ reference: - quarto_path - quarto_version - is_using_quarto + - quarto_binary_sitrep diff --git a/man/quarto_binary_sitrep.Rd b/man/quarto_binary_sitrep.Rd new file mode 100644 index 0000000..33429c2 --- /dev/null +++ b/man/quarto_binary_sitrep.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/quarto.R +\name{quarto_binary_sitrep} +\alias{quarto_binary_sitrep} +\title{Check configurations for quarto binary used} +\usage{ +quarto_binary_sitrep(verbose = TRUE, debug = FALSE) +} +\arguments{ +\item{verbose}{if \code{FALSE}, only return the result of the check.} + +\item{debug}{if \code{TRUE}, print more information about value set in configurations.} +} +\value{ +\code{TRUE} if this package should be using the same quarto binary as the +RStudio IDE. \code{FALSE} otherwise if a difference is detected or quarto is not +found. Use \code{verbose = TRUE} or\code{debug = TRUE} to get detailed information. +} +\description{ +This function check the configuration for the quarto package R package to +detect a possible difference with version used by RStudio IDE. +} +\examples{ +quarto_binary_sitrep(verbose = FALSE) +quarto_binary_sitrep(verbose = TRUE) +quarto_binary_sitrep(debug = TRUE) + +} diff --git a/tests/testthat/_snaps/quarto.md b/tests/testthat/_snaps/quarto.md index 8e74a38..8d3700f 100644 --- a/tests/testthat/_snaps/quarto.md +++ b/tests/testthat/_snaps/quarto.md @@ -45,3 +45,35 @@ Output [1] FALSE +# quarto CLI sitrep + + Code + quarto_binary_sitrep(debug = TRUE) + Message + v quarto R package will use '' + ! It is configured through `QUARTO_PATH` environment variable. RStudio IDE will likely use another binary. + Output + [1] FALSE + +--- + + Code + quarto_binary_sitrep(debug = TRUE) + Message + v quarto R package will use '' + i It is configured to use the latest version found in the PATH environment variable. + x RStudio IDE render button seems configured to use ''. + ! It is configured through `RSTUDIO_QUARTO` environment variable. + Output + [1] FALSE + +--- + + Code + quarto_binary_sitrep(debug = TRUE) + Message + v quarto R package will use '' + i It is configured to use the latest version found in the PATH environment variable. + Output + [1] TRUE + diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R index a7686f0..1e76e2c 100644 --- a/tests/testthat/helper.R +++ b/tests/testthat/helper.R @@ -73,11 +73,13 @@ expect_snapshot_qmd_output <- function(name, input, output_file = NULL, ...) { } -transform_quarto_cli_in_output <- function(full_path = FALSE) { +transform_quarto_cli_in_output <- function(full_path = FALSE, normalize_path = FALSE) { return( function(lines) { if (full_path) { - lines <- gsub(find_quarto(), "", lines, fixed = TRUE) + quarto_found <- find_quarto() + if (normalize_path) {quarto_found <- normalizePath(quarto_found, mustWork = FALSE)} + lines <- gsub(quarto_found, "", lines, fixed = TRUE) # seems like there are quotes around path in CI windows lines <- gsub("\"\"", "", lines, fixed = TRUE) return(lines) diff --git a/tests/testthat/test-quarto.R b/tests/testthat/test-quarto.R index 4b105e8..acbe22a 100644 --- a/tests/testthat/test-quarto.R +++ b/tests/testthat/test-quarto.R @@ -34,3 +34,35 @@ test_that("is_using_quarto correctly check directory", { withr::local_dir(dirname(qmd)) withr::local_file("test.txt") }) + +test_that("quarto CLI sitrep", { + skip_if_no_quarto() + skip_on_cran() + local_reproducible_output(width = 1000) + dummy_quarto_path <- normalizePath("dummy", mustWork = FALSE) + withr::with_envvar( + list(QUARTO_PATH = dummy_quarto_path, RSTUDIO_QUARTO = NA), + expect_snapshot( + quarto_binary_sitrep(debug = TRUE), + transform = function(lines) gsub(dummy_quarto_path, "", lines, fixed = TRUE) + ) + ) + withr::with_envvar( + list(QUARTO_PATH = NA, RSTUDIO_QUARTO = dummy_quarto_path), + expect_snapshot( + quarto_binary_sitrep(debug = TRUE), + transform = function(lines) { + lines <- gsub(dummy_quarto_path, "", lines, fixed = TRUE) + transform_quarto_cli_in_output(full_path = TRUE, normalize_path = TRUE)(lines) + } + ) + ) + + withr::with_envvar( + list(QUARTO_PATH = NA, RSTUDIO_QUARTO = NA), + expect_snapshot( + quarto_binary_sitrep(debug = TRUE), + transform = transform_quarto_cli_in_output(full_path = TRUE, normalize_path = TRUE) + ) + ) +})