From 13d8d621105a3a527a05e46c6c805a6564c39791 Mon Sep 17 00:00:00 2001 From: Jay Hesselberth Date: Thu, 30 Nov 2023 06:56:22 -0700 Subject: [PATCH] Use cli functions (#2378) Part of #2116 --- DESCRIPTION | 2 +- NAMESPACE | 1 - NEWS.md | 2 + R/build-articles.R | 21 ++-- R/build-favicons.R | 40 +++--- R/build-github.R | 4 +- R/build-home-authors.R | 4 +- R/build-home-index.R | 28 +++-- R/build-home-md.R | 2 +- R/build-home.R | 2 +- R/build-news.R | 17 +-- R/build-redirects.R | 21 ++-- R/build-reference-index.R | 28 ++--- R/build-reference.R | 18 +-- R/build-search-docs.R | 4 +- R/build-tutorials.R | 2 +- R/build.R | 20 +-- R/check.R | 2 +- R/clean.R | 8 +- R/deploy-site.R | 33 ++--- R/figure.R | 6 +- R/init.R | 7 +- R/markdown.R | 9 +- R/package.R | 39 +++--- R/preview.R | 2 +- R/rd-example.R | 35 +++--- R/rd-html.R | 16 +-- R/render.R | 56 +++++---- R/rmarkdown.R | 17 +-- R/sitrep.R | 32 +++-- R/templates.R | 11 +- R/test.R | 2 +- R/theme.R | 22 ++-- R/topics-external.R | 6 +- R/topics.R | 18 +-- R/usage.R | 20 ++- R/utils-fs.R | 20 ++- R/utils-yaml.R | 42 ++++--- R/utils.R | 35 +----- man/build_favicons.Rd | 3 - man/clean_site.Rd | 4 +- man/test-dont.Rd | 2 +- tests/testthat/_snaps/build-articles.md | 119 +++++++++++++++++- tests/testthat/_snaps/build-favicons.md | 5 +- tests/testthat/_snaps/build-github.md | 8 ++ tests/testthat/_snaps/build-home-authors.md | 2 +- tests/testthat/_snaps/build-home-citation.md | 8 ++ tests/testthat/_snaps/build-home-index.md | 41 ++++-- tests/testthat/_snaps/build-home.md | 46 ++++++- tests/testthat/_snaps/build-logo.md | 5 +- tests/testthat/_snaps/build-news.md | 31 +++-- tests/testthat/_snaps/build-redirects.md | 7 +- .../testthat/_snaps/build-reference-index.md | 46 ++++--- tests/testthat/_snaps/build-reference.md | 41 ++++-- tests/testthat/_snaps/check.md | 6 +- tests/testthat/_snaps/figure.md | 18 +++ tests/testthat/_snaps/init.md | 21 ++-- tests/testthat/_snaps/markdown.md | 5 +- tests/testthat/_snaps/navbar.md | 4 +- tests/testthat/_snaps/package.md | 6 +- tests/testthat/_snaps/rd-example.md | 8 ++ tests/testthat/_snaps/rd-html.md | 34 +++-- tests/testthat/_snaps/render.md | 3 +- tests/testthat/_snaps/rmarkdown.md | 28 +++-- tests/testthat/_snaps/sitrep.md | 22 +++- tests/testthat/_snaps/topics-external.md | 4 +- tests/testthat/_snaps/topics.md | 26 ++-- tests/testthat/_snaps/utils-yaml.md | 20 +-- tests/testthat/assets/articles/_pkgdown.yml | 0 tests/testthat/setup.R | 3 + tests/testthat/test-build-articles.R | 36 +++--- tests/testthat/test-build-favicons.R | 2 +- tests/testthat/test-build-github.R | 2 +- tests/testthat/test-build-home-authors.R | 1 + tests/testthat/test-build-home-citation.R | 2 +- tests/testthat/test-build-home-index.R | 11 +- tests/testthat/test-build-home.R | 9 +- tests/testthat/test-build-logo.R | 2 + tests/testthat/test-build-news.R | 5 +- tests/testthat/test-build-redirects.R | 5 +- tests/testthat/test-build-reference-index.R | 9 +- tests/testthat/test-build-reference.R | 25 ++-- tests/testthat/test-build-search-docs.R | 25 ++-- tests/testthat/test-check.R | 3 + tests/testthat/test-figure.R | 5 +- tests/testthat/test-init.R | 14 ++- tests/testthat/test-package.R | 6 +- tests/testthat/test-rd-example.R | 9 +- tests/testthat/test-rd-html.R | 15 ++- tests/testthat/test-render.R | 10 +- tests/testthat/test-rmarkdown.R | 7 +- tests/testthat/test-sitrep.R | 8 +- tests/testthat/test-utils-yaml.R | 20 +-- 93 files changed, 934 insertions(+), 527 deletions(-) create mode 100644 tests/testthat/_snaps/build-github.md create mode 100644 tests/testthat/_snaps/figure.md create mode 100644 tests/testthat/_snaps/rd-example.md create mode 100644 tests/testthat/assets/articles/_pkgdown.yml create mode 100644 tests/testthat/setup.R diff --git a/DESCRIPTION b/DESCRIPTION index 0ee5912bc..ae63aff58 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,7 +22,7 @@ Depends: Imports: bslib (>= 0.3.1), callr (>= 3.7.3), - cli, + cli (>= 3.6.1), desc (>= 1.4.0), digest, downlit (>= 0.4.0), diff --git a/NAMESPACE b/NAMESPACE index 744020aa2..7ae939ddb 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -112,7 +112,6 @@ export(autolink_html) export(build_article) export(build_articles) export(build_articles_index) -export(build_favicon) export(build_favicons) export(build_home) export(build_home_index) diff --git a/NEWS.md b/NEWS.md index f353ab075..cff5f58be 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # pkgdown (development version) +* Deprecated `build_favicon()` was removed (`build_favicons()` remains). +* Use [cli](https://github.com/r-lib/cli) to provide interactive feedback. * Preserve Markdown code blocks with class rmd from roxygen2 docs (@salim-b, #2298). * Avoid unwanted linebreaks from parsing `DESCRIPTION` (@salim-b, #2247). * Remove redundant entries in the documentation index when multiple explicit `@usage` tags are provided (@klmr, #2302) diff --git a/R/build-articles.R b/R/build-articles.R index 32c60612d..ceb406d93 100644 --- a/R/build-articles.R +++ b/R/build-articles.R @@ -177,7 +177,7 @@ build_articles <- function(pkg = ".", return(invisible()) } - rule("Building articles") + cli::cli_rule("Building articles") build_articles_index(pkg) purrr::walk( @@ -207,7 +207,9 @@ build_article <- function(name, # allow code sharing with building of the index. vig <- match(name, pkg$vignettes$name) if (is.na(vig)) { - stop("Can't find article called ", src_path(name), call. = FALSE) + cli::cli_abort( + "Can't find article {.file {name}}" + ) } input <- pkg$vignettes$file_in[vig] @@ -368,12 +370,9 @@ data_articles_index <- function(pkg = ".") { missing <- setdiff(pkg$vignettes$name, c(listed, pkg$package)) if (length(missing) > 0) { - abort( - paste0( - "Vignettes missing from index: ", - paste(missing, collapse = ", ") - ), - call. = FALSE + cli::cli_abort( + "{length(missing)} vignette{?s} missing from index: {.file {missing}}.", + call = caller_env() ) } @@ -385,7 +384,10 @@ data_articles_index <- function(pkg = ".") { data_articles_index_section <- function(section, pkg) { if (!set_contains(names(section), c("title", "contents"))) { - abort("Section must have components `title`, `contents`") + cli::cli_abort( + "Section must have components {.field title}, {.field contents}", + call = caller_env() + ) } # Match topics against any aliases @@ -424,7 +426,6 @@ default_articles_index <- function(pkg = ".") { return(NULL) } - print_yaml(list( list( title = tr_("All vignettes"), diff --git a/R/build-favicons.R b/R/build-favicons.R index f1e9fda82..066f4dfb7 100644 --- a/R/build-favicons.R +++ b/R/build-favicons.R @@ -19,20 +19,25 @@ build_favicons <- function(pkg = ".", overwrite = FALSE) { rlang::check_installed("openssl") pkg <- as_pkgdown(pkg) - rule("Building favicons") + cli::cli_rule("Building favicons") logo_path <- find_logo(pkg$src_path) if (is.null(logo_path)) { - stop("Can't find package logo PNG or SVG to build favicons.", call. = FALSE) + cli::cli_abort( + "Can't find package logo PNG or SVG to build favicons." + ) } if (has_favicons(pkg) && !overwrite) { - message("Favicons already exist in `pkgdown/`. Set `overwrite = TRUE` to re-create.") + cli::cli_inform(c( + "Favicons already exist in {.path pkgdown}", + "i" = "Set {.var overwrite = TRUE} to re-create." + )) return(invisible()) } - message("Building favicons with realfavicongenerator.net...") + cli::cli_inform("Building favicons with {.url https://realfavicongenerator.net} ...") logo <- readBin(logo_path, what = "raw", n = fs::file_info(logo_path)$size) @@ -66,18 +71,17 @@ build_favicons <- function(pkg = ".", overwrite = FALSE) { quiet = TRUE ) if (httr::http_error(resp)) { - stop("API request failed.", call. = FALSE) + cli::cli_abort("API request failed.", call = caller_env()) } content <- httr::content(resp) result <- content$favicon_generation_result if (!identical(result$result$status, "success")) { - stop( - "API request failed. ", " - Please submit bug report to ", - call. = FALSE - ) + cli::cli_abort(c( + "API request failed.", + "i" = "{.href [Please submit a bug report](https://github.com/r-lib/pkgdown/issues)}" + )) } tmp <- tempfile() @@ -93,27 +97,15 @@ build_favicons <- function(pkg = ".", overwrite = FALSE) { utils::unzip(tmp, exdir = path(pkg$src_path, "pkgdown", "favicon")) }, warning = function(e) { - abort("Your logo file couldn't be processed and may be corrupt.", parent = e) + cli::cli_abort("Your logo file couldn't be processed and may be corrupt.", parent = e) }, error = function(e) { - abort("Your logo file couldn't be processed and may be corrupt.", parent = e) + cli::cli_abort("Your logo file couldn't be processed and may be corrupt.", parent = e) }) invisible() } -#' Deprecated as of pkgdown 1.4.0 -#' @rdname build_favicons -#' @inheritParams build_favicons -#' @export -build_favicon <- function(pkg, overwrite) { - message( - "`build_favicon()` is deprecated as of pkgdown 1.4.0. ", - "Please use `build_favicons()` instead." - ) - build_favicons(pkg, overwrite) -} - copy_favicons <- function(pkg = ".") { pkg <- as_pkgdown(pkg) diff --git a/R/build-github.R b/R/build-github.R index 1aff9055a..76111e896 100644 --- a/R/build-github.R +++ b/R/build-github.R @@ -25,7 +25,7 @@ build_site_github_pages <- function(pkg = ".", pkg <- as_pkgdown(pkg, override = list(destination = dest_dir)) if (clean) { - rule("Cleaning files from old site", line = 1) + cli::cli_rule("Cleaning files from old site") clean_site(pkg) } @@ -36,7 +36,7 @@ build_site_github_pages <- function(pkg = ".", } build_github_pages <- function(pkg = ".") { - rule("Extra files for GitHub pages") + cli::cli_rule("Extra files for GitHub pages") pkg <- as_pkgdown(pkg) # Add .nojekyll since site is static HTML diff --git a/R/build-home-authors.R b/R/build-home-authors.R index dd1763ad9..87fef29a7 100644 --- a/R/build-home-authors.R +++ b/R/build-home-authors.R @@ -186,8 +186,8 @@ role_lookup <- function(abbr) { out <- unname(roles[abbr]) if (any(is.na(out))) { - missing <- paste0("'", abbr[is.na(out)], "'", collapse = ", ") - warn(paste0("Unknown MARC role abbreviation ", missing)) + missing <- abbr[is.na(out)] + cli::cli_warn("Unknown MARC role abbreviation{?s}: {.field {missing}}") out[is.na(out)] <- abbr[is.na(out)] } out diff --git a/R/build-home-index.R b/R/build-home-index.R index 3c39aca2a..86b99782a 100644 --- a/R/build-home-index.R +++ b/R/build-home-index.R @@ -64,13 +64,21 @@ data_home_sidebar <- function(pkg = ".") { if (length(html_path)) { if (!file.exists(html_path)) { - abort( - sprintf( - "Can't find file '%s' specified by %s.", - pkg$meta$home$sidebar$html, - pkgdown_field(pkg, c("home", "sidebar", "html")) - ) + rel_html_path <- fs::path_rel(html_path, pkg$src_path) + + msg_fld <- pkgdown_field( + pkg, c('home', 'sidebar', 'html'), fmt = TRUE, cfg = TRUE + ) + + cli::cli_abort( + c( + "Can't locate {.file {rel_html_path}}.", + x = paste0(msg_fld, " is misconfigured.") + ), + call = caller_env() ) + + } return(read_file(html_path)) } @@ -215,10 +223,10 @@ check_missing_images <- function(pkg, src_path, dst_path) { exists <- fs::file_exists(path(pkg$dst_path, rel_path)) if (any(!exists)) { - paths <- encodeString(rel_src[!exists], quote = "'") - warn(c( - paste0("Missing images in '", src_path, "': ", paste0(paths, collapse = ", ")), - i = "pkgdown can only use images in 'man/figures' and 'vignettes'" + paths <- rel_src[!exists] + cli::cli_warn(c( + "Missing images in {.file {src_path}}: {.file {paths}}", + i = "pkgdown can only use images in {.file man/figures} and {.file vignettes}" )) } } diff --git a/R/build-home-md.R b/R/build-home-md.R index 38c9d461e..f2309deae 100644 --- a/R/build-home-md.R +++ b/R/build-home-md.R @@ -22,7 +22,7 @@ build_home_md <- function(pkg) { } render_md <- function(pkg, filename) { - cat_line("Reading ", src_path(path_rel(filename, pkg$src_path))) + cli::cli_inform("Reading {src_path(path_rel(filename, pkg$src_path))}") body <- markdown_body(filename, strip_header = TRUE) path <- path_ext_set(basename(filename), "html") diff --git a/R/build-home.R b/R/build-home.R index c987490e9..6bfa26ce5 100644 --- a/R/build-home.R +++ b/R/build-home.R @@ -31,7 +31,7 @@ build_home <- function(pkg = ".", quiet = TRUE) { pkg <- section_init(pkg, depth = 0L, override = override) - rule("Building home") + cli::cli_rule("Building home") dir_create(pkg$dst_path) build_citation_authors(pkg) diff --git a/R/build-news.R b/R/build-news.R index 27a0fac7a..03643affb 100644 --- a/R/build-news.R +++ b/R/build-news.R @@ -78,7 +78,7 @@ build_news <- function(pkg = ".", if (!has_news(pkg$src_path)) return() - rule("Building news") + cli::cli_rule("Building news") dir_create(path(pkg$dst_path, "news")) switch(news_style(pkg$meta), @@ -151,7 +151,7 @@ data_news <- function(pkg = list()) { sections <- xml2::xml_find_all(xml, "./body/div") footnotes <- has_class(sections, "footnotes") if (any(footnotes)) { - warn("Footnotes in NEWS.md are not currently supported") + cli::cli_warn("Footnotes in NEWS.md are not currently supported") } sections <- sections[!footnotes] @@ -160,11 +160,14 @@ data_news <- function(pkg = list()) { xml2::xml_name() ulevels <- unique(levels) if (!identical(ulevels, "h1") && !identical(ulevels, "h2")) { - abort(c( - "Invalid NEWS.md: inconsistent use of section headings.", - i = "Top-level headings must be either all

or all

.", - i = "See ?build_news for more details." - )) + cli::cli_abort( + c( + "Invalid NEWS.md: inconsistent use of section headings.", + i = "Top-level headings must be either all

or all

.", + i = "See {.help pkgdown::build_news} for more details." + ), + call = caller_env() + ) } if (ulevels == "h1") { # Bump every heading down a level so to get a single

for the page title diff --git a/R/build-redirects.R b/R/build-redirects.R index 408ff09f0..9bd64871f 100644 --- a/R/build-redirects.R +++ b/R/build-redirects.R @@ -11,9 +11,13 @@ build_redirects <- function(pkg = ".", return(invisible()) } - rule("Building redirects") + cli::cli_rule("Building redirects") if (is.null(pkg$meta$url)) { - abort(sprintf("%s required to generate redirects", pkgdown_field(pkg, "url"))) + msg_fld <- pkgdown_field(pkg, "url", cfg = TRUE, fmt = TRUE) + cli::cli_abort( + paste0(msg_fld, " is required to generate redirects."), + call = caller_env() + ) } purrr::iwalk( @@ -25,12 +29,13 @@ build_redirects <- function(pkg = ".", build_redirect <- function(entry, index, pkg) { if (!is.character(entry) || length(entry) != 2) { - abort( - sprintf( - "Entry %s in %s must be a character vector of length 2.", - index, - pkgdown_field(pkg, "redirects") - ) + msg_fld <- pkgdown_field(pkg, "url", cfg = TRUE, fmt = TRUE) + cli::cli_abort( + c( + "Entry {.emph {index}} must be a character vector of length 2.", + x = paste0("Edit ", msg_fld, ".") + ), + call = caller_env() ) } diff --git a/R/build-reference-index.R b/R/build-reference-index.R index d8e4df7e5..1e0c3dfce 100644 --- a/R/build-reference-index.R +++ b/R/build-reference-index.R @@ -69,16 +69,12 @@ check_all_characters <- function(contents, index, pkg) { any_null <- any(null) if (any_null) { - abort( + msg_fld <- pkgdown_field(pkg, "reference", cfg = TRUE, fmt = TRUE) + cli::cli_abort( c( - sprintf( - "Item %s in section %s in %s is empty.", - toString(which(null)), - index, - pkgdown_field(pkg, "reference") - ), - i = "Either delete the empty line or add a function name." - ) + "Item {.field {which(null)}} in section {index} is empty.", + x = paste0("Delete the empty line or add function name to ", msg_fld, ".") + ), call = caller_env() ) } @@ -89,16 +85,12 @@ check_all_characters <- function(contents, index, pkg) { return(invisible()) } - abort( + msg_fld <- pkgdown_field(pkg, "reference", cfg = TRUE, fmt = TRUE) + cli::cli_abort( c( - sprintf( - "Item %s in section %s in %s must be a character.", - toString(which(not_char)), - index, - pkgdown_field(pkg, "reference") - ), - i = "You might need to add '' around e.g. - 'N' or - 'off'." - ) + "Item {.field {which(not_char)}} in section {index} must be a character.", + x = paste0("You might need to add '' around e.g. - 'N' or - 'off' to ", msg_fld, ".") + ), call = caller_env() ) } diff --git a/R/build-reference.R b/R/build-reference.R index add462c13..66a62e23e 100644 --- a/R/build-reference.R +++ b/R/build-reference.R @@ -161,12 +161,16 @@ build_reference <- function(pkg = ".", topics = NULL) { pkg <- section_init(pkg, depth = 1L, override = override) - if (!missing(document)) { - warning("`document` is deprecated. Please use `devel` instead.", call. = FALSE) + if (document != "DEPRECATED") { + lifecycle::deprecate_warn( + "1.4.0", + "build_site(document)", + details = "build_site(devel)" + ) devel <- document } - rule("Building function reference") + cli::cli_rule("Building function reference") build_reference_index(pkg) copy_figures(pkg) @@ -274,7 +278,7 @@ build_reference_topic <- function(topic, if (lazy && !out_of_date(in_path, out_path)) return(invisible()) - cat_line("Reading ", src_path("man", topic$file_in)) + cli::cli_inform("Reading {src_path(path('man', topic$file_in))}") data <- withCallingHandlers( data_reference_topic( @@ -284,11 +288,7 @@ build_reference_topic <- function(topic, run_dont_run = run_dont_run ), error = function(err) { - msg <- c( - paste0("Failed to parse Rd in ", topic$file_in), - i = err$message - ) - abort(msg, parent = err) + cli::cli_abort("Failed to parse Rd in {.file {topic$file_in}}", parent = err) } ) diff --git a/R/build-search-docs.R b/R/build-search-docs.R index cb61ed127..012b93986 100644 --- a/R/build-search-docs.R +++ b/R/build-search-docs.R @@ -45,7 +45,7 @@ build_sitemap <- function(pkg = ".") { } xml_path <- path(pkg$dst_path, "sitemap.xml") - cat_line("Writing ", dst_path(path_rel(xml_path, pkg$dst_path))) + cli::cli_inform("Writing {dst_path(path_rel(xml_path, pkg$dst_path))}") xml2::write_xml(doc, file = xml_path) @@ -86,7 +86,7 @@ url_node <- function(url) { build_search <- function(pkg = ".", override = list()) { pkg <- section_init(pkg, depth = 1L, override = override) - rule("Building search index") + cli::cli_rule("Building search index") search_index <- build_search_index(pkg) jsonlite::write_json( search_index, diff --git a/R/build-tutorials.R b/R/build-tutorials.R index 8138c23cd..d9b6679bd 100644 --- a/R/build-tutorials.R +++ b/R/build-tutorials.R @@ -35,7 +35,7 @@ build_tutorials <- function(pkg = ".", override = list(), preview = NA) { return(invisible()) } - rule("Building tutorials") + cli::cli_rule("Building tutorials") dir_create(path(pkg$dst_path, "tutorials")) data <- purrr::transpose(tutorials) diff --git a/R/build.R b/R/build.R index a44a0a99a..f455f9b31 100644 --- a/R/build.R +++ b/R/build.R @@ -327,14 +327,18 @@ build_site <- function(pkg = ".", document = "DEPRECATED") { pkg <- as_pkgdown(pkg, override = override) - if (!missing(document)) { - warning("`document` is deprecated. Please use `devel` instead.", call. = FALSE) + if (document != "DEPRECATED") { + lifecycle::deprecate_warn( + "1.4.0", + "build_site(document)", + details = "build_site(devel)" + ) devel <- document } if (install) { withr::local_temp_libpaths() - rule("Installing package into temporary library") + cli::cli_rule("Installing package {.pkg {pkg$package}} into temporary library") # Keep source, so that e.g. pillar can show the source code # of its functions in its articles withr::with_options( @@ -404,6 +408,8 @@ build_site_external <- function(pkg = ".", timeout = getOption('pkgdown.timeout', Inf) ) + cli::cli_rule(paste0("Finished building pkgdown site for package ", cli::col_blue(pkg$package))) + preview_site(pkg, preview = preview) invisible() } @@ -420,9 +426,9 @@ build_site_local <- function(pkg = ".", pkg <- section_init(pkg, depth = 0, override = override) - rule("Building pkgdown site", line = "=") - cat_line("Reading from: ", src_path(path_abs(pkg$src_path))) - cat_line("Writing to: ", dst_path(path_abs(pkg$dst_path))) + cli::cli_rule(paste0("Building pkgdown site for package ", cli::col_blue(pkg$package))) + cli::cli_inform("Reading from: {src_path(path_abs(pkg$src_path))}") + cli::cli_inform("Writing to: {dst_path(path_abs(pkg$dst_path))}") init_site(pkg) @@ -447,6 +453,6 @@ build_site_local <- function(pkg = ".", build_search(pkg, override = override) } - rule("DONE", line = "=") + cli::cli_rule(paste0("Finished building pkgdown site for package ", cli::col_blue(pkg$package))) preview_site(pkg, preview = preview) } diff --git a/R/check.R b/R/check.R index 0cfb38a05..49a1154df 100644 --- a/R/check.R +++ b/R/check.R @@ -12,6 +12,6 @@ check_pkgdown <- function(pkg = ".") { data_articles_index(pkg) data_reference_index(pkg) - inform("No problems found") + cli::cli_alert_success("No problems found in {.file {pkgdown_config_relpath(pkg)}}") } diff --git a/R/clean.R b/R/clean.R index d70d02ad9..6116f3ae8 100644 --- a/R/clean.R +++ b/R/clean.R @@ -2,11 +2,17 @@ #' #' Delete all files in `docs/` (except for `CNAME`). #' +#' @param quiet If `TRUE`, suppresses a message. #' @inheritParams build_site #' @export -clean_site <- function(pkg = ".") { +clean_site <- function(pkg = ".", quiet = FALSE) { + pkg <- as_pkgdown(pkg) + if (!quiet) { + cli::cli_inform("Cleaning {.pkg {pkg$package}} pkgdown docs from {.path {pkg$dst_path}}") + } + if (!dir_exists(pkg$dst_path)) return(invisible()) top_level <- dir_ls(pkg$dst_path) diff --git a/R/deploy-site.R b/R/deploy-site.R index fab5d892c..3a3899019 100644 --- a/R/deploy-site.R +++ b/R/deploy-site.R @@ -43,31 +43,31 @@ deploy_site_github <- function( repo_slug = Sys.getenv("TRAVIS_REPO_SLUG", "")) { rlang::check_installed("openssl") if (!nzchar(tarball)) { - stop("No built tarball detected, please provide the location of one with `tarball`", call. = FALSE) + cli::cli_abort("No built tarball detected, please provide the location of one with {.var tarball}", call = caller_env()) } if (!nzchar(ssh_id)) { - stop("No deploy key found, please setup with `travis::use_travis_deploy()`", call. = FALSE) + cli::cli_abort("No deploy key found, please setup with {.fn travis::use_travis_deploy}", call = caller_env()) } if (!nzchar(repo_slug)) { - stop("No repo detected, please supply one with `repo_slug`", call. = FALSE) + cli::cli_abort("No repo detected, please supply one with {.var repo_slug}", call = caller_env()) } - rule("Deploying site", line = 2) + cli::cli_alert("Deploying site to GitHub") if (install) { - rule("Installing package", line = 1) + cli::cli_inform("Installing package") callr::rcmd("INSTALL", tarball, show = verbose, fail_on_status = TRUE) } ssh_id_file <- "~/.ssh/id_rsa" - rule("Setting up SSH id", line = 1) - cat_line("Copying private key to: ", ssh_id_file) + cli::cli_inform("Setting up SSH id") + cli::cli_inform("Copying private key to {.file ssh_id_file}") write_lines(rawToChar(openssl::base64_decode(ssh_id)), ssh_id_file) - cat_line("Setting private key permissions to 0600") + cli::cli_inform("Setting private key permissions to 0600") fs::file_chmod(ssh_id_file, "0600") - cat_line("Setting remote to use the ssh url") + cli::cli_inform("Setting remote to use the ssh url") git("remote", "set-url", "origin", sprintf("git@%s:%s.git", host, repo_slug)) @@ -79,7 +79,7 @@ deploy_site_github <- function( ... ) - rule("Deploy completed", line = 2) + cli::cli_alert_success("Deploy completed") } #' Build and deploy a site locally @@ -158,13 +158,14 @@ deploy_to_branch <- function(pkg = ".", git_has_remote_branch <- function(remote, branch) { has_remote_branch <- git("ls-remote", "--quiet", "--exit-code", remote, branch, echo = FALSE, echo_cmd = FALSE, error_on_status = FALSE)$status == 0 } + git_current_branch <- function() { branch <- git("rev-parse", "--abbrev-ref", "HEAD", echo = FALSE, echo_cmd = FALSE)$stdout sub("\n$", "", branch) } github_worktree_add <- function(dir, remote, branch) { - rule("Adding worktree", line = 1) + cli::cli_inform("Adding worktree") git("worktree", "add", "--track", "-B", branch, @@ -174,7 +175,7 @@ github_worktree_add <- function(dir, remote, branch) { } github_worktree_remove <- function(dir) { - rule("Removing worktree", line = 1) + cli::cli_inform("Removing worktree") git("worktree", "remove", dir) } @@ -182,13 +183,13 @@ github_push <- function(dir, commit_message, remote, branch) { # force execution before changing working directory force(commit_message) - rule("Commiting updated site", line = 1) + cli::cli_inform("Commiting updated site") withr::with_dir(dir, { git("add", "-A", ".") git("commit", "--allow-empty", "-m", commit_message) - rule("Deploying to GitHub Pages", line = 1) + cli::cli_alert("Deploying to GitHub Pages") git("remote", "-v") git("push", "--force", remote, paste0("HEAD:", branch)) }) @@ -200,8 +201,8 @@ git <- function(..., echo_cmd = TRUE, echo = TRUE, error_on_status = TRUE) { construct_commit_message <- function(pkg, commit = ci_commit_sha()) { pkg <- as_pkgdown(pkg) - - sprintf("Built site for %s: %s@%s", pkg$package, pkg$version, substr(commit, 1, 7)) + commit <- sprintf("%s@%s", pkg$version, substr(commit, 1, 7)) + cli::cli_alert_success("Built site for {cli::col_yellow(pkg$package)}: {.emph {cli::col_green(commit)}}") } ci_commit_sha <- function() { diff --git a/R/figure.R b/R/figure.R index 280ae73a4..10ceb864e 100644 --- a/R/figure.R +++ b/R/figure.R @@ -136,12 +136,12 @@ match_fun <- function(x) { f <- eval(e, globalenv()) if (!is.function(f)) { - stop("`x` must evaluate to a function", call. = FALSE) + cli::cli_abort("{.var x} must evaluate to a function", call = caller_env()) } f } else { - stop("`x` must be a function or string", call. = FALSE) + cli::cli_abort("{.var x} must be a function or string", call = caller_env()) } } @@ -157,6 +157,6 @@ fun_name <- function(x) { } else if (is_call(expr, "::")) { as.character(expr[[3]]) } else { - stop("Unknown input", call. = FALSE) + cli::cli_abort("Unknown input", call = caller_env()) } } diff --git a/R/init.R b/R/init.R index bff37086a..8946dfd86 100644 --- a/R/init.R +++ b/R/init.R @@ -24,10 +24,13 @@ init_site <- function(pkg = ".") { pkg <- as_pkgdown(pkg) if (is_non_pkgdown_site(pkg$dst_path)) { - stop(dst_path(pkg$dst_path), " is non-empty and not built by pkgdown", call. = FALSE) + cli::cli_abort( + "{.file {pkg$dst_path}} is non-empty and not built by pkgdown", + call = caller_env() + ) } - rule("Initialising site") + cli::cli_rule("Initialising site") dir_create(pkg$dst_path) copy_assets(pkg) diff --git a/R/markdown.R b/R/markdown.R index c0ce0b7dd..5574343fe 100644 --- a/R/markdown.R +++ b/R/markdown.R @@ -16,12 +16,9 @@ markdown_text_inline <- function(text, where = "", ...) { children <- xml2::xml_children(xml2::xml_find_first(html, ".//body")) if (length(children) > 1) { - abort( - sprintf( - "Can't use a block element in %s, need an inline element: \n%s", - where, - text - ) + cli::cli_abort( + "Can't use a block element in {.var {where}}, need an inline element: {.var {text}}", + call = caller_env() ) } diff --git a/R/package.R b/R/package.R index 82c9c83f6..415baf2ef 100644 --- a/R/package.R +++ b/R/package.R @@ -13,7 +13,10 @@ as_pkgdown <- function(pkg = ".", override = list()) { } if (!dir_exists(pkg)) { - stop("`pkg` is not an existing directory", call. = FALSE) + cli::cli_abort( + "{.file {pkg}} is not an existing directory", + call = caller_env() + ) } desc <- read_desc(pkg) @@ -89,28 +92,28 @@ is_pkgdown <- function(x) inherits(x, "pkgdown") read_desc <- function(path = ".") { path <- path(path, "DESCRIPTION") if (!file_exists(path)) { - stop("Can't find DESCRIPTION", call. = FALSE) + cli::cli_abort("Can't find {.file DESCRIPTION}", call = caller_env()) } desc::description$new(path) } -check_bootstrap_version <- function(version, pkg = list()) { +check_bootstrap_version <- function(version, pkg) { if (is.null(version)) { 3 } else if (version %in% c(3, 5)) { version } else if (version == 4) { - warn("`bootstrap: 4` no longer supported; using `bootstrap: 5` instead") + cli::cli_warn("{.var bootstrap: 4} no longer supported, using {.var bootstrap: 5} instead") 5 } else { - abort(c( - "Boostrap version must be 3 or 5.", - x = sprintf( - "You specified a value of %s in %s.", - version, - pkgdown_field(pkg, c("template", "bootstrap")) - ) - )) + msg_fld <- pkgdown_field(pkg, c("template", "bootstrap"), cfg = TRUE, fmt = TRUE) + cli::cli_abort( + c( + "Boostrap version must be 3 or 5.", + x = paste0("You set a value of {.val {version}} to ", msg_fld, ".") + ), + call = caller_env() + ) } } @@ -290,12 +293,14 @@ check_unique_article_paths <- function(file_in, file_out) { same_out_bullets <- purrr::map_chr(file_out_dup, function(f_out) { src_files <- src_path(file_in[which(file_out == f_out)]) src_files <- paste(src_files, collapse = " and ") - sprintf("%s both create %s", src_files, dst_path(f_out)) }) names(same_out_bullets) <- rep_len("x", length(same_out_bullets)) - rlang::abort(c( - "Rendered articles must have unique names. Rename or relocate one of the following source files:", - same_out_bullets - )) + cli::cli_abort( + c( + "Rendered articles must have unique names. Rename or relocate:", + same_out_bullets + ), + call = caller_env() + ) } diff --git a/R/preview.R b/R/preview.R index 7129d5ce4..130392896 100644 --- a/R/preview.R +++ b/R/preview.R @@ -11,7 +11,7 @@ preview_site <- function(pkg = ".", path = ".", preview = NA) { } if (preview) { - rule("Previewing site") + cli::cli_alert_info("Previewing site") utils::browseURL(path(pkg$dst_path, path, "index.html")) } diff --git a/R/rd-example.R b/R/rd-example.R index e1fd10a7a..ee54d2cf9 100644 --- a/R/rd-example.R +++ b/R/rd-example.R @@ -29,7 +29,7 @@ run_examples <- function(x, code <- flatten_ex(x, run_dont_run = run_dont_run) if (!can_parse(code)) { - warning("Failed to parse example for topic '", topic, "'", call. = FALSE) + cli::cli_warn("Failed to parse example for topic {.val {topic}}") return("") } @@ -48,13 +48,17 @@ process_conditional_examples <- function(rd) { grepl("# examplesIf$", x[[1]]) })) if (length(which_exif) == 0) return(rd) - if (length(which_exif) %% 2 != 0) stop("@examplesIf error, not closed?") + if (length(which_exif) %% 2 != 0) { + cli::cli_abort("@examplesIf error, not closed?", call = caller_env()) + } remove <- integer() modes <- c("begin", "end") for (idx in which_exif) { if (rd[[idx]] != "}) # examplesIf") { # Start of @examplesIf - if (modes[1] == "end") stop("@examplesIf error, not closed?") + if (modes[1] == "end") { + cli::cli_abort("@examplesIf error, not closed?", call = caller_env()) + } cond_expr <- parse(text = paste0(rd[[idx]], "\n})"))[[1]][[2]] cond <- eval(cond_expr) if (isTRUE(cond)) { @@ -64,10 +68,8 @@ process_conditional_examples <- function(rd) { is_false <- cond_expr_str == "FALSE" if (!is_false) { new_cond <- paste0("if (FALSE) { # ", cond_expr_str) - warning( - "@examplesIf condition `", - cond_expr_str, - "` is FALSE" + cli::cli_warn( + "@examplesIf condition {.val {cond_expr_str}} is {.val FALSE}" ) } else { new_cond <- "if (FALSE) {" @@ -76,7 +78,9 @@ process_conditional_examples <- function(rd) { } } else { # End of @examplesIf - if (modes[1] == "begin") stop("@examplesIf error, closed twice?") + if (modes[1] == "begin") { + cli::cli_abort("@examplesIf error, closed twice?", call = caller_env()) + } if (isTRUE(cond)) { remove <- c(remove, idx, idx + 1L) } else { @@ -110,11 +114,12 @@ as_example.TEXT <- as_example.RCODE #' @export as_example.COMMENT <- function(x, run_dont_run = FALSE) { if (grepl("^%[^ ]*%", x)) { - warning( - "In the examples, ", unclass(x), "\n", - "is an Rd comment: did you mean ", gsub("%", "\\\\%", x), " ?", - call. = FALSE - ) + meant <- gsub("%", "\\\\%", x) + xun <- unclass(x) + cli::cli_warn(c( + "In the examples, {.val {xun}} is an Rd comment", + "x" = "did you mean {.val {meant}}?" + )) } "" } @@ -155,8 +160,8 @@ block_tag_to_comment <- function(tag, x, run_dont_run = FALSE) { #' @export as_example.tag <- function(x, run_dont_run = FALSE) { - warning("Unknown tag: ", paste(class(x), collapse = "/"), call. = FALSE) - "" + untag <- paste(class(x), collapse = "/") + cli::cli_warn("Unknown tag: {.val {untag}}") } #' @export diff --git a/R/rd-html.R b/R/rd-html.R index 6e00c3b93..712f97501 100644 --- a/R/rd-html.R +++ b/R/rd-html.R @@ -130,7 +130,7 @@ as_html.tag_deqn <- function(x, ...) { as_html.tag_url <- function(x, ...) { if (length(x) != 1) { if (length(x) == 0) { - msg <- "Check for empty \\url{} tags." + msg <- "Check for empty \\url{{}} tags." } else { msg <- "This may be caused by a \\url tag that spans a line break." } @@ -229,7 +229,10 @@ as_html.tag_Sexpr <- function(x, ...) { text = as.character(res), rd = flatten_text(rd_text(as.character(res))), hide = "", - stop("\\Sexpr{result=", results, "} not yet supported", call. = FALSE) + cli::cli_abort( + "\\\\Sexpr{{result={results}}} not yet supported", + call = caller_env() + ) ) } @@ -510,7 +513,7 @@ as_html.tag <- function(x, ...) { if (identical(class(x), "tag")) { flatten_text(x, ...) } else { - message("Unknown tag: ", paste(class(x), collapse = "/")) + cli::cli_inform("Unknown tag: ", paste(class(x), collapse = "/")) "" } } @@ -566,10 +569,9 @@ parse_opts <- function(string) { } stop_bad_tag <- function(tag, msg = NULL) { - abort(c( - paste0("Failed to parse \\", tag, "{}."), - i = msg - )) + bad_tag <- paste0("\\", tag, "{}") + msg_abort <- 'Failed to parse tag {.val {bad_tag}}.' + cli::cli_abort(c(msg_abort, i = msg), call = NULL) } is_newline <- function(x, trim = FALSE) { diff --git a/R/render.R b/R/render.R index fefb96988..81ebb5a00 100644 --- a/R/render.R +++ b/R/render.R @@ -148,47 +148,51 @@ data_open_graph <- function(pkg = ".") { check_open_graph <- function(og) { if (!is.list(og)) { - abort(paste("`opengraph` must be a list, not", friendly_type_of(og))) + fog <- friendly_type_of(og) + cli::cli_abort( + "{.var opengraph} must be a list, not {.val fog}.", + call = caller_env() + ) } supported_fields <- c("image", "twitter") unsupported_fields <- setdiff(names(og), supported_fields) if (length(unsupported_fields)) { - warn(paste0( - "Unsupported `opengraph` field(s): ", - paste(unsupported_fields, collapse = ", ") - )) + cli::cli_warn( + "Unsupported {.var opengraph} field{?s}: {.val unsupported_fields}." + ) } if ("twitter" %in% names(og)) { if (is.character(og$twitter) && length(og$twitter) == 1 && grepl("^@", og$twitter)) { - abort(paste( - "The `opengraph: twitter` option must be a list. Did you mean this?", - "opengraph:", - " twitter:", - paste(" creator:", og$twitter), - sep = "\n" - )) + cli::cli_abort( + "The {.var opengraph: twitter} option must be a list.", + call = caller_env() + ) } if (!is.list(og$twitter)) { - abort("The `opengraph: twitter` option must be a list.") + cli::cli_abort( + "The {.var opengraph: twitter} option must be a list.", + call = caller_env() + ) } if (is.null(og$twitter$creator) && is.null(og$twitter$site)) { - abort( - "The `opengraph: twitter` option must include either 'creator' or 'site'." + cli::cli_abort( + "{.var opengraph: twitter} must include either {.val creator} or {.val site}.", + call = caller_env() ) } } if ("image" %in% names(og)) { if (is.character(og$image) && length(og$image) == 1) { - abort(paste( - "The `opengraph: image` option must be a list. Did you mean this?", - "opengraph", - " image:", - paste(" src:", og$image), - sep = "\n" - )) + cli::cli_abort( + "The {.var opengraph: image} option must be a list.", + call = caller_env() + ) } if (!is.list(og$image)) { - abort("The `opengraph: image` option must be a list.") + cli::cli_abort( + "The {.var opengraph: image} option must be a list.", + call = caller_env() + ) } } og[intersect(supported_fields, names(og))] @@ -208,7 +212,7 @@ write_if_different <- function(pkg, contents, path, quiet = FALSE, check = TRUE) if (check && !made_by_pkgdown(full_path)) { if (!quiet) { - message("Skipping '", path, "': not generated by pkgdown") + cli::cli_inform("Skipping {.file {{path}}: not generated by pkgdown") } return(FALSE) } @@ -221,9 +225,9 @@ write_if_different <- function(pkg, contents, path, quiet = FALSE, check = TRUE) } if (!quiet) { - href <- paste0("ide:run:pkgdown::preview_page('", path_rel(full_path, pkg$dst_path), "')") - cat_line("Writing ", cli::style_hyperlink(dst_path(path), href)) + cli::cli_inform("Writing {dst_path(path)}") } + write_lines(contents, path = full_path) TRUE } diff --git a/R/rmarkdown.R b/R/rmarkdown.R index f13241862..4f1b8308f 100644 --- a/R/rmarkdown.R +++ b/R/rmarkdown.R @@ -7,10 +7,10 @@ render_rmarkdown <- function(pkg, input, output, ..., copy_images = TRUE, quiet output_path <- path_abs(output, pkg$dst_path) if (!file_exists(input_path)) { - stop("Can't find ", src_path(input), call. = FALSE) + cli::cli_abort("Can't find {src_path(input).", call = caller_env()) } - cat_line("Reading ", src_path(input)) + cli::cli_inform("Reading {src_path(input)}") digest <- file_digest(output_path) args <- list( @@ -38,10 +38,13 @@ render_rmarkdown <- function(pkg, input, output, ..., copy_images = TRUE, quiet ) ), error = function(cnd) { - rule("RMarkdown error") - cat(gsub("\r", "", cnd$stderr, fixed = TRUE)) - rule() - abort("Failed to render RMarkdown", parent = cnd) + cli::cli_abort( + c( + "Failed to render RMarkdown document.", + x = gsub("\r", "", cnd$stderr, fixed = TRUE) + ), + parent = cnd + ) } ) @@ -55,7 +58,7 @@ render_rmarkdown <- function(pkg, input, output, ..., copy_images = TRUE, quiet } if (digest != file_digest(output_path)) { href <- paste0("ide:run:pkgdown::preview_page('", path_rel(output_path, pkg$dst_path), "')") - cat_line("Writing ", cli::style_hyperlink(dst_path(output), href)) + cli::cli_inform("Writing {cli::style_hyperlink(dst_path(output), href)}") } # Copy over images needed by the document diff --git a/R/sitrep.R b/R/sitrep.R index ca123c8cd..e67ca7d45 100644 --- a/R/sitrep.R +++ b/R/sitrep.R @@ -13,18 +13,30 @@ #' @export #' pkgdown_sitrep <- function(pkg = ".") { - pkg_dir <- pkg - pkg <- as_pkgdown(pkg_dir) + pkg <- as_pkgdown(pkg) + warns <- c() + if (is.null(pkg$meta[["url"]])) { - cat(sprintf("* %s not configured.", pkgdown_field(pkg, "url"))) + msg_fld <- pkgdown_field(pkg, "url", cfg = TRUE, fmt = TRUE) + warns <- c(warns, x = paste0(msg_fld, "is misconfigured. See {.vignette pkgdown::metatdata}.")) + } + + desc_urls <- pkg$desc$get_urls() + desc_urls <- sub("/$", "", desc_urls) + if (length(desc_urls) == 0 || !pkg$meta[["url"]] %in% desc_urls) { + warns <- c(warns, x = "{.file DESCRIPTION} {.field URL} is empty.") + } + + if (length(warns) == 0) { + cli::cli_alert_success("pkgdown situation report: {.emph {cli::col_green('all clear')}}") + cli::cli_inform("{.emph Double-check the following URLs:}") + cli::cli_inform("{.file {pkgdown_config_relpath(pkg)}} contains URL {.url {pkg$meta['url']}}") + cli::cli_inform("{.file DESCRIPTION} contains URL{?s} {.url {desc_urls}}") } else { - urls <- desc::desc(pkg_dir)$get_urls() - urls <- sub("/$", "", urls) - if (!pkg$meta[["url"]] %in% urls) { - cat("* URL missing from the DESCRIPTION URL field.") - } else { - cat("All good :-)") - } + cli::cli_warn(c( + "pkgdown situation report: {.emph {cli::col_red('configuration error')}}", + warns + )) } invisible() diff --git a/R/templates.R b/R/templates.R index 02376ff73..54816e4e5 100644 --- a/R/templates.R +++ b/R/templates.R @@ -6,7 +6,11 @@ find_template <- function(type, name, ext = ".html", pkg = ".") { existing <- paths[file_exists(paths)] if (length(existing) == 0) { - abort(paste0("Can't find template for ", type, "-", name, ".")) + tname <- paste0(type, "-", name) + cli::cli_abort( + "Can't find template for {.val {tname}}.", + call = caller_env() + ) } existing[[1]] } @@ -43,7 +47,10 @@ templates_dir <- function(pkg = list()) { if (!is.null(template$path)) { # Directory specified in yaml doesn't exist, so eagerly error if (!dir_exists(template$path)) { - abort(paste0("Can not find templates path ", src_path(template$path))) + cli::cli_abort( + "Can't find templates path: {src_path(template$path)}", + call = caller_env() + ) } path_abs(template$path, start = pkg$src_path) } else if (!is.null(template$package)) { diff --git a/R/test.R b/R/test.R index 800de5117..e63affb14 100644 --- a/R/test.R +++ b/R/test.R @@ -89,7 +89,7 @@ NULL #' @family tests #' @examples #' \dontrun{ -#' stop("This is an error!", call. = FALSE) +#' abort("This is an error!") #' } #' #' # Inline \donttest is silently ommitted diff --git a/R/theme.R b/R/theme.R index 197180281..eb7e3f142 100644 --- a/R/theme.R +++ b/R/theme.R @@ -12,7 +12,10 @@ build_bslib <- function(pkg = ".") { data_deps <- function(pkg, depth) { if (!file.exists(data_deps_path(pkg))) { - abort("Run pkgdown::init_site() first.") + cli::cli_abort( + "Run {.fn pkgdown::init_site} first.", + call = caller_env() + ) } deps_path <- paste0(up_path(depth), "deps") @@ -56,10 +59,10 @@ bs_theme_rules <- function(pkg) { theme <- purrr::pluck(pkg, "meta", "template", "theme", .default = "arrow-light") theme_path <- path_pkgdown("highlight-styles", paste0(theme, ".scss")) if (!file_exists(theme_path)) { - abort(c( - paste0("Unknown theme '", theme, "'"), - i = paste0("Valid themes are: ", paste0(highlight_styles(), collapse = ", ")) - )) + cli::cli_abort(c( + "Unknown theme: {.val {theme}}", + i = "Valid themes are: {.val highlight_styles()}" + ), call = caller_env()) } paths <- c(paths, theme_path) @@ -101,15 +104,16 @@ check_bootswatch_theme <- function(bootswatch_theme, bs_version, pkg) { } else if (bootswatch_theme %in% bslib::bootswatch_themes(bs_version)) { bootswatch_theme } else { - abort( + cli::cli_abort(c( sprintf( - "Can't find Bootswatch theme '%s' (%s) for Bootstrap version '%s' (%s).", + "Can't find Bootswatch theme {.val %s} ({.field %s}) for Bootstrap version {.val %s} ({.field %s}).", bootswatch_theme, pkgdown_field(pkg, c("template", "bootswatch")), bs_version, pkgdown_field(pkg, c("template", "bootstrap")) - ) - ) + ), + x = "Edit settings in {.file {pkgdown_config_relpath(pkg)}}" + ), call = caller_env()) } } diff --git a/R/topics-external.R b/R/topics-external.R index b51091992..0bd56bd90 100644 --- a/R/topics-external.R +++ b/R/topics-external.R @@ -29,7 +29,11 @@ get_rd_from_help <- function(package, alias) { help <- utils::help((alias), (package)) if (length(help) == 0) { - abort(sprintf("Could not find documentation for %s::%s", package, alias)) + fun <- paste0(package, "::", alias) + cli::cli_abort( + "Could not find documentation for {.fn {fun}}.", + call = caller_env() + ) return() } diff --git a/R/topics.R b/R/topics.R index e7ffb1a51..b135eb3bc 100644 --- a/R/topics.R +++ b/R/topics.R @@ -10,7 +10,10 @@ select_topics <- function(match_strings, topics, check = FALSE) { # If none of the specified topics have a match, return no topics if (purrr::every(indexes, is_empty)) { if (check) { - abort("No topics matched in '_pkgdown.yml'. No topics selected.") + cli::cli_abort( + "No topics matched in {.file _pkgdown.yml}. No topics selected.", + call = caller_env() + ) } return(integer()) } @@ -51,7 +54,10 @@ all_sign <- function(x, text) { } } - stop("Must be all negative or all positive: ", text, call. = FALSE) + cli::cli_abort( + "Must be all negative or all positive: {.val {text}}", + call = caller_env() + ) } match_env <- function(topics) { @@ -170,11 +176,8 @@ match_eval <- function(string, env) { } topic_must <- function(message, topic, ..., call = NULL) { - abort( - c( - paste0("In '_pkgdown.yml', topic must ", message), - x = paste0("Not ", encodeString(topic, quote = "'")) - ), + cli::cli_abort( + "In {.file _pkgdown.yml}, topic must {message}, not {.val {topic}}.", ..., call = call ) @@ -186,6 +189,7 @@ section_topics <- function(match_strings, topics, src_path) { topics <- rbind(topics, ext_topics(ext_strings)) selected <- topics[select_topics(match_strings, topics), , ] + tibble::tibble( name = selected$name, path = selected$file_out, diff --git a/R/usage.R b/R/usage.R index bec8fd162..aa88be084 100644 --- a/R/usage.R +++ b/R/usage.R @@ -28,7 +28,9 @@ parse_usage <- function(x) { parse_exprs(r) }, error = function(e) { - warning("Failed to parse usage:\n", r, call. = FALSE, immediate. = TRUE) + cli::cli_warn( + "Failed to parse usage: {.code {r}}" + ) list() } ) @@ -83,7 +85,11 @@ usage_type <- function(x) { out } else { - stop("Unknown type: ", typeof(x), " (in ", as.character(x), ")", call. = FALSE) + untype <- paste0(typeof(x), " (in ", as.character(x), ")") + cli::cli_abort( + "Unknown type: {.val {untype}}", + call = caller_env() + ) } } @@ -127,7 +133,10 @@ fun_info <- function(fun) { name = call_name(fun) ) } else { - stop("Unknown call: ", as.character(x[[1]])) + cli::cli_abort( + "Unknown call: {.val {as.character(x[[1]])}}", + call = caller_env() + ) } } else { list( @@ -158,7 +167,10 @@ usage_code.NULL <- function(x) character() #' @export usage_code.tag <- function(x) { if (!identical(class(x), "tag")) { - stop("Undefined tag in usage ", class(x)[[1]], call. = FALSE) + cli::cli_abort( + "Undefined tag in usage: {.val class(x)[[1]]}}", + call = caller_env() + ) } paste0(purrr::flatten_chr(purrr::map(x, usage_code)), collapse = "") } diff --git a/R/utils-fs.R b/R/utils-fs.R index 05f48890c..9e4445da0 100644 --- a/R/utils-fs.R +++ b/R/utils-fs.R @@ -41,10 +41,10 @@ file_copy_to <- function(pkg, eq <- purrr::map2_lgl(from_paths, to_paths, file_equal) if (any(!eq)) { - cat_line( - "Copying ", src_path(path_rel(from_paths[!eq], pkg$src_path)), - " to ", dst_path(path_rel(to_paths[!eq], pkg$dst_path)) - ) + cli::cli_inform(c( + "Copying {src_path(path_rel(from_paths[!eq], pkg$src_path))}", + " to {dst_path(path_rel(to_paths[!eq], pkg$dst_path))}" + )) } file_copy(from_paths[!eq], to_paths[!eq], overwrite = overwrite) @@ -55,7 +55,10 @@ out_of_date <- function(source, target) { return(TRUE) if (!file_exists(source)) { - stop("'", source, "' does not exist", call. = FALSE) + cli::cli_abort( + "{.fn {source}} does not exist", + call = caller_env() + ) } file.info(source)$mtime > file.info(target)$mtime @@ -100,3 +103,10 @@ path_package_pkgdown <- function(..., package, bs_version = NULL) { path_pkgdown <- function(...) { system_file(..., package = "pkgdown") } + +pkgdown_config_relpath <- function(pkg) { + pkg <- as_pkgdown(pkg) + config_path <- pkgdown_config_path(pkg$src_path) + + fs::path_rel(config_path, pkg$src_path) +} diff --git a/R/utils-yaml.R b/R/utils-yaml.R index 1c21bc19f..ff8ece88d 100644 --- a/R/utils-yaml.R +++ b/R/utils-yaml.R @@ -4,12 +4,12 @@ check_yaml_has <- function(missing, where, pkg) { } missing_components <- lapply(missing, function(x) c(where, x)) - missing_fields <- pkgdown_fields(pkg, missing_components) + msg_flds <- pkgdown_field(pkg, missing_components, fmt = TRUE, cfg = TRUE) - abort(paste0( - "Can't find component", if (length(missing) > 1) "s", " ", - missing_fields, "." - )) + cli::cli_abort( + paste0("Can't find {cli::qty(missing)} component{?s} ", msg_flds, "."), + call = caller_env() + ) } yaml_character <- function(pkg, where) { @@ -20,25 +20,33 @@ yaml_character <- function(pkg, where) { } else if (is.character(x)) { x } else { - abort(paste0(pkgdown_field(pkg, where), " must be a character vector")) + fld <- pkgdown_field(pkg, where, fmt = TRUE) + cli::cli_abort( + paste0(fld, " must be a character vector."), + call = caller_env() + ) } } -pkgdown_field <- function(pkg, field) { - pkgdown_fields(pkg, list(field)) -} +pkgdown_field <- function(pkg, fields, cfg = FALSE, fmt = FALSE) { + + if (!is.list(fields)) fields <- list(fields) -pkgdown_fields <- function(pkg, fields, join = ", ") { - fields <- purrr::map_chr(fields, ~ paste0(cli::style_bold(.x), collapse = ".")) - fields_str <- paste0(fields, collapse = join) + flds <- purrr::map_chr(fields, ~ paste0(.x, collapse = ".")) + if (fmt) { + flds <- paste0("{.field ", flds, "}") + } - config_path <- pkgdown_config_path(pkg$src_path) + if (cfg) { + config_path <- pkgdown_config_relpath(pkg) + if (fmt) { + config_path <- paste0("{.file ", config_path, "}") + } - if (is.null(config_path)) { - fields_str + paste0(flds, " in ", config_path) } else { - config <- src_path(fs::path_rel(config_path, pkg$src_path)) - paste0(fields_str, " in ", config) + + flds } } diff --git a/R/utils.R b/R/utils.R index 6ace99a97..290748126 100644 --- a/R/utils.R +++ b/R/utils.R @@ -59,36 +59,13 @@ devtools_meta <- function(x) { # CLI --------------------------------------------------------------------- -dst_path <- function(...) { - cli::col_blue(encodeString(path(...), quote = "'")) -} - -src_path <- function(...) { - cli::col_green(encodeString(path(...), quote = "'")) -} - -cat_line <- function(...) { - cat(paste0(..., "\n"), sep = "") -} - -rule <- function(x = NULL, line = "-") { - width <- getOption("width") - - if (!is.null(x)) { - prefix <- paste0(line, line, " ") - suffix <- " " - } else { - prefix <- "" - suffix <- "" - x <- "" - } - - line_length <- width - nchar(x) - nchar(prefix) - nchar(suffix) - # protect against negative values which can result in narrow terminals - line_length <- max(0, line_length) - cat_line(prefix, cli::style_bold(x), suffix, strrep(line, line_length)) -} +dst_path <- cli::combine_ansi_styles( + cli::style_bold, cli::col_cyan +) +src_path <- cli::combine_ansi_styles( + cli::style_bold, cli::col_green +) skip_if_no_pandoc <- function(version = "1.12.3") { testthat::skip_if_not(rmarkdown::pandoc_available(version)) diff --git a/man/build_favicons.Rd b/man/build_favicons.Rd index b252e0b4b..245393ebf 100644 --- a/man/build_favicons.Rd +++ b/man/build_favicons.Rd @@ -2,12 +2,9 @@ % Please edit documentation in R/build-favicons.R \name{build_favicons} \alias{build_favicons} -\alias{build_favicon} \title{Create favicons from package logo} \usage{ build_favicons(pkg = ".", overwrite = FALSE) - -build_favicon(pkg, overwrite) } \arguments{ \item{pkg}{Path to package.} diff --git a/man/clean_site.Rd b/man/clean_site.Rd index 4fee8dfee..d8e73f3cf 100644 --- a/man/clean_site.Rd +++ b/man/clean_site.Rd @@ -4,10 +4,12 @@ \alias{clean_site} \title{Clean site} \usage{ -clean_site(pkg = ".") +clean_site(pkg = ".", quiet = FALSE) } \arguments{ \item{pkg}{Path to package.} + +\item{quiet}{If \code{TRUE}, suppresses a message.} } \description{ Delete all files in \verb{docs/} (except for \code{CNAME}). diff --git a/man/test-dont.Rd b/man/test-dont.Rd index dbcfb7959..804b68984 100644 --- a/man/test-dont.Rd +++ b/man/test-dont.Rd @@ -8,7 +8,7 @@ Test case: don't } \examples{ \dontrun{ - stop("This is an error!", call. = FALSE) + abort("This is an error!") } # Inline \donttest is silently ommitted diff --git a/tests/testthat/_snaps/build-articles.md b/tests/testthat/_snaps/build-articles.md index 807792066..186dd29ad 100644 --- a/tests/testthat/_snaps/build-articles.md +++ b/tests/testthat/_snaps/build-articles.md @@ -1,14 +1,123 @@ +# links to man/figures are automatically relocated + + Code + copy_figures(pkg) + Message + Copying man/figures/kitten.jpg + to reference/figures/kitten.jpg + +--- + + Code + build_articles(pkg, lazy = FALSE) + Message + Writing articles/index.html + Reading vignettes/kitten.Rmd + Writing articles/kitten.html + # warns about missing images Code build_articles(pkg) - Output - -- Building articles ----------------------------------------------------------- - Writing 'articles/index.html' - Reading 'vignettes/html-vignette.Rmd' - Writing 'articles/html-vignette.html' + Message + Writing articles/index.html + Reading vignettes/html-vignette.Rmd + Writing articles/html-vignette.html Condition Warning: Missing images in 'vignettes/html-vignette.Rmd': 'foo.png' i pkgdown can only use images in 'man/figures' and 'vignettes' +# articles don't include header-attrs.js script + + Code + path <- build_article("standard", pkg) + Message + Reading vignettes/standard.Rmd + Writing articles/standard.html + +# can build article that uses html_vignette + + Code + expect_error(build_article("html-vignette", pkg), NA) + Message + Reading vignettes/html-vignette.Rmd + Writing articles/html-vignette.html + +# can override html_document() options + + Code + path <- build_article("html-document", pkg) + Message + Reading vignettes/html-document.Rmd + Writing articles/html-document.html + +# html widgets get needed css/js + + Code + path <- build_article("widget", pkg) + Message + Reading vignettes/widget.Rmd + Writing articles/widget.html + +# can override options with _output.yml + + Code + path <- build_article("html-document", pkg) + Message + Reading vignettes/html-document.Rmd + Writing articles/html-document.html + +# can set width + + Code + path <- build_article("width", pkg) + Message + Reading vignettes/width.Rmd + Writing articles/width.html + +# finds external resources referenced by R code in the article html + + Code + path <- build_article("resources", pkg) + Message + Reading vignettes/resources.Rmd + Writing articles/resources.html + +# BS5 article laid out correctly with and without TOC + + Code + toc_true_path <- build_article("standard", pkg) + Message + Reading vignettes/standard.Rmd + Writing articles/standard.html + +--- + + Code + toc_false_path <- build_article("toc-false", pkg) + Message + Reading vignettes/toc-false.Rmd + Writing articles/toc-false.html + +# articles in vignettes/articles/ are unnested into articles/ + + Code + path <- build_article("articles/nested", pkg) + Message + Reading vignettes/articles/nested.Rmd + Writing articles/nested.html + +--- + + Code + build_redirects(pkg) + +# pkgdown deps are included only once in articles + + Code + path <- build_article("html-deps", pkg) + Message + Reading vignettes/html-deps.Rmd + Writing articles/html-deps.html + diff --git a/tests/testthat/_snaps/build-favicons.md b/tests/testthat/_snaps/build-favicons.md index 8d68d02b0..21f970cf1 100644 --- a/tests/testthat/_snaps/build-favicons.md +++ b/tests/testthat/_snaps/build-favicons.md @@ -2,8 +2,7 @@ Code build_favicons(pkg) - Output - -- Building favicons ----------------------------------------------------------- Message - Favicons already exist in `pkgdown/`. Set `overwrite = TRUE` to re-create. + Favicons already exist in 'pkgdown' + i Set `overwrite = TRUE` to re-create. diff --git a/tests/testthat/_snaps/build-github.md b/tests/testthat/_snaps/build-github.md new file mode 100644 index 000000000..36977fe4c --- /dev/null +++ b/tests/testthat/_snaps/build-github.md @@ -0,0 +1,8 @@ +# a CNAME record is built if a url exists in metadata + + Code + build_github_pages(pkg) + Message + Writing .nojekyll + Writing CNAME + diff --git a/tests/testthat/_snaps/build-home-authors.md b/tests/testthat/_snaps/build-home-authors.md index 46755f61b..361466b5a 100644 --- a/tests/testthat/_snaps/build-home-authors.md +++ b/tests/testthat/_snaps/build-home-authors.md @@ -22,7 +22,7 @@ role_lookup("unknown") Condition Warning: - Unknown MARC role abbreviation 'unknown' + Unknown MARC role abbreviation: unknown Output [1] "unknown" diff --git a/tests/testthat/_snaps/build-home-citation.md b/tests/testthat/_snaps/build-home-citation.md index 220471332..89dac427d 100644 --- a/tests/testthat/_snaps/build-home-citation.md +++ b/tests/testthat/_snaps/build-home-citation.md @@ -1,3 +1,11 @@ +# source link is added to citation page + + Code + build_home(pkg) + Message + Writing authors.html + Writing 404.html + # multiple citations all have HTML and BibTeX formats [[1]] diff --git a/tests/testthat/_snaps/build-home-index.md b/tests/testthat/_snaps/build-home-index.md index 4e33fc563..afad1e7cb 100644 --- a/tests/testthat/_snaps/build-home-index.md +++ b/tests/testthat/_snaps/build-home-index.md @@ -48,7 +48,8 @@ # data_home_sidebar() errors well when no HTML file - Can't find file 'file.html' specified by home.sidebar.html in '_pkgdown.yml'. + Can't locate 'file.html'. + x home.sidebar.html in '_pkgdown.yml' is misconfigured. # data_home_sidebar() can get a custom markdown formatted component @@ -70,23 +71,41 @@ # data_home_sidebar() outputs informative error messages - Can't find component home.sidebar.components.fancy in '_pkgdown.yml'. + Code + data_home_sidebar(pkg) + Condition + Error in `data_home_sidebar()`: + ! Can't find component home.sidebar.components.fancy in '_pkgdown.yml'. --- - Can't find components home.sidebar.components.fancy, home.sidebar.components.cool in '_pkgdown.yml'. + Code + data_home_sidebar(pkg) + Condition + Error in `data_home_sidebar()`: + ! Can't find components home.sidebar.components.fancy in '_pkgdown.yml'. + Can't find components home.sidebar.components.cool in '_pkgdown.yml'. --- - i In index: 1. - i With name: fancy. - Caused by error in `check_yaml_has()`: - ! Can't find component home.sidebar.components.fancy.title in '_pkgdown.yml'. + Code + data_home_sidebar(pkg) + Condition + Error in `purrr::map2()`: + i In index: 1. + i With name: fancy. + Caused by error in `.f()`: + ! Can't find component home.sidebar.components.fancy.title in '_pkgdown.yml'. --- - i In index: 1. - i With name: fancy. - Caused by error in `check_yaml_has()`: - ! Can't find components home.sidebar.components.fancy.title, home.sidebar.components.fancy.text in '_pkgdown.yml'. + Code + data_home_sidebar(pkg) + Condition + Error in `purrr::map2()`: + i In index: 1. + i With name: fancy. + Caused by error in `.f()`: + ! Can't find components home.sidebar.components.fancy.title in '_pkgdown.yml'. + Can't find components home.sidebar.components.fancy.text in '_pkgdown.yml'. diff --git a/tests/testthat/_snaps/build-home.md b/tests/testthat/_snaps/build-home.md index 022d951c2..cf1bf5b85 100644 --- a/tests/testthat/_snaps/build-home.md +++ b/tests/testthat/_snaps/build-home.md @@ -1,14 +1,50 @@ +# intermediate files cleaned up automatically + + Code + build_home(pkg) + Message + Writing authors.html + Writing 404.html + +--- + + Code + build_home(pkg) + Message + Writing authors.html + Writing 404.html + # warns about missing images Code build_home(pkg) - Output - -- Building home --------------------------------------------------------------- - Writing 'authors.html' + Message + Writing authors.html Condition Warning: Missing images in 'README.md': 'foo.png' i pkgdown can only use images in 'man/figures' and 'vignettes' - Output - Writing '404.html' + Message + Writing 404.html + +# can build site even if no Authors@R present + + Code + build_home(pkg) + Message + Writing authors.html + Writing 404.html + +# .github files are copied and linked + + Code + build_home(pkg) + Message + Writing authors.html + Reading .github/404.md + Writing 404.html + Reading .github/CODE_OF_CONDUCT.md + Writing CODE_OF_CONDUCT.html + Reading .github/SUPPORT.md + Writing SUPPORT.html diff --git a/tests/testthat/_snaps/build-logo.md b/tests/testthat/_snaps/build-logo.md index 6064320d3..bf005edad 100644 --- a/tests/testthat/_snaps/build-logo.md +++ b/tests/testthat/_snaps/build-logo.md @@ -2,6 +2,7 @@ Code copy_logo(pkg) - Output - Copying 'man/figures/logo.svg' to 'logo.svg' + Message + Copying man/figures/logo.svg + to logo.svg diff --git a/tests/testthat/_snaps/build-news.md b/tests/testthat/_snaps/build-news.md index 7317c2bec..0209c2e89 100644 --- a/tests/testthat/_snaps/build-news.md +++ b/tests/testthat/_snaps/build-news.md @@ -16,13 +16,26 @@ # multi-page news are rendered - # A tibble: 4 x 3 - version page anchor - - 1 2.0 2.0 testpackage-20 - 2 1.1 1.1 testpackage-11 - 3 1.0.1 1.0 testpackage-101 - 4 1.0.0 1.0 testpackage-100 + Code + data_news(pkg)[c("version", "page", "anchor")] + Output + # A tibble: 4 x 3 + version page anchor + + 1 2.0 2.0 testpackage-20 + 2 1.1 1.1 testpackage-11 + 3 1.0.1 1.0 testpackage-101 + 4 1.0.0 1.0 testpackage-100 + +--- + + Code + build_news(pkg) + Message + Writing news/news-2.0.html + Writing news/news-1.1.html + Writing news/news-1.0.html + Writing news/index.html # news headings get class and release date @@ -43,13 +56,13 @@ Invalid NEWS.md: inconsistent use of section headings. i Top-level headings must be either all

or all

. - i See ?build_news for more details. + i See `?pkgdown::build_news()` for more details. # clear error for bad hierarchy - h3 Invalid NEWS.md: inconsistent use of section headings. i Top-level headings must be either all

or all

. - i See ?build_news for more details. + i See `?pkgdown::build_news()` for more details. # news can contain footnotes diff --git a/tests/testthat/_snaps/build-redirects.md b/tests/testthat/_snaps/build-redirects.md index f7b6c2fe4..5d392178e 100644 --- a/tests/testthat/_snaps/build-redirects.md +++ b/tests/testthat/_snaps/build-redirects.md @@ -1,4 +1,9 @@ # build_redirect() errors if one entry is not right. - Entry 5 in redirects must be a character vector of length 2. + Code + build_redirect(c("old.html"), 5, pkg) + Condition + Error: + ! Entry 5 must be a character vector of length 2. + x Edit url in '_pkgdown.yml'. diff --git a/tests/testthat/_snaps/build-reference-index.md b/tests/testthat/_snaps/build-reference-index.md index d595dc877..13a43f0e2 100644 --- a/tests/testthat/_snaps/build-reference-index.md +++ b/tests/testthat/_snaps/build-reference-index.md @@ -58,32 +58,44 @@ # errors well when a content entry is empty i In index: 1. - Caused by error in `check_all_characters()`: - ! Item 2 in section 1 in reference in '_pkgdown.yml' is empty. - i Either delete the empty line or add a function name. + Caused by error in `.f()`: + ! Item 2 in section 1 is empty. + x Delete the empty line or add function name to reference in '_pkgdown.yml'. # errors well when a content entry is not a character - i In index: 1. - Caused by error in `check_all_characters()`: - ! Item 2 in section 1 in reference in '_pkgdown.yml' must be a character. - i You might need to add '' around e.g. - 'N' or - 'off'. + Code + build_reference_index(pkg) + Condition + Error in `map2()`: + i In index: 1. + Caused by error in `.f()`: + ! Item 2 in section 1 must be a character. + x You might need to add '' around e.g. - 'N' or - 'off' to reference in '_pkgdown.yml'. # errors well when a content entry refers to a not installed package - i In index: 1. - Caused by error in `purrr::map2()`: - i In index: 1. - Caused by error in `.f()`: - ! The package "notapackage" is required as it's used in the reference index. + Code + build_reference_index(pkg) + Condition + Error in `map2()`: + i In index: 1. + Caused by error in `purrr::map2()`: + i In index: 1. + Caused by error in `.f()`: + ! The package "notapackage" is required as it's used in the reference index. # errors well when a content entry refers to a non existing function - i In index: 1. - Caused by error in `purrr::map2()`: - i In index: 1. - Caused by error in `.f()`: - ! Could not find documentation for rlang::lala + Code + build_reference_index(pkg) + Condition + Error in `map2()`: + i In index: 1. + Caused by error in `purrr::map2()`: + i In index: 1. + Caused by error in `map2_()`: + ! Could not find documentation for `rlang::lala()`. # can use a topic from another package diff --git a/tests/testthat/_snaps/build-reference.md b/tests/testthat/_snaps/build-reference.md index 2190def0e..31f9b6a92 100644 --- a/tests/testthat/_snaps/build-reference.md +++ b/tests/testthat/_snaps/build-reference.md @@ -2,20 +2,45 @@ Code build_reference(pkg) - Output - -- Building function reference ------------------------------------------------- - Writing 'reference/index.html' - Reading 'man/f.Rd' + Message + Writing reference/index.html + Reading man/f.Rd Condition Error in `purrr::map()`: i In index: 1. i With name: f.Rd. Caused by error in `.f()`: - ! Failed to parse Rd in f.Rd - In index: 4. + ! Failed to parse Rd in 'f.Rd' Caused by error in `purrr::map()`: i In index: 4. - Caused by error in `stop_bad_tag()`: - ! Failed to parse \url{}. + Caused by error: + ! Failed to parse tag "\\url{}". i Check for empty \url{} tags. +# .Rd without usage doesn't get Usage section + + Code + build_reference(pkg, topics = "e") + Message + Writing reference/index.html + Reading man/e.Rd + Writing reference/e.html + +--- + + Code + build_reference(pkg, topics = "e") + Message + Writing reference/index.html + Reading man/e.Rd + Writing reference/e.html + +# pkgdown html dependencies are suppressed from examples in references + + Code + build_reference(pkg, topics = "a") + Message + Writing reference/index.html + Reading man/a.Rd + Writing reference/a.html + diff --git a/tests/testthat/_snaps/check.md b/tests/testthat/_snaps/check.md index 0580cafd1..d90010d88 100644 --- a/tests/testthat/_snaps/check.md +++ b/tests/testthat/_snaps/check.md @@ -13,13 +13,11 @@ Code check_pkgdown(pkg) Condition - Error in `data_articles_index()`: - ! Vignettes missing from index: articles/nested, width + Error in `check_pkgdown()`: + ! 2 vignettes missing from index: 'articles/nested' and 'width'. # informs if everything is ok Code check_pkgdown(pkg) - Message - No problems found diff --git a/tests/testthat/_snaps/figure.md b/tests/testthat/_snaps/figure.md new file mode 100644 index 000000000..462dbe54c --- /dev/null +++ b/tests/testthat/_snaps/figure.md @@ -0,0 +1,18 @@ +# can override defaults in _pkgdown.yml + + Code + build_reference(pkg, devel = FALSE) + Message + Writing reference/index.html + Reading man/figure.Rd + Writing reference/figure.html + +--- + + Code + build_articles(pkg) + Message + Writing articles/index.html + Reading vignettes/figures.Rmd + Writing articles/figures.html + diff --git a/tests/testthat/_snaps/init.md b/tests/testthat/_snaps/init.md index 31a5e2518..953b138c4 100644 --- a/tests/testthat/_snaps/init.md +++ b/tests/testthat/_snaps/init.md @@ -1,12 +1,15 @@ # site meta doesn't break unexpectedly - pandoc: '{version}' - pkgdown: '{version}' - pkgdown_sha: '{sha}' - articles: {} - last_built: 2020-01-01T00:00Z - urls: - reference: http://test.org/reference - article: http://test.org/articles - + Code + yaml + Output + pandoc: '{version}' + pkgdown: '{version}' + pkgdown_sha: '{sha}' + articles: {} + last_built: 2020-01-01T00:00Z + urls: + reference: http://test.org/reference + article: http://test.org/articles + diff --git a/tests/testthat/_snaps/markdown.md b/tests/testthat/_snaps/markdown.md index 15d37dbfd..74d9b40c7 100644 --- a/tests/testthat/_snaps/markdown.md +++ b/tests/testthat/_snaps/markdown.md @@ -1,7 +1,4 @@ # markdown_text_inline() works with inline markdown - Can't use a block element in , need an inline element: - x - - y + Can't use a block element in ``, need an inline element: `x y` diff --git a/tests/testthat/_snaps/navbar.md b/tests/testthat/_snaps/navbar.md index 3e39d249c..40190cdf0 100644 --- a/tests/testthat/_snaps/navbar.md +++ b/tests/testthat/_snaps/navbar.md @@ -174,8 +174,8 @@ Code data_navbar(pkg) Condition - Error in `yaml_character()`: - ! navbar.structure.left must be a character vector + Error in `navbar_links()`: + ! navbar.structure.left must be a character vector. # render_navbar_links BS3 & BS4 default diff --git a/tests/testthat/_snaps/package.md b/tests/testthat/_snaps/package.md index a069241e7..f556c9cf4 100644 --- a/tests/testthat/_snaps/package.md +++ b/tests/testthat/_snaps/package.md @@ -1,9 +1,9 @@ # check_bootstrap_version() gives informative error otherwise Code - check_bootstrap_version(1) + check_bootstrap_version(1, pkg) Condition - Error in `check_bootstrap_version()`: + Error: ! Boostrap version must be 3 or 5. - x You specified a value of 1 in template.bootstrap. + x You set a value of 1 to template.bootstrap in '_pkgdown.yml'. diff --git a/tests/testthat/_snaps/rd-example.md b/tests/testthat/_snaps/rd-example.md new file mode 100644 index 000000000..8d4c6fc03 --- /dev/null +++ b/tests/testthat/_snaps/rd-example.md @@ -0,0 +1,8 @@ +# @examplesIf + + Code + expect_equal(strtrim(rd2ex(rd3), 40), strtrim(exp3, 40)) + Condition + Warning: + @examplesIf condition "TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && TRUE && FALSE" is "FALSE" + diff --git a/tests/testthat/_snaps/rd-html.md b/tests/testthat/_snaps/rd-html.md index bd153d0cb..16c6be23d 100644 --- a/tests/testthat/_snaps/rd-html.md +++ b/tests/testthat/_snaps/rd-html.md @@ -1,7 +1,7 @@ # subsection generates h3 Code - cat_line(rd2html("\\subsection{A}{B}")) + cli::cat_line(rd2html("\\subsection{A}{B}")) Output

A

@@ -11,7 +11,7 @@ --- Code - cat_line(rd2html("\\subsection{A}{\n p1\n\n p2\n }")) + cli::cat_line(rd2html("\\subsection{A}{\n p1\n\n p2\n }")) Output

A

@@ -22,7 +22,7 @@ # nested subsection generates h4 Code - cat_line(rd2html("\\subsection{H3}{\\subsection{H4}{}}")) + cli::cat_line(rd2html("\\subsection{H3}{\\subsection{H4}{}}")) Output

H3

@@ -32,6 +32,16 @@
+# Sexprs with multiple args are parsed + + Code + rd2html("\\Sexpr[results=verbatim]{1}") + Condition + Error in `purrr::map_chr()`: + i In index: 1. + Caused by error in `map_()`: + ! \\Sexpr{result=verbatim} not yet supported + # bad specs throw errors Code @@ -39,32 +49,32 @@ Condition Error in `purrr::map_chr()`: i In index: 1. - Caused by error in `stop_bad_tag()`: - ! Failed to parse \url{}. + Caused by error: + ! Failed to parse tag "\\url{}". i Check for empty \url{} tags. Code rd2html("\\url{a\nb}") Condition Error in `purrr::map_chr()`: i In index: 1. - Caused by error in `stop_bad_tag()`: - ! Failed to parse \url{}. + Caused by error: + ! Failed to parse tag "\\url{}". i This may be caused by a \url tag that spans a line break. Code rd2html("\\email{}") Condition Error in `purrr::map_chr()`: i In index: 1. - Caused by error in `stop_bad_tag()`: - ! Failed to parse \email{}. - i empty {} + Caused by error: + ! Failed to parse tag "\\email{}". + i empty Code rd2html("\\linkS4class{}") Condition Error in `purrr::map_chr()`: i In index: 1. - Caused by error in `stop_bad_tag()`: - ! Failed to parse \linkS4class{}. + Caused by error: + ! Failed to parse tag "\\linkS4class{}". # \describe items can contain multiple paragraphs diff --git a/tests/testthat/_snaps/render.md b/tests/testthat/_snaps/render.md index 9886a9c8e..700823873 100644 --- a/tests/testthat/_snaps/render.md +++ b/tests/testthat/_snaps/render.md @@ -1,6 +1,7 @@ # check_bootswatch_theme() works - Can't find Bootswatch theme 'paper' (template.bootswatch) for Bootstrap version '4' (template.bootstrap). + Can't find Bootswatch theme "paper" (template.bootswatch) for Bootstrap version "4" (template.bootstrap). + x Edit settings in '_pkgdown.yml' # capture data_template() diff --git a/tests/testthat/_snaps/rmarkdown.md b/tests/testthat/_snaps/rmarkdown.md index dfcebf315..adee21568 100644 --- a/tests/testthat/_snaps/rmarkdown.md +++ b/tests/testthat/_snaps/rmarkdown.md @@ -1,17 +1,22 @@ +# render_rmarkdown copies image files in subdirectories + + Code + render_rmarkdown(pkg, "assets/vignette-with-img.Rmd", "test.html") + Message + Reading assets/vignette-with-img.Rmd + Writing test.html + # render_rmarkdown yields useful error Code render_rmarkdown(pkg, "assets/pandoc-fail.Rmd", "test.html", output_format = rmarkdown::html_document( pandoc_args = "--fail-if-warnings")) - Output - Reading 'assets/pandoc-fail.Rmd' - -- RMarkdown error ------------------------------------------------------------- - [WARNING] Could not fetch resource path-to-image.png - Failing because there were warnings. - -------------------------------------------------------------------------------- + Message + Reading assets/pandoc-fail.Rmd Condition Error in `render_rmarkdown()`: - ! Failed to render RMarkdown + ! Failed to render RMarkdown document. + x [WARNING] Could not fetch resource path-to-image.png Failing because there were warnings. Caused by error: ! in callr subprocess. Caused by error: @@ -19,5 +24,14 @@ # render_rmarkdown styles ANSI escapes + Code + path <- render_rmarkdown(pkg, input = "assets/vignette-with-crayon.Rmd", + output = "test.html") + Message + Reading assets/vignette-with-crayon.Rmd + Writing test.html + +--- + #> X diff --git a/tests/testthat/_snaps/sitrep.md b/tests/testthat/_snaps/sitrep.md index 330db5d0c..46c863665 100644 --- a/tests/testthat/_snaps/sitrep.md +++ b/tests/testthat/_snaps/sitrep.md @@ -1,12 +1,28 @@ # pkgdown_sitrep works - * url in '_pkgdown.yml' not configured. + Code + pkgdown_sitrep(pkg) + Condition + Warning: + pkgdown situation report: configuration error + x url in '_pkgdown.yml'is misconfigured. See `vignette(pkgdown::metatdata)`. + x 'DESCRIPTION' URL is empty. --- - * URL missing from the DESCRIPTION URL field. + Code + pkgdown_sitrep(pkg) + Condition + Warning: + pkgdown situation report: configuration error + x 'DESCRIPTION' URL is empty. --- - All good :-) + Code + pkgdown_sitrep(pkg) + Message + Double-check the following URLs: + '_pkgdown.yml' contains URL + 'DESCRIPTION' contains URL diff --git a/tests/testthat/_snaps/topics-external.md b/tests/testthat/_snaps/topics-external.md index 6a2e8ed02..f2f7ab738 100644 --- a/tests/testthat/_snaps/topics-external.md +++ b/tests/testthat/_snaps/topics-external.md @@ -28,6 +28,6 @@ Condition Error in `purrr::map2()`: i In index: 1. - Caused by error in `.f()`: - ! Could not find documentation for base::doesntexist + Caused by error in `map2_()`: + ! Could not find documentation for `base::doesntexist()`. diff --git a/tests/testthat/_snaps/topics.md b/tests/testthat/_snaps/topics.md index 0a2c20ad1..7d3e10dbe 100644 --- a/tests/testthat/_snaps/topics.md +++ b/tests/testthat/_snaps/topics.md @@ -6,24 +6,21 @@ Error in `purrr::map()`: i In index: 1. Caused by error: - ! In '_pkgdown.yml', topic must be valid R code - x Not 'x + ' + ! In '_pkgdown.yml', topic must be valid R code, not "x + ". Code t <- select_topics("y", topics) Condition Error in `purrr::map()`: i In index: 1. Caused by error: - ! In '_pkgdown.yml', topic must be a known topic name or alias - x Not 'y' + ! In '_pkgdown.yml', topic must be a known topic name or alias, not "y". Code t <- select_topics("paste(1)", topics) Condition Error in `purrr::map()`: i In index: 1. Caused by error: - ! In '_pkgdown.yml', topic must be a known selector function - x Not 'paste(1)' + ! In '_pkgdown.yml', topic must be a known selector function, not "paste(1)". Caused by error in `paste()`: ! could not find function "paste" Code @@ -32,20 +29,18 @@ Error in `purrr::map()`: i In index: 1. Caused by error: - ! In '_pkgdown.yml', topic must be a known topic name or alias - x Not 'starts_with' + ! In '_pkgdown.yml', topic must be a known topic name or alias, not "starts_with". Code t <- select_topics("1", topics) Condition Error in `purrr::map()`: i In index: 1. Caused by error: - ! In '_pkgdown.yml', topic must be a string or function call - x Not '1' + ! In '_pkgdown.yml', topic must be a string or function call, not "1". Code t <- select_topics("starts_with('y')", topics, check = TRUE) Condition - Error in `select_topics()`: + Error: ! No topics matched in '_pkgdown.yml'. No topics selected. # can select by name or alias @@ -56,16 +51,14 @@ Error in `purrr::map()`: i In index: 1. Caused by error: - ! In '_pkgdown.yml', topic must be a known topic name or alias - x Not 'a4' + ! In '_pkgdown.yml', topic must be a known topic name or alias, not "a4". Code select_topics("c::a", topics) Condition Error in `purrr::map()`: i In index: 1. Caused by error: - ! In '_pkgdown.yml', topic must be a known topic name or alias - x Not 'c::a' + ! In '_pkgdown.yml', topic must be a known topic name or alias, not "c::a". # an unmatched selection generates a warning @@ -73,6 +66,5 @@ select_topics(c("a", "starts_with('unmatched')"), topics, check = TRUE) Condition Error: - ! In '_pkgdown.yml', topic must match a function or concept - x Not 'starts_with(\'unmatched\')' + ! In '_pkgdown.yml', topic must match a function or concept, not "starts_with('unmatched')". diff --git a/tests/testthat/_snaps/utils-yaml.md b/tests/testthat/_snaps/utils-yaml.md index 7573cb83f..2f000754a 100644 --- a/tests/testthat/_snaps/utils-yaml.md +++ b/tests/testthat/_snaps/utils-yaml.md @@ -1,24 +1,14 @@ -# pkgdown_field(s) produces useful description - - Code - pkgdown_field(pkg, c("a", "b")) - Output - [1] "a.b in '_pkgdown.yml'" - Code - pkgdown_fields(pkg, list(c("a", "b"), "c")) - Output - [1] "a.b, c in '_pkgdown.yml'" - ---- +# pkgdown_field produces useful description Code check_yaml_has("x", where = "a", pkg = pkg) Condition - Error in `check_yaml_has()`: + Error: ! Can't find component a.x in '_pkgdown.yml'. Code check_yaml_has(c("x", "y"), where = "a", pkg = pkg) Condition - Error in `check_yaml_has()`: - ! Can't find components a.x, a.y in '_pkgdown.yml'. + Error: + ! Can't find components a.x in '_pkgdown.yml'. + Can't find components a.y in '_pkgdown.yml'. diff --git a/tests/testthat/assets/articles/_pkgdown.yml b/tests/testthat/assets/articles/_pkgdown.yml new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testthat/setup.R b/tests/testthat/setup.R new file mode 100644 index 000000000..75010f6ee --- /dev/null +++ b/tests/testthat/setup.R @@ -0,0 +1,3 @@ +# suppress cli messages in interactive testthat output +# https://github.com/r-lib/cli/issues/434 +options(cli.default_handler = function(...) { }) diff --git a/tests/testthat/test-build-articles.R b/tests/testthat/test-build-articles.R index 250af53d3..037702796 100644 --- a/tests/testthat/test-build-articles.R +++ b/tests/testthat/test-build-articles.R @@ -10,8 +10,8 @@ test_that("links to man/figures are automatically relocated", { skip_on_cran() pkg <- local_pkgdown_site(test_path("assets/man-figures")) - expect_output(copy_figures(pkg)) - expect_output(build_articles(pkg, lazy = FALSE)) + expect_snapshot(copy_figures(pkg)) + expect_snapshot(build_articles(pkg, lazy = FALSE)) html <- xml2::read_html(path(pkg$dst_path, "articles", "kitten.html")) src <- xpath_attr(html, "//img", "src") @@ -27,15 +27,16 @@ test_that("links to man/figures are automatically relocated", { }) test_that("warns about missing images", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/bad-images")) expect_snapshot(build_articles(pkg)) }) test_that("articles don't include header-attrs.js script", { pkg <- as_pkgdown(test_path("assets/articles")) - withr::defer(clean_site(pkg)) + withr::defer(clean_site(pkg, quiet = TRUE)) - expect_output(path <- build_article("standard", pkg)) + expect_snapshot(path <- build_article("standard", pkg)) html <- xml2::read_html(path) js <- xpath_attr(html, ".//body//script", "src") @@ -48,12 +49,12 @@ test_that("can build article that uses html_vignette", { pkg <- local_pkgdown_site(test_path("assets/articles")) # theme is not set since html_vignette doesn't support it - expect_output(expect_error(build_article("html-vignette", pkg), NA)) + expect_snapshot(expect_error(build_article("html-vignette", pkg), NA)) }) test_that("can override html_document() options", { pkg <- local_pkgdown_site(test_path("assets/articles")) - expect_output(path <- build_article("html-document", pkg)) + expect_snapshot(path <- build_article("html-document", pkg)) # Check that number_sections is respected html <- xml2::read_html(path) @@ -69,7 +70,7 @@ test_that("can override html_document() options", { test_that("html widgets get needed css/js", { pkg <- local_pkgdown_site(test_path("assets/articles")) - expect_output(path <- build_article("widget", pkg)) + expect_snapshot(path <- build_article("widget", pkg)) html <- xml2::read_html(path) css <- xpath_attr(html, ".//body//link", "href") @@ -81,7 +82,7 @@ test_that("html widgets get needed css/js", { test_that("can override options with _output.yml", { pkg <- local_pkgdown_site(test_path("assets/articles")) - expect_output(path <- build_article("html-document", pkg)) + expect_snapshot(path <- build_article("html-document", pkg)) # Check that number_sections is respected html <- xml2::read_html(path) @@ -94,7 +95,7 @@ test_that("can set width", { width: 50 ") - expect_output(path <- build_article("width", pkg)) + expect_snapshot(path <- build_article("width", pkg)) html <- xml2::read_html(path) expect_equal(xpath_text(html, ".//pre")[[2]], "## [1] 50") }) @@ -104,7 +105,7 @@ test_that("finds external resources referenced by R code in the article html", { skip_on_cran() pkg <- local_pkgdown_site(test_path("assets", "articles-resources")) - expect_output(path <- build_article("resources", pkg)) + expect_snapshot(path <- build_article("resources", pkg)) # ensure that we the HTML references `` directly expect_equal( @@ -124,9 +125,9 @@ test_that("BS5 article laid out correctly with and without TOC", { bootstrap: 5 ") - expect_output(init_site(pkg)) - expect_output(toc_true_path <- build_article("standard", pkg)) - expect_output(toc_false_path <- build_article("toc-false", pkg)) + suppressMessages(expect_message(init_site(pkg))) + expect_snapshot(toc_true_path <- build_article("standard", pkg)) + expect_snapshot(toc_false_path <- build_article("toc-false", pkg)) toc_true <- xml2::read_html(toc_true_path) toc_false <- xml2::read_html(toc_false_path) @@ -145,7 +146,7 @@ test_that("articles in vignettes/articles/ are unnested into articles/", { skip_on_cran() pkg <- local_pkgdown_site(test_path("assets/articles")) - expect_output(path <- build_article("articles/nested", pkg)) + expect_snapshot(path <- build_article("articles/nested", pkg)) expect_equal( normalizePath(path), @@ -154,7 +155,7 @@ test_that("articles in vignettes/articles/ are unnested into articles/", { # Check automatic redirect from articles/articles/foo.html -> articles/foo.html pkg$meta$url <- "https://example.com" - expect_output(build_redirects(pkg)) + expect_snapshot(build_redirects(pkg)) # Check that the redirect file exists in /articles/articles/ redirect_path <- path(pkg$dst_path, "articles", "articles", "nested.html") @@ -170,13 +171,14 @@ test_that("articles in vignettes/articles/ are unnested into articles/", { }) test_that("pkgdown deps are included only once in articles", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/articles"), " template: bootstrap: 5 ") - expect_output(init_site(pkg)) - expect_output(path <- build_article("html-deps", pkg)) + suppressMessages(expect_message(init_site(pkg))) + expect_snapshot(path <- build_article("html-deps", pkg)) html <- xml2::read_html(path) diff --git a/tests/testthat/test-build-favicons.R b/tests/testthat/test-build-favicons.R index 4990401fd..dbc1cea90 100644 --- a/tests/testthat/test-build-favicons.R +++ b/tests/testthat/test-build-favicons.R @@ -2,7 +2,7 @@ test_that("missing logo generates message", { pkg <- local_pkgdown_site(test_path("assets/site-empty")) expect_error( - expect_output(build_favicons(pkg)), + expect_snapshot(build_favicons(pkg)), "Can't find package logo" ) }) diff --git a/tests/testthat/test-build-github.R b/tests/testthat/test-build-github.R index 23dd0e5dc..bbb90ddd1 100644 --- a/tests/testthat/test-build-github.R +++ b/tests/testthat/test-build-github.R @@ -2,7 +2,7 @@ test_that("a CNAME record is built if a url exists in metadata", { pkg <- local_pkgdown_site(test_path("assets/cname")) dir_create(path(pkg$dst_path, "docs")) - expect_output(build_github_pages(pkg)) + expect_snapshot(build_github_pages(pkg)) expect_equal(read_lines(path(pkg$dst_path, "CNAME")), "testpackage.r-lib.org") }) diff --git a/tests/testthat/test-build-home-authors.R b/tests/testthat/test-build-home-authors.R index 0eb6cd332..661d7dba9 100644 --- a/tests/testthat/test-build-home-authors.R +++ b/tests/testthat/test-build-home-authors.R @@ -56,6 +56,7 @@ test_that("data_home_sidebar_authors() works with text", { }) test_that("role has multiple fallbacks", { + local_edition(3) expect_equal(role_lookup("cre"), "maintainer") expect_equal(role_lookup("res"), "researcher") expect_snapshot(role_lookup("unknown")) diff --git a/tests/testthat/test-build-home-citation.R b/tests/testthat/test-build-home-citation.R index d3ae147e9..cf369c151 100644 --- a/tests/testthat/test-build-home-citation.R +++ b/tests/testthat/test-build-home-citation.R @@ -23,7 +23,7 @@ test_that("create_meta can read DESCRIPTION with an Encoding", { test_that("source link is added to citation page", { pkg <- local_pkgdown_site(test_path("assets/site-citation/encoding-UTF-8")) - expect_output(build_home(pkg)) + expect_snapshot(build_home(pkg)) lines <- read_lines(path(pkg$dst_path, "authors.html")) expect_true(any(grepl("inst/CITATION", lines))) diff --git a/tests/testthat/test-build-home-index.R b/tests/testthat/test-build-home-index.R index 141547a69..0d52ad2be 100644 --- a/tests/testthat/test-build-home-index.R +++ b/tests/testthat/test-build-home-index.R @@ -12,7 +12,7 @@ test_that("version formatting in preserved", { pkg <- local_pkgdown_site(test_path("assets/version-formatting")) expect_equal(pkg$version, "1.0.0-9000") - expect_output(init_site(pkg)) + suppressMessages(expect_message(init_site(pkg))) build_home_index(pkg, quiet = TRUE) index <- read_lines(path(pkg$dst_path, "index.html")) expect_true(any(grepl("1.0.0-9000", index, fixed = TRUE))) @@ -80,29 +80,30 @@ test_that("data_home_sidebar() can add a README", { }) test_that("data_home_sidebar() outputs informative error messages", { + local_edition(3) pkg <- as_pkgdown(test_path("assets/sidebar")) # no component definition for a component named in structure pkg$meta$home$sidebar <- list(structure = "fancy") - expect_snapshot_error(data_home_sidebar(pkg)) + expect_snapshot(data_home_sidebar(pkg), error = TRUE) # no component definition for two components named in structure pkg$meta$home$sidebar <- list(structure = c("fancy", "cool")) - expect_snapshot_error(data_home_sidebar(pkg)) + expect_snapshot(data_home_sidebar(pkg), error = TRUE) # no title pkg$meta$home$sidebar <- list( structure = c("fancy"), components = list(fancy = list(text = "bla")) ) - expect_snapshot_error(data_home_sidebar(pkg)) + expect_snapshot(data_home_sidebar(pkg), error = TRUE) # no title nor text pkg$meta$home$sidebar <- list( structure = c("fancy"), components = list(fancy = list(html = "bla")) ) - expect_snapshot_error(data_home_sidebar(pkg)) + expect_snapshot(data_home_sidebar(pkg), error = TRUE) }) test_that("package repo verification", { diff --git a/tests/testthat/test-build-home.R b/tests/testthat/test-build-home.R index 4299e6e61..6376a3592 100644 --- a/tests/testthat/test-build-home.R +++ b/tests/testthat/test-build-home.R @@ -4,7 +4,7 @@ test_that("intermediate files cleaned up automatically", { skip_if_no_pandoc() pkg <- local_pkgdown_site(test_path("assets/home-index-rmd")) - expect_output(build_home(pkg)) + expect_snapshot(build_home(pkg)) expect_setequal(dir(pkg$src_path), c("DESCRIPTION", "index.Rmd")) }) @@ -13,7 +13,7 @@ test_that("intermediate files cleaned up automatically", { skip_if_no_pandoc() pkg <- local_pkgdown_site(test_path("assets/home-readme-rmd")) - expect_output(build_home(pkg)) + expect_snapshot(build_home(pkg)) expect_setequal( dir(pkg$src_path), @@ -22,6 +22,7 @@ test_that("intermediate files cleaned up automatically", { }) test_that("warns about missing images", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/bad-images")) expect_snapshot(build_home(pkg)) }) @@ -30,7 +31,7 @@ test_that("can build site even if no Authors@R present", { skip_if_no_pandoc() pkg <- local_pkgdown_site(test_path("assets/home-old-skool")) - expect_output(build_home(pkg)) + expect_snapshot(build_home(pkg)) }) # .github files ----------------------------------------------------------- @@ -42,7 +43,7 @@ test_that(".github files are copied and linked", { skip_if_not(dir_exists(test_path("assets/site-dot-github/.github"))) pkg <- local_pkgdown_site(test_path("assets/site-dot-github")) - expect_output(build_home(pkg)) + expect_snapshot(build_home(pkg)) lines <- read_lines(path(pkg$dst_path, "index.html")) expect_true(any(grepl('href="CODE_OF_CONDUCT.html"', lines))) diff --git a/tests/testthat/test-build-logo.R b/tests/testthat/test-build-logo.R index b0d027bdc..5a97e1b87 100644 --- a/tests/testthat/test-build-logo.R +++ b/tests/testthat/test-build-logo.R @@ -1,4 +1,6 @@ test_that("can handle logo in subdir", { + local_edition(3) + src <- withr::local_tempdir() dst <- withr::local_tempdir() diff --git a/tests/testthat/test-build-news.R b/tests/testthat/test-build-news.R index 64fe95269..0b6386e99 100644 --- a/tests/testthat/test-build-news.R +++ b/tests/testthat/test-build-news.R @@ -26,6 +26,7 @@ test_that("data_news works as expected for h1 & h2", { test_that("multi-page news are rendered", { skip_if_no_pandoc() + local_edition(3) pkg <- local_pkgdown_site(meta = " news: @@ -45,8 +46,8 @@ test_that("multi-page news are rendered", { "* second thing" )) - expect_snapshot_output(data_news(pkg)[c("version", "page", "anchor")]) - expect_output(build_news(pkg)) + expect_snapshot(data_news(pkg)[c("version", "page", "anchor")]) + expect_snapshot(build_news(pkg)) # test that index links are correct lines <- read_lines(path(pkg$dst_path, "news", "index.html")) diff --git a/tests/testthat/test-build-redirects.R b/tests/testthat/test-build-redirects.R index 4ecf2d604..db03260a7 100644 --- a/tests/testthat/test-build-redirects.R +++ b/tests/testthat/test-build-redirects.R @@ -17,6 +17,7 @@ test_that("build_redirect() works", { }) test_that("build_redirect() errors if one entry is not right.", { + local_edition(3) pkg <- list( src_path = withr::local_tempdir(), dst_path = withr::local_tempdir(), @@ -25,7 +26,9 @@ test_that("build_redirect() errors if one entry is not right.", { bs_version = 5 ) pkg <- structure(pkg, class = "pkgdown") - expect_snapshot_error(build_redirect(c("old.html"), 5, pkg = pkg)) + file_touch(file.path(pkg$src_path, "_pkgdown.yml")) + + expect_snapshot(build_redirect(c("old.html"), 5, pkg), error = TRUE) }) test_that("article_redirects() creates redirects for vignettes in vignettes/articles", { diff --git a/tests/testthat/test-build-reference-index.R b/tests/testthat/test-build-reference-index.R index 562a02c88..59ef31855 100644 --- a/tests/testthat/test-build-reference-index.R +++ b/tests/testthat/test-build-reference-index.R @@ -73,26 +73,29 @@ test_that("errors well when a content entry is empty", { }) test_that("errors well when a content entry is not a character", { + local_edition(3) meta <- yaml::yaml.load( "reference:\n- title: bla\n contents:\n - aname\n - N") pkg <- as_pkgdown(test_path("assets/reference"), override = meta) - expect_snapshot_error(build_reference_index(pkg)) + expect_snapshot(build_reference_index(pkg), error = TRUE) }) test_that("errors well when a content entry refers to a not installed package", { skip_if_not_installed("cli", "3.1.0") + local_edition(3) meta <- yaml::yaml.load( "reference:\n- title: bla\n contents:\n - notapackage::lala") pkg <- as_pkgdown(test_path("assets/reference"), override = meta) - expect_snapshot_error(build_reference_index(pkg)) + expect_snapshot(build_reference_index(pkg), error = TRUE) }) test_that("errors well when a content entry refers to a non existing function", { + local_edition(3) meta <- yaml::yaml.load( "reference:\n- title: bla\n contents:\n - rlang::lala") pkg <- as_pkgdown(test_path("assets/reference"), override = meta) - expect_snapshot_error(build_reference_index(pkg)) + expect_snapshot(build_reference_index(pkg), error = TRUE) }) test_that("can exclude topics", { diff --git a/tests/testthat/test-build-reference.R b/tests/testthat/test-build-reference.R index 029065c4f..43356f136 100644 --- a/tests/testthat/test-build-reference.R +++ b/tests/testthat/test-build-reference.R @@ -1,6 +1,7 @@ test_that("parse failures include file name", { skip_if_not(getRversion() >= "4.0.0") - pkg <- local_pkgdown_site("assets/reference-fail") + local_edition(3) + pkg <- local_pkgdown_site(test_path("assets/reference-fail")) expect_snapshot(build_reference(pkg), error = TRUE) }) @@ -31,36 +32,38 @@ test_that("examples_env sets width", { test_that("test usage ok on rendered page", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/reference")) - expect_output(build_reference(pkg, topics = "c")) + suppressMessages(expect_message(build_reference(pkg, topics = "c"))) html <- xml2::read_html(file.path(pkg$dst_path, "reference", "c.html")) expect_equal(xpath_text(html, "//div[@id='ref-usage']", trim = TRUE), "c()") - clean_site(pkg) + clean_site(pkg, quiet = TRUE) pkg <- local_pkgdown_site(test_path("assets/reference"), " template: bootstrap: 5 ") - expect_output(init_site(pkg)) - expect_output(build_reference(pkg, topics = "c")) + suppressMessages(expect_message(init_site(pkg))) + suppressMessages(expect_message(build_reference(pkg, topics = "c"))) html <- xml2::read_html(file.path(pkg$dst_path, "reference", "c.html")) # tweak_anchors() moves id into

expect_equal(xpath_text(html, "//div[h2[@id='ref-usage']]/div", trim = TRUE), "c()") }) test_that(".Rd without usage doesn't get Usage section", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/reference")) - expect_output(build_reference(pkg, topics = "e")) + expect_snapshot(build_reference(pkg, topics = "e")) html <- xml2::read_html(file.path(pkg$dst_path, "reference", "e.html")) expect_equal(xpath_length(html, "//div[@id='ref-usage']"), 0) - clean_site(pkg) + clean_site(pkg, quiet = TRUE) pkg <- local_pkgdown_site(test_path("assets/reference"), " template: bootstrap: 5 ") - expect_output(init_site(pkg)) - expect_output(build_reference(pkg, topics = "e")) + suppressMessages(expect_message(init_site(pkg))) + expect_snapshot(build_reference(pkg, topics = "e")) html <- xml2::read_html(file.path(pkg$dst_path, "reference", "e.html")) # tweak_anchors() moves id into

expect_equal(xpath_length(html, "//div[h2[@id='ref-usage']]"), 0) @@ -68,8 +71,8 @@ test_that(".Rd without usage doesn't get Usage section", { test_that("pkgdown html dependencies are suppressed from examples in references", { pkg <- local_pkgdown_site(test_path("assets/reference-html-dep")) - expect_output(init_site(pkg)) - expect_output(build_reference(pkg, topics = "a")) + suppressMessages(expect_message(init_site(pkg))) + expect_snapshot(build_reference(pkg, topics = "a")) html <- xml2::read_html(file.path(pkg$dst_path, "reference", "a.html")) # jquery is only loaded once, even though it's included by an example diff --git a/tests/testthat/test-build-search-docs.R b/tests/testthat/test-build-search-docs.R index f39b4f1f6..ad61a7a86 100644 --- a/tests/testthat/test-build-search-docs.R +++ b/tests/testthat/test-build-search-docs.R @@ -1,7 +1,8 @@ test_that("docsearch.json and sitemap.xml are valid", { pkg <- local_pkgdown_site(test_path("assets/search-site")) - expect_output(build_site(pkg, new_process = FALSE)) + # can't use expect_snapshot() here because the dst_path is different each time + suppressMessages(expect_message(build_site(pkg, new_process = FALSE))) json <- path(pkg$dst_path, "docsearch.json") expect_true(jsonlite::validate(read_lines(json))) @@ -21,10 +22,13 @@ test_that("build_search() builds the expected search`.json with an URL", { mode: devel ') - expect_output(init_site(pkg)) - expect_output(build_news(pkg)) - expect_output(build_home(pkg)) - expect_output(build_sitemap(pkg)) + # can't use expect_snapshot() here because the dst_path is different each time + # expect_message caputres the messages from from build_* and init_site functions + # suppressMessages prevents the messages from spilling into the testthat results + suppressMessages(expect_message(init_site(pkg))) + suppressMessages(expect_message(build_news(pkg))) + suppressMessages(expect_message(build_home(pkg))) + suppressMessages(expect_message(build_sitemap(pkg))) json_path <- withr::local_tempfile() jsonlite::write_json(build_search_index(pkg), json_path, pretty = TRUE) @@ -41,10 +45,13 @@ test_that("build_search() builds the expected search.json with no URL", { mode: devel ') - expect_output(init_site(pkg)) - expect_output(build_news(pkg)) - expect_output(build_home(pkg)) - expect_output(build_sitemap(pkg)) + # expect_message caputres the messages from from build_* and init_site functions + # suppressMessages prevents the messages from spilling into the testthat results + + suppressMessages(expect_message(init_site(pkg))) + suppressMessages(expect_message(build_news(pkg))) + suppressMessages(expect_message(build_home(pkg))) + suppressMessages(expect_message(build_sitemap(pkg))) json_path <- withr::local_tempfile() jsonlite::write_json(build_search_index(pkg), json_path, pretty = TRUE) diff --git a/tests/testthat/test-check.R b/tests/testthat/test-check.R index 8dcfc6cfb..e3a9edb6b 100644 --- a/tests/testthat/test-check.R +++ b/tests/testthat/test-check.R @@ -1,4 +1,5 @@ test_that("fails if reference index incomplete", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/reference"), meta = " reference: - title: Title @@ -9,6 +10,7 @@ test_that("fails if reference index incomplete", { test_that("fails if article index incomplete", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/articles"), meta = " articles: - title: Title @@ -18,6 +20,7 @@ test_that("fails if article index incomplete", { }) test_that("informs if everything is ok", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/reference")) expect_snapshot(check_pkgdown(pkg)) }) diff --git a/tests/testthat/test-figure.R b/tests/testthat/test-figure.R index 5be80c383..05e45633e 100644 --- a/tests/testthat/test-figure.R +++ b/tests/testthat/test-figure.R @@ -1,16 +1,17 @@ test_that("can override defaults in _pkgdown.yml", { skip_if_no_pandoc() + local_edition(3) withr::local_temp_libpaths() pkg <- local_pkgdown_site(test_path("assets/figure")) callr::rcmd("INSTALL", pkg$src_path, show = FALSE, fail_on_status = TRUE) - expect_output(build_reference(pkg, devel = FALSE)) + expect_snapshot(build_reference(pkg, devel = FALSE)) img <- path_file(dir_ls(path(pkg$dst_path, "reference"), glob = "*.jpg")) expect_setequal(img, c("figure-1.jpg", "figure-2.jpg")) - expect_output(build_articles(pkg)) + expect_snapshot(build_articles(pkg)) img <- path_file(dir_ls(path(pkg$dst_path, "articles"), glob = "*.jpg", recurse = TRUE)) expect_equal(img, "unnamed-chunk-1-1.jpg") }) diff --git a/tests/testthat/test-init.R b/tests/testthat/test-init.R index 9f4a9cc91..7a7aefc1f 100644 --- a/tests/testthat/test-init.R +++ b/tests/testthat/test-init.R @@ -1,13 +1,14 @@ test_that("extra.css and extra.js copied and linked", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/init-extra-2")) - expect_output(init_site(pkg)) + suppressMessages(expect_message(init_site(pkg))) expect_true(file_exists(path(pkg$dst_path, "extra.css"))) expect_true(file_exists(path(pkg$dst_path, "extra.js"))) skip_if_no_pandoc() # Now check they actually get used . - expect_output(build_home(pkg)) + suppressMessages(expect_message(build_home(pkg))) html <- xml2::read_html(path(pkg$dst_path, "index.html")) paths <- xpath_attr(html, ".//link", "href") @@ -16,21 +17,24 @@ test_that("extra.css and extra.js copied and linked", { }) test_that("single extra.css correctly copied", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/init-extra-1")) - expect_output(init_site(pkg)) + suppressMessages(expect_message(init_site(pkg))) expect_true(file_exists(path(pkg$dst_path, "extra.css"))) }) test_that("asset subdirectories are copied", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/init-asset-subdirs")) - expect_output(init_site(pkg)) + suppressMessages(expect_message(init_site(pkg))) expect_true(file_exists(path(pkg$dst_path, "subdir1", "file1.txt"))) expect_true(file_exists(path(pkg$dst_path, "subdir1", "subdir2", "file2.txt"))) }) test_that("site meta doesn't break unexpectedly", { + local_edition(3) pkgdown <- as_pkgdown(test_path("assets/reference")) # null out components that will vary @@ -40,5 +44,5 @@ test_that("site meta doesn't break unexpectedly", { yaml$pandoc <- "{version}" yaml$last_built <- timestamp(as.POSIXct("2020-01-01", tz = "UTC")) - expect_snapshot_output(yaml) + expect_snapshot(yaml) }) diff --git a/tests/testthat/test-package.R b/tests/testthat/test-package.R index 22bbaff7c..01fef0a4f 100644 --- a/tests/testthat/test-package.R +++ b/tests/testthat/test-package.R @@ -14,7 +14,11 @@ test_that("check_bootstrap_version() allows 3, 4 (with warning), and 5", { }) test_that("check_bootstrap_version() gives informative error otherwise", { - expect_snapshot(check_bootstrap_version(1), error = TRUE) + local_edition(3) + pkg <- local_pkgdown_site(test_path("assets/articles")) + file_touch(file.path(pkg$src_path, "_pkgdown.yml")) + + expect_snapshot(check_bootstrap_version(1, pkg), error = TRUE) }) test_that("package_vignettes() moves vignettes/articles up one level", { diff --git a/tests/testthat/test-rd-example.R b/tests/testthat/test-rd-example.R index c53cd7511..b3cd337a5 100644 --- a/tests/testthat/test-rd-example.R +++ b/tests/testthat/test-rd-example.R @@ -52,6 +52,8 @@ test_that("extracts conditions from if", { }) test_that("@examplesIf", { + local_edition(3) + rd <- paste0( "\\dontshow{if (1 == 0) (if (getRversion() >= \"3.4\") withAutoprint else force)(\\{ # examplesIf}\n", "answer <- 43\n", @@ -88,8 +90,7 @@ test_that("@examplesIf", { "answer <- 43", "}" ) - expect_no_error(expect_warning( - expect_equal(strtrim(rd2ex(rd3), 40), strtrim(exp3, 40)), - "is FALSE" - )) + expect_snapshot( + expect_equal(strtrim(rd2ex(rd3), 40), strtrim(exp3, 40)) + ) }) diff --git a/tests/testthat/test-rd-html.R b/tests/testthat/test-rd-html.R index 98a240729..9d9305407 100644 --- a/tests/testthat/test-rd-html.R +++ b/tests/testthat/test-rd-html.R @@ -25,10 +25,13 @@ test_that("simple wrappers work as expected", { }) test_that("subsection generates h3", { - expect_snapshot(cat_line(rd2html("\\subsection{A}{B}"))) + local_edition(3) + expect_snapshot(cli::cat_line(rd2html("\\subsection{A}{B}"))) }) + test_that("subsection generates h3", { - expect_snapshot(cat_line(rd2html("\\subsection{A}{ + local_edition(3) + expect_snapshot(cli::cat_line(rd2html("\\subsection{A}{ p1 p2 @@ -45,7 +48,8 @@ test_that("subsection generates generated anchor", { }) test_that("nested subsection generates h4", { - expect_snapshot(cat_line(rd2html("\\subsection{H3}{\\subsection{H4}{}}"))) + local_edition(3) + expect_snapshot(cli::cat_line(rd2html("\\subsection{H3}{\\subsection{H4}{}}"))) }) test_that("if generates html", { @@ -171,8 +175,10 @@ test_that("Sexprs with multiple args are parsed", { }) test_that("Sexprs with multiple args are parsed", { + skip_if_not(getRversion() >= "4.0.0") + local_edition(3) local_context_eval() - expect_error(rd2html("\\Sexpr[results=verbatim]{1}"), "not yet supported") + expect_snapshot(rd2html("\\Sexpr[results=verbatim]{1}"), error = TRUE) }) test_that("Sexprs in file share environment", { @@ -278,6 +284,7 @@ test_that("link to non-existing functions return label", { }) test_that("bad specs throw errors", { + local_edition(3) expect_snapshot(error = TRUE, { rd2html("\\url{}") rd2html("\\url{a\nb}") diff --git a/tests/testthat/test-render.R b/tests/testthat/test-render.R index 77e5316b2..fe6d98043 100644 --- a/tests/testthat/test-render.R +++ b/tests/testthat/test-render.R @@ -1,7 +1,8 @@ test_that("check_bootswatch_theme() works", { - expect_equal(check_bootswatch_theme("_default", 4, list()), NULL) - expect_equal(check_bootswatch_theme("lux", 4, list()), "lux") - expect_snapshot_error(check_bootswatch_theme("paper", 4, list())) + pkg <- as_pkgdown(test_path("assets/reference")) + expect_equal(check_bootswatch_theme("_default", 4, pkg), NULL) + expect_equal(check_bootswatch_theme("lux", 4, pkg), "lux") + expect_snapshot_error(check_bootswatch_theme("paper", 4, pkg)) }) test_that("capture data_template()", { @@ -13,6 +14,7 @@ test_that("capture data_template()", { }) test_that("can include text in header, before body, and after body", { + local_edition(3) pkg <- local_pkgdown_site(test_path("assets/site-empty"), ' template: includes: @@ -34,7 +36,7 @@ test_that("can include text in header, before body, and after body", { ) pkg$bs_version <- 5 - expect_output(init_site(pkg)) + expect_message(init_site(pkg)) html <- render_page_html(pkg, "title-body") expect_equal( xpath_text(html, ".//test"), diff --git a/tests/testthat/test-rmarkdown.R b/tests/testthat/test-rmarkdown.R index c0ffe732d..24b3af222 100644 --- a/tests/testthat/test-rmarkdown.R +++ b/tests/testthat/test-rmarkdown.R @@ -1,9 +1,10 @@ test_that("render_rmarkdown copies image files in subdirectories", { + local_edition(3) skip_if_no_pandoc() tmp <- dir_create(file_temp()) pkg <- list(src_path = test_path("."), dst_path = tmp, bs_version = 3) - expect_output( + expect_snapshot( render_rmarkdown(pkg, "assets/vignette-with-img.Rmd", "test.html") ) expect_equal( @@ -13,6 +14,7 @@ test_that("render_rmarkdown copies image files in subdirectories", { }) test_that("render_rmarkdown yields useful error", { + local_edition(3) skip_on_cran() # fragile due to pandoc dependency skip_if_no_pandoc("2.18") @@ -27,10 +29,11 @@ test_that("render_rmarkdown yields useful error", { test_that("render_rmarkdown styles ANSI escapes", { skip_if_no_pandoc() + local_edition(3) tmp <- dir_create(file_temp()) pkg <- list(src_path = test_path("."), dst_path = tmp, bs_version = 5) - expect_output({ + expect_snapshot({ path <- render_rmarkdown(pkg, input = "assets/vignette-with-crayon.Rmd", output = "test.html" diff --git a/tests/testthat/test-sitrep.R b/tests/testthat/test-sitrep.R index bae4e8d7f..cbc709a83 100644 --- a/tests/testthat/test-sitrep.R +++ b/tests/testthat/test-sitrep.R @@ -1,11 +1,13 @@ test_that("pkgdown_sitrep works", { + local_edition(3) + # URL not in the pkgdown config pkg <- test_path("assets/figure") - expect_snapshot_output(pkgdown_sitrep(pkg)) + expect_snapshot(pkgdown_sitrep(pkg)) # URL only in the pkgdown config pkg <- test_path("assets/cname") - expect_snapshot_output(pkgdown_sitrep(pkg)) + expect_snapshot(pkgdown_sitrep(pkg)) # URL everywhere pkg <- test_path("assets/open-graph") - expect_snapshot_output(pkgdown_sitrep(pkg)) + expect_snapshot(pkgdown_sitrep(pkg)) }) diff --git a/tests/testthat/test-utils-yaml.R b/tests/testthat/test-utils-yaml.R index ebf8d2d7a..20477723f 100644 --- a/tests/testthat/test-utils-yaml.R +++ b/tests/testthat/test-utils-yaml.R @@ -1,17 +1,17 @@ -test_that("pkgdown_field(s) produces useful description", { - pkg <- local_pkgdown_site() - file_touch(file.path(pkg$src_path, "_pkgdown.yml")) - - expect_snapshot({ - pkgdown_field(pkg, c("a", "b")) - pkgdown_fields(pkg, list(c("a", "b"), "c")) - }) -}) +test_that("pkgdown_field produces useful description", { + local_edition(3) -test_that("pkgdown_field(s) produces useful description", { pkg <- local_pkgdown_site() file_touch(file.path(pkg$src_path, "_pkgdown.yml")) + expect_equal(pkgdown_field(pkg, c("a", "b")), "a.b") + expect_equal(pkgdown_field(pkg, c("a", "b"), fmt = TRUE), "{.field a.b}") + expect_equal(pkgdown_field(pkg, c("a"), cfg = TRUE), "a in _pkgdown.yml") + expect_equal( + pkgdown_field(pkg, c("a"), cfg = TRUE, fmt = TRUE), + "{.field a} in {.file _pkgdown.yml}" + ) + expect_snapshot(error = TRUE, { check_yaml_has("x", where = "a", pkg = pkg) check_yaml_has(c("x", "y"), where = "a", pkg = pkg)