diff --git a/NEWS.md b/NEWS.md index 2458e101..32566dd5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # roxygen2 (development version) +* Markdown links now do a better job of resolving package names: the process is cached for better performance (#1724); it works with infix operators (e.g. `[%in%]`) (#1728); no longer changes the link text (#1662); and includes base packages when reporting ambiguous functions (#1725). * Package documentation now uses `logo.svg` if available, falling back to `logo.png` (#1640). * `@family` no longer adds a trailing space after the colon in the default family prefix (#1628). Custom `rd_family_title` values now automatically get a colon appended if they don't already end with one (#1656). * `@inheritDotParams` now warns and produces no output when there are no parameters to inherit, instead of generating an empty `\describe` block that caused CRAN HTML validation warnings (#1671). diff --git a/R/markdown-link-resolve.R b/R/markdown-link-resolve.R new file mode 100644 index 00000000..09191642 --- /dev/null +++ b/R/markdown-link-resolve.R @@ -0,0 +1,151 @@ +find_package <- function(topic, tag = NULL) { + cur_pkg <- roxy_meta_get("current_package") + cur_pkg_dir <- roxy_meta_get("current_package_dir") + if (is.null(cur_pkg)) { + # Don't try and link in basic tests + return(NA_character_) + } + + pkg <- find_package_cached(topic, pkg = cur_pkg, pkg_dir = cur_pkg_dir) + if (length(pkg) == 0) { + warn_roxy_tag( + tag, + c( + "Could not resolve link to topic {.val {topic}} in the dependencies or base packages.", + "i" = paste( + "If you haven't documented {.val {topic}} yet, or just changed its name, this is normal.", + "Once {.val {topic}} is documented, this warning goes away." + ), + "i" = "Make sure that the name of the topic is spelled correctly.", + "i" = "Always list the linked package as a dependency.", + "i" = "Alternatively, you can fully qualify the link with a package name." + ) + ) + NA_character_ + } else if (length(pkg) == 1) { + pkg + } else { + warn_roxy_tag( + tag, + c( + "Topic {.val {topic}} is available in multiple packages: {.pkg {pkg}}.", + i = "Qualify topic explicitly with a package name when linking to it." + ) + ) + NA_character_ + } +} + +find_package_cache <- new_environment() +# run in roxygenize() because the documented functions might change between runs +find_package_cache_reset <- function() { + env_unbind(find_package_cache, env_names(find_package_cache)) + + # also reset the cache used by dev_help() (used by has_topic()) + pkg <- roxy_meta_get("current_package") + if (!is.null(pkg)) pkgload::dev_topic_index_reset(pkg) +} +find_package_cached <- function(topic, pkg, pkg_dir) { + key <- paste0(pkg, "::", topic) + env_cache(find_package_cache, key, find_package_lookup(topic, pkg, pkg_dir)) +} + +# NA_character = found, doesn't need qualification +# character(0) = not found +# character(1) = one match +# character(>1) = multiple matches +find_package_lookup <- function(topic, pkg, pkg_dir) { + # if it is in the current package, then no need for package name + if (has_topic(topic, pkg)) { + return(NA_character_) + } + + pkgs <- pkg_deps(pkg_dir) + pkg_has_topic <- pkgs[map_lgl(pkgs, has_topic, topic = topic)] + pkg_has_topic <- map_chr(pkg_has_topic, \(pkg) find_source(topic, pkg)) + pkg_has_topic <- unique(pkg_has_topic) + + base <- base_packages() + if (length(pkg_has_topic) == 0) { + # can't find it anywhere + character() + } else if (length(pkg_has_topic) == 1) { + if (pkg_has_topic %in% base) { + # never qualify links to base packages + NA_character_ + } else { + pkg_has_topic + } + } else if (all(pkg_has_topic %in% base)) { + # multiple base packages, no qualification needed + NA_character_ + } else { + pkg_has_topic + } +} + +pkg_deps <- function(pkgdir) { + deps <- desc::desc_get_deps(pkgdir) + deps <- deps[deps$package != "R", ] + deps <- deps[deps$type %in% c("Depends", "Imports", "Suggests"), ] + c(deps$package, base_packages()) +} + +base_packages <- function() { + if (getRversion() >= "4.4.0") { + asNamespace("tools")$standard_package_names()[["base"]] + } else { + c( + "base", + "compiler", + "datasets", + "graphics", + "grDevices", + "grid", + "methods", + "parallel", + "splines", + "stats", + "stats4", + "tcltk", + "tools", + "utils" + ) + } +} + +# Adapted from downlit:::find_reexport_source +find_source <- function(topic, package) { + if (package %in% base_packages()) { + return(package) + } + + ns <- ns_env(package) + if (!env_has(ns, topic, inherit = TRUE)) { + return(package) + } + + obj <- env_get(ns, topic, inherit = TRUE) + if (is.primitive(obj)) { + # primitive functions all live in base + "base" + } else if (is.function(obj)) { + ## For functions, we can just take their environment. + ns_env_name(get_env(obj)) + } else { + ## For other objects, we need to check the import env of the package, + ## to see where 'topic' is coming from. The import env has redundant + ## information. It seems that we just need to find a named list + ## entry that contains `topic`. + imp <- getNamespaceImports(ns) + imp <- imp[names(imp) != ""] + wpkgs <- map_lgl(imp, `%in%`, x = topic) + if (!any(wpkgs)) { + return(package) + } + + pkgs <- names(wpkgs)[wpkgs] + # Take the last match, in case imports have name clashes. + pkgs[[length(pkgs)]] + } +} diff --git a/R/markdown-link.R b/R/markdown-link.R index 01607a1b..0b412aa4 100644 --- a/R/markdown-link.R +++ b/R/markdown-link.R @@ -131,22 +131,26 @@ parse_link <- function(destination, contents, state) { thispkg <- roxy_meta_get("current_package") %||% "" is_code <- is_code || (grepl("[(][)]$", destination) && !has_link_text) pkg <- str_match(destination, "^(.*)::")[1, 2] - pkg <- gsub("%", "\\\\%", pkg) + explicit_pkg <- !is.na(pkg) fun <- utils::tail(strsplit(destination, "::", fixed = TRUE)[[1]], 1) - fun <- gsub("%", "\\\\%", fun) is_fun <- grepl("[(][)]$", fun) obj <- sub("[(][)]$", "", fun) s4 <- str_detect(destination, "-class$") noclass <- str_match(fun, "^(.*)-class$")[1, 2] + # Lookup topic using unescaped names, then escape % for Rd output if (is.na(pkg)) { - pkg <- resolve_link_package(obj, thispkg, state = state) - } - if (!is.na(pkg) && pkg == thispkg) { + pkg <- find_package(obj, tag = state$tag) + } else if (!is.na(pkg) && pkg == thispkg) { pkg <- NA_character_ } file <- find_topic_filename(pkg, obj, state$tag) + pkg <- gsub("%", "\\\\%", pkg) + fun <- gsub("%", "\\\\%", fun) + obj <- gsub("%", "\\\\%", obj) + noclass <- gsub("%", "\\\\%", noclass) + ## To understand this, look at the RD column of the table above if (!has_link_text) { paste0( @@ -157,7 +161,7 @@ parse_link <- function(destination, contents, state) { if (!is.na(pkg)) paste0(pkg, ":"), if (is_fun || !is.na(pkg)) paste0(if (is.na(pkg)) obj else file, "]"), "{", - if (!is.na(pkg)) paste0(pkg, "::"), + if (explicit_pkg && !is.na(pkg)) paste0(pkg, "::"), if (s4) noclass else fun, "}", if (is_code) "}" else "" @@ -180,119 +184,6 @@ parse_link <- function(destination, contents, state) { } } -resolve_link_package <- function( - topic, - me = NULL, - pkgdir = NULL, - state = NULL -) { - me <- me %||% roxy_meta_get("current_package") - # this is from the roxygen2 tests, should not happen on a real package - if (is.null(me) || is.na(me) || me == "") { - return(NA_character_) - } - - # if it is in the current package, then no need for package name, right? - if (has_topic(topic, me)) { - return(NA_character_) - } - - # try packages in depends, imports, suggests first, error on name clashes - pkgs <- local_pkg_deps(pkgdir) - - pkg_has_topic <- pkgs[map_lgl(pkgs, has_topic, topic = topic)] - pkg_has_topic <- map_chr(pkg_has_topic, function(p) { - p0 <- find_reexport_source(topic, p) - if (is.na(p0)) p else p0 - }) - pkg_has_topic <- unique(pkg_has_topic) - base <- base_packages() - if (length(pkg_has_topic) == 0) { - # fall through to check base packages as well - } else if (length(pkg_has_topic) == 1) { - if (pkg_has_topic %in% base) { - return(NA_character_) - } else { - return(pkg_has_topic) - } - } else { - warn_roxy_tag( - state$tag, - c( - "Topic {.val {topic}} is available in multiple packages: {.pkg {pkg_has_topic}}", - i = "Qualify topic explicitly with a package name when linking to it." - ) - ) - return(NA_character_) - } - - # try base packages as well, take the first hit, - # there should not be any name clashes, anyway - for (bp in base) { - if (has_topic(topic, bp)) return(NA_character_) - } - - warn_roxy_tag( - state$tag, - c( - "Could not resolve link to topic {.val {topic}} in the dependencies or base packages", - "i" = paste( - "If you haven't documented {.val {topic}} yet, or just changed its name, this is normal.", - "Once {.val {topic}} is documented, this warning goes away." - ), - "i" = "Make sure that the name of the topic is spelled correctly.", - "i" = "Always list the linked package as a dependency.", - "i" = "Alternatively, you can fully qualify the link with a package name." - ) - ) - - NA_character_ -} - -# this is mostly from downlit -is_exported <- function(name, package) { - name %in% getNamespaceExports(ns_env(package)) -} - -is_reexported <- function(name, package) { - if (package == "base") { - return(FALSE) - } - is_imported <- env_has(ns_imports_env(package), name) - is_imported && is_exported(name, package) -} - -find_reexport_source <- function(topic, package) { - ns <- ns_env(package) - if (!env_has(ns, topic, inherit = TRUE)) { - return(NA_character_) - } - - obj <- env_get(ns, topic, inherit = TRUE) - if (is.primitive(obj)) { - # primitive functions all live in base - "base" - } else if (is.function(obj)) { - ## For functions, we can just take their environment. - ns_env_name(get_env(obj)) - } else { - ## For other objects, we need to check the import env of the package, - ## to see where 'topic' is coming from. The import env has redundant - ## information. It seems that we just need to find a named list - ## entry that contains `topic`. - imp <- getNamespaceImports(ns) - imp <- imp[names(imp) != ""] - wpkgs <- vapply(imp, `%in%`, x = topic, FUN.VALUE = logical(1)) - - if (!any(wpkgs)) { - return(NA_character_) - } - pkgs <- names(wpkgs)[wpkgs] - # Take the last match, in case imports have name clashes. - pkgs[[length(pkgs)]] - } -} - #' Dummy page to test roxygen's markdown formatting #' #' Links are very tricky, so I'll put in some links here: diff --git a/R/markdown.R b/R/markdown.R index 8844d73f..f8455bf0 100644 --- a/R/markdown.R +++ b/R/markdown.R @@ -17,8 +17,6 @@ markdown <- function(text, tag = NULL, sections = FALSE) { ) } -mddata <- new.env(parent = emptyenv()) - #' Expand the embedded inline code #' #' @details @@ -70,7 +68,6 @@ mddata <- new.env(parent = emptyenv()) #' @keywords internal markdown_pass1 <- function(text) { - rm(list = ls(envir = mddata), envir = mddata) text <- paste(text, collapse = "\n") mdxml <- xml_ns_strip(md_to_mdxml(text, sourcepos = TRUE)) code_nodes <- xml_find_all(mdxml, ".//code | .//code_block") diff --git a/R/roxygenize.R b/R/roxygenize.R index 9cf349da..7c139822 100644 --- a/R/roxygenize.R +++ b/R/roxygenize.R @@ -33,6 +33,7 @@ roxygenize <- function( base_path <- normalizePath(package.dir) is_first <- roxygen_setup(base_path) + find_package_cache_reset() roxy_meta_load(base_path) # Load required packages for method registration packages <- roxy_meta_get("packages") diff --git a/R/utils-warn.R b/R/utils-warn.R index 41a44b79..3d0b5d88 100644 --- a/R/utils-warn.R +++ b/R/utils-warn.R @@ -1,6 +1,12 @@ #' @export #' @rdname roxy_tag warn_roxy_tag <- function(tag, message, parent = NULL, envir = parent.frame()) { + if (is.null(tag)) { + names(message)[[1]] <- "x" + cli::cli_inform(message, parent = parent, .envir = envir) + return(invisible()) + } + tag_name <- cli::format_inline("{.strong @{tag$tag}} ") if (is.null(tag$raw)) { tag_name <- paste(tag_name, "(automatically generated) ") diff --git a/R/utils.R b/R/utils.R index 798a5875..4a2cdaee 100644 --- a/R/utils.R +++ b/R/utils.R @@ -234,41 +234,3 @@ auto_quote <- function(x) { is_syntactic <- function(x) make.names(x) == x has_quotes <- function(x) str_detect(x, r"[^(`|'|").*\1$]") strip_quotes <- function(x) str_replace(x, r"[^(`|'|")(.*)\1$]", r"(\2)") - -base_packages <- function() { - if (getRversion() >= "4.4.0") { - asNamespace("tools")$standard_package_names()[["base"]] - } else { - c( - "base", - "compiler", - "datasets", - "graphics", - "grDevices", - "grid", - "methods", - "parallel", - "splines", - "stats", - "stats4", - "tcltk", - "tools", - "utils" - ) - } -} - -# Note that this caches the result regardless of -# pkgdir! pkgdir is mainly for testing, in which case you -# need to clear the cache manually. - -local_pkg_deps <- function(pkgdir = NULL) { - if (!is.null(mddata[["deps"]])) { - return(mddata[["deps"]]) - } - pkgdir <- pkgdir %||% roxy_meta_get("current_package_dir") - deps <- desc::desc_get_deps(pkgdir) - deps <- deps[deps$package != "R", ] - deps <- deps[deps$type %in% c("Depends", "Imports", "Suggests"), ] - deps$package -} diff --git a/tests/testthat/_snaps/markdown-link-resolve.md b/tests/testthat/_snaps/markdown-link-resolve.md new file mode 100644 index 00000000..af1a5318 --- /dev/null +++ b/tests/testthat/_snaps/markdown-link-resolve.md @@ -0,0 +1,19 @@ +# useful warning if no topic found + + Code + . <- find_package("doesntexist") + Message + x Could not resolve link to topic "doesntexist" in the dependencies or base packages. + i If you haven't documented "doesntexist" yet, or just changed its name, this is normal. Once "doesntexist" is documented, this warning goes away. + i Make sure that the name of the topic is spelled correctly. + i Always list the linked package as a dependency. + i Alternatively, you can fully qualify the link with a package name. + +# gives useful warning if same name in multiple packages + + Code + . <- find_package("pkg_env") + Message + x Topic "pkg_env" is available in multiple packages: pkgload and rlang. + i Qualify topic explicitly with a package name when linking to it. + diff --git a/tests/testthat/_snaps/markdown-link.md b/tests/testthat/_snaps/markdown-link.md index 12543453..1e5dff8f 100644 --- a/tests/testthat/_snaps/markdown-link.md +++ b/tests/testthat/_snaps/markdown-link.md @@ -19,43 +19,3 @@ Message x :4: @description refers to unavailable topic stringr::bar111. -# resolve_link_package - - Code - resolve_link_package("roxygenize", "roxygen2", test_path("testMdLinks2")) - Output - [1] NA - Code - resolve_link_package("UseMethod", "roxygen2", test_path("testMdLinks2")) - Output - [1] NA - Code - resolve_link_package("cli_abort", "roxygen2", test_path("testMdLinks2")) - Output - [1] "cli" - ---- - - Code - resolve_link_package("aa3bc042880aa3b64fef1a9", "roxygen2", test_path( - "testMdLinks2"), list(tag = tag)) - Message - x foo.R:10: @title (automatically generated) Could not resolve link to topic "aa3bc042880aa3b64fef1a9" in the dependencies or base packages. - i If you haven't documented "aa3bc042880aa3b64fef1a9" yet, or just changed its name, this is normal. Once "aa3bc042880aa3b64fef1a9" is documented, this warning goes away. - i Make sure that the name of the topic is spelled correctly. - i Always list the linked package as a dependency. - i Alternatively, you can fully qualify the link with a package name. - Output - [1] NA - -# resolve_link_package name clash - - Code - resolve_link_package("pkg_env", "roxygen2", test_path("testMdLinks2"), list( - tag = tag)) - Message - x foo.R:10: @title (automatically generated) Topic "pkg_env" is available in multiple packages: pkgload and rlang. - i Qualify topic explicitly with a package name when linking to it. - Output - [1] NA - diff --git a/tests/testthat/test-markdown-link-resolve.R b/tests/testthat/test-markdown-link-resolve.R new file mode 100644 index 00000000..5bb212d3 --- /dev/null +++ b/tests/testthat/test-markdown-link-resolve.R @@ -0,0 +1,85 @@ +test_that("don't resolve if current_package not set", { + expect_equal(find_package("cli_abort"), NA_character_) +}) + +test_that("topics in current package don't need qualification", { + local_roxy_meta_set("current_package", "cli") + expect_equal(find_package("cli_abort"), NA_character_) +}) + +test_that("imported functions qualified with package name", { + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + expect_equal(find_package("cli_abort"), "cli") +}) + +test_that("base functions don't need qualification", { + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + expect_equal(find_package("mean"), NA_character_) +}) + +test_that("base functions re-exported by deps don't need qualification", { + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + expect_equal(find_package("is.null"), NA_character_) +}) + +test_that("useful warning if no topic found", { + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + expect_snapshot(. <- find_package("doesntexist")) +}) + +test_that("re-exported topics are identified", { + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + expect_equal(. <- find_package("process"), "processx") +}) + +test_that("gives useful warning if same name in multiple packages", { + skip_on_cran() # in case pkgload/rlang changes this + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + expect_equal( + find_package_lookup("pkg_env", "testMdLinks", test_path("testMdLinks")), + c("pkgload", "rlang") + ) + + expect_snapshot(. <- find_package("pkg_env")) +}) + + +test_that("topic found in multiple base packages doesn't warn", { + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + # plot is in both base and graphics + expect_no_message(expect_equal(find_package("plot"), NA_character_)) +}) + +test_that("find_source handles simple cases", { + skip_on_cran() # since depends on other packages + + # in base package + expect_equal(find_source("list", "base"), "base") + # topic not in namespace + expect_equal(find_source("doesnt'exist", "cli"), "cli") + # primitive objects are always in base + expect_equal(find_source("is_null", "rlang"), "base") + # callr re-exports process from processx + expect_equal(find_source("process", "callr"), "processx") +}) + +test_that("find_source traces re-exported non-function to source package", { + # .data is a non-function object exported by rlang, re-exported by others + skip_on_cran() + skip_if_not_installed("tidyselect") + expect_equal(find_source(".data", "tidyselect"), "rlang") +}) diff --git a/tests/testthat/test-markdown-link.R b/tests/testthat/test-markdown-link.R index 833fb472..450a151e 100644 --- a/tests/testthat/test-markdown-link.R +++ b/tests/testthat/test-markdown-link.R @@ -52,6 +52,8 @@ test_that("% in links are escaped", { expect_equal(markdown("[%][x]"), r"(\link[=x]{\%})") expect_equal(markdown("[%%]"), r"(\link{\%\%})") expect_equal(markdown("[base::%%]"), r"(\link[base:Arithmetic]{base::\%\%})") + # %in% can be resolved to base package (#1728) + expect_equal(markdown("[%in%]"), r"(\link{\%in\%})") }) test_that("{ and } in links are escaped (#1259)", { @@ -581,6 +583,16 @@ test_that("linking to self is unqualified", { ) }) +test_that("resolved links don't change link text (#1662)", { + local_roxy_meta_set("current_package", "testMdLinks") + local_roxy_meta_set("current_package_dir", test_path("testMdLinks")) + + expect_equal( + markdown("[cli_abort()]"), + r"(\code{\link[cli:cli_abort]{cli_abort()}})" + ) +}) + test_that("percents are escaped in link targets", { out1 <- roc_proc_text( rd_roclet(), @@ -602,56 +614,3 @@ test_that("percents are escaped in link targets", { )[[1]] expect_equivalent_rd(out1, out2) }) - -test_that("resolve_link_package", { - # Doesn't work with - skip_if_not( - is.null(.getNamespace("roxygen2")[[".__DEVTOOLS__"]]), - "roxygen2 loaded with devtools" - ) - rm(list = ls(envir = mddata), envir = mddata) - expect_snapshot({ - resolve_link_package("roxygenize", "roxygen2", test_path("testMdLinks2")) - resolve_link_package("UseMethod", "roxygen2", test_path("testMdLinks2")) - resolve_link_package("cli_abort", "roxygen2", test_path("testMdLinks2")) - }) - - tag <- roxy_tag("title", NULL, NULL, file = "foo.R", line = 10) - expect_snapshot({ - resolve_link_package( - "aa3bc042880aa3b64fef1a9", - "roxygen2", - test_path("testMdLinks2"), - list(tag = tag) - ) - }) - # re-exported topics are identified - rm(list = ls(envir = mddata), envir = mddata) - expect_equal( - resolve_link_package("process", "testthat", test_path("testMdLinks")), - "processx" - ) -}) - -test_that("resolve_link_package name clash", { - # skip in case pkgload/rlang changes this - skip_on_cran() - tag <- roxy_tag("title", NULL, NULL, file = "foo.R", line = 10) - expect_snapshot({ - resolve_link_package( - "pkg_env", - "roxygen2", - test_path("testMdLinks2"), - list(tag = tag) - ) - }) -}) - -test_that("is_reexported", { - expect_false(is_reexported("process", "processx")) - expect_true(is_reexported("process", "callr")) -}) - -test_that("find_reexport_source", { - expect_equal(find_reexport_source("process", "callr"), "processx") -}) diff --git a/tests/testthat/testMdLinks/DESCRIPTION b/tests/testthat/testMdLinks/DESCRIPTION index 0d38b02d..0cead249 100644 --- a/tests/testthat/testMdLinks/DESCRIPTION +++ b/tests/testthat/testMdLinks/DESCRIPTION @@ -1,58 +1,9 @@ -Package: testthat -Title: Unit Testing for R -Version: 3.2.1.9000 -Authors@R: c( - person("Hadley", "Wickham", , "hadley@posit.co", role = c("aut", "cre")), - person("Posit Software, PBC", role = c("cph", "fnd")), - person("R Core team", role = "ctb", - comment = "Implementation of utils::recover()") - ) -Description: Software testing is important, but, in part because it is - frustrating and boring, many of us avoid it. 'testthat' is a testing - framework for R that is easy to learn and use, and integrates with - your existing 'workflow'. -License: MIT + file LICENSE -URL: https://testthat.r-lib.org, https://github.com/r-lib/testthat -BugReports: https://github.com/r-lib/testthat/issues -Depends: - R (>= 3.6.0) +Package: testMdLinks +Title: Dummy package for testing markdown link resolution +Version: 1.0.0 Imports: - brio (>= 1.1.3), - callr (>= 3.7.3), - cli (>= 3.6.1), - desc (>= 1.4.2), - digest (>= 0.6.33), - evaluate (>= 0.21), - jsonlite (>= 1.8.7), - lifecycle (>= 1.0.3), - magrittr (>= 2.0.3), - methods, - pkgload (>= 1.3.2.1), - praise (>= 1.0.0), - processx (>= 3.8.2), - ps (>= 1.7.5), - R6 (>= 2.5.1), - rlang (>= 1.1.1), - utils, - waldo (>= 0.5.1), - withr (>= 2.5.0) -Suggests: - covr, - curl (>= 0.9.5), - diffviewer (>= 0.1.0), - knitr, - rmarkdown, - rstudioapi, - shiny, - usethis, - vctrs (>= 0.1.0), - xml2 -VignetteBuilder: - knitr -Config/Needs/website: tidyverse/tidytemplate -Config/testthat/edition: 3 -Config/testthat/parallel: true -Config/testthat/start-first: watcher, parallel* -Encoding: UTF-8 -Roxygen: list(markdown = TRUE, r6 = FALSE) -RoxygenNote: 7.2.3 + callr, + processx, + cli, + pkgload, + rlang diff --git a/tests/testthat/testMdLinks2/DESCRIPTION b/tests/testthat/testMdLinks2/DESCRIPTION deleted file mode 100644 index d37a0f02..00000000 --- a/tests/testthat/testMdLinks2/DESCRIPTION +++ /dev/null @@ -1,56 +0,0 @@ -Package: roxygen2 -Title: In-Line Documentation for R -Version: 7.3.2.9000 -Authors@R: c( - person("Hadley", "Wickham", , "hadley@posit.co", role = c("aut", "cre", "cph"), - comment = c(ORCID = "0000-0003-4757-117X")), - person("Peter", "Danenberg", , "pcd@roxygen.org", role = c("aut", "cph")), - person("Gábor", "Csárdi", , "csardi.gabor@gmail.com", role = "aut"), - person("Manuel", "Eugster", role = c("aut", "cph")), - person("Posit Software, PBC", role = c("cph", "fnd")) - ) -Description: Generate your Rd documentation, 'NAMESPACE' file, and - collation field using specially formatted comments. Writing - documentation in-line with code makes it easier to keep your - documentation up-to-date as your requirements change. 'roxygen2' is - inspired by the 'Doxygen' system for C++. -License: MIT + file LICENSE -URL: https://roxygen2.r-lib.org/, https://github.com/r-lib/roxygen2 -BugReports: https://github.com/r-lib/roxygen2/issues -Depends: - R (>= 3.6) -Imports: - brew, - cli (>= 3.3.0), - commonmark, - desc (>= 1.2.0), - knitr, - methods, - pkgload (>= 1.0.2), - purrr (>= 1.0.0), - R6 (>= 2.1.2), - rlang (>= 1.0.6), - stringi, - stringr (>= 1.0.0), - utils, - withr, - xml2 -Suggests: - covr, - R.methodsS3, - R.oo, - rmarkdown (>= 2.16), - testthat (>= 3.1.2), - yaml -LinkingTo: - cpp11 -VignetteBuilder: - knitr -Config/Needs/development: testthat -Config/Needs/website: tidyverse/tidytemplate -Config/testthat/edition: 3 -Config/testthat/parallel: TRUE -Encoding: UTF-8 -Language: en-GB -Roxygen: list(markdown = TRUE, load = "installed") -RoxygenNote: 7.3.2.9000