Skip to content

Commit

Permalink
produce an error when Quarto content cannot be inspected (#1039)
Browse files Browse the repository at this point in the history
* produce an error when Quarto content cannot be inspected

fixes #1032

* snapshot inspect error tests and other minor tweaks

* suppress quarto colors
  • Loading branch information
aronatkins authored Jan 26, 2024
1 parent cbb41bb commit 2e59f9d
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 44 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
needed to be quoted. The resulting manifest lacked information about the
Quarto runtime, which caused difficult-to-understand deployment errors.
(#1037)
* Produce an error when Quarto content cannot be inspected. (#1032)

# rsconnect 1.2.0

Expand Down
40 changes: 25 additions & 15 deletions R/appMetadata-quarto.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Called only when the content is known to be Quarto.
inferQuartoInfo <- function(metadata, appDir, appPrimaryDoc) {
if (hasQuartoMetadata(metadata)) {
return(list(
Expand All @@ -11,10 +12,6 @@ inferQuartoInfo <- function(metadata, appDir, appPrimaryDoc) {
appDir = appDir,
appPrimaryDoc = appPrimaryDoc
)
if (is.null(inspect)) {
return(NULL)
}

list(
version = inspect[["quarto"]][["version"]],
engines = I(inspect[["engines"]])
Expand All @@ -37,20 +34,33 @@ quartoInspect <- function(appDir = NULL, appPrimaryDoc = NULL) {
))
}

paths <- c(appDir, file.path(appDir, appPrimaryDoc))
json <- suppressWarnings(
system2(
quarto, c("inspect", shQuote(appDir)),
stdout = TRUE, stderr = TRUE
)
)
status <- attr(json, "status")

if (!is.null(status) && !is.null(appPrimaryDoc)) {
json <- suppressWarnings(
system2(
quarto, c("inspect", shQuote(file.path(appDir, appPrimaryDoc))),
stdout = TRUE, stderr = TRUE
)
)
status <- attr(json, "status")
}

for (path in paths) {
args <- c("inspect", shQuote(path.expand(path)))
inspect <- tryCatch(
{
json <- suppressWarnings(system2(quarto, args, stdout = TRUE, stderr = TRUE))
parsed <- jsonlite::fromJSON(json)
return(parsed)
},
error = function(e) NULL
if (!is.null(status)) {
cli::cli_abort(
c(
"Failed to run `quarto inspect` against your content:",
json
)
)
}
return(NULL)
jsonlite::fromJSON(json)
}

# inlined from quarto::quarto_path()
Expand Down
18 changes: 18 additions & 0 deletions tests/testthat/_snaps/appMetadata-quarto.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,21 @@
! `quarto` not found.
i Check that it is installed and available on your `PATH`.

# quartoInspect produces an error when a document cannot be inspected

Code
quartoInspect(dir, "bad.qmd")
Condition
Error in `quartoInspect()`:
! Failed to run `quarto inspect` against your content:
ERROR: Unknown format unsupported

# quartoInspect produces an error when a project cannot be inspected

Code
quartoInspect(dir, "bad.qmd")
Condition
Error in `quartoInspect()`:
! Failed to run `quarto inspect` against your content:
ERROR: Unsupported project type unsupported

85 changes: 56 additions & 29 deletions tests/testthat/test-appMetadata-quarto.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test_that("inferQuartoInfo correctly detects info when quarto is provided alone"
expect_equal(quartoInfo$engines, I(c("knitr")))
})

test_that("inferQuartoInfo extracts info from metadata", {
test_that("inferQuartoInfo prefers metadata over quarto inspect", {
metadata <- fakeQuartoMetadata(version = "99.9.9", engines = c("internal-combustion"))

quartoInfo <- inferQuartoInfo(
Expand All @@ -43,38 +43,14 @@ test_that("inferQuartoInfo extracts info from metadata", {
))
})

test_that("inferQuartoInfo prefers using metadata over quarto inspect", {
skip_if_no_quarto()

metadata <- fakeQuartoMetadata(version = "99.9.9", engines = c("internal-combustion"))

quartoInfo <- inferQuartoInfo(
appDir = test_path("quarto-website-r"),
appPrimaryDoc = NULL,
metadata = metadata
)
expect_equal(quartoInfo$engines, I(c("internal-combustion")))
})

test_that("inferQuartoInfo returns NULL for non-quarto content", {
skip_if_no_quarto()

quartoInfo <- inferQuartoInfo(
appDir = test_path("shinyapp-simple"),
appPrimaryDoc = NULL,
metadata = list()
)
expect_null(quartoInfo)
})

test_that("quartoInspect requires quarto", {
local_mocked_bindings(quarto_path = function() NULL)
expect_snapshot(error = TRUE, {
quartoInspect()
})
})

test_that("quartoInspect identifies on Quarto projects", {
test_that("quartoInspect identifies Quarto projects", {
skip_if_no_quarto()

inspect <- quartoInspect(test_path("quarto-website-r"))
Expand Down Expand Up @@ -123,9 +99,60 @@ test_that("quartoInspect processes content with filenames containing spaces", {
expect_equal(inspect$engines, c("markdown"))
})

test_that("quartoInspect returns NULL on non-quarto Quarto content", {
# Some versions of Quarto show Quarto stack traces with source references when
# inspect fails.
#
# Only preserve:
#
# Error in `quartoInspect()`:
# ! Failed to run `quarto inspect` against your content:
# ERROR: Unsupported project type unsupported
strip_quarto_trace <- function(lines) {
head(lines, 3)
}

test_that("quartoInspect produces an error when a document cannot be inspected", {
skip_if_no_quarto()

# Suppress colors from Quarto errors.
withr::local_envvar(NO_COLOR = "1")

dir <- local_temp_app(list("bad.qmd" = c(
"---",
"format: unsupported",
"---",
"this is a document using an unsupported format."
)))
expect_snapshot(
quartoInspect(dir, "bad.qmd"),
error = TRUE,
transform = strip_quarto_trace
)
})

test_that("quartoInspect produces an error when a project cannot be inspected", {
skip_if_no_quarto()

inspect <- quartoInspect(test_path("shinyapp-simple"))
expect_null(inspect)
# Suppress colors from Quarto errors.
withr::local_envvar(NO_COLOR = "1")

dir <- local_temp_app(
list(
"_quarto.yml" = c(
"project:",
" type: unsupported"
),
"bad.qmd" = c(
"---",
"title: bad",
"---",
"this is a document using an unsupported format."
)
)
)
expect_snapshot(
quartoInspect(dir, "bad.qmd"),
error = TRUE,
transform = strip_quarto_trace
)
})

0 comments on commit 2e59f9d

Please sign in to comment.