Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export(build_vignettes)
export(check)
export(check_built)
export(check_dep_version)
export(check_doc_fields)
export(check_mac_devel)
export(check_mac_release)
export(check_man)
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* `bash()`, `create()`, `missing_s3()`, `reload()`, `show_news()`, and `wd()` are now deprecated. These functions are all historical parts of our workflow that we no longer use or recommend. `create()` is superseded by `usethis::create_package()`.
* `build_manual()` reports more details on failure (#2586).
* `check_doc_fields()` is a new function that checks for missing `\value` and `\examples` fields in Rd files, which are commonly flagged by CRAN (#2525).
* `build_vignettes()` and `clean_vignettes()` are now deprecated. We no longer recommend building vignettes in this way; instead use `pkgdown::build_article()` to render articles locally (#2488).
* `build_site()` now just calls `pkgdown::build_site()`, meaning that you will get more (informative) output by default (#2578).
* New `check_mac_devel()` function to check a package using the macOS builder at https://mac.r-project.org/macbuilder/submit.html (@nfrerebeau, #2507)
Expand Down
51 changes: 51 additions & 0 deletions R/check-doc.R
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,54 @@ man_message <- function(x) {
FALSE
}
}

#' Check for missing documentation fields
#'
#' Checks all Rd files in `man/` and looks for any that have a `\usage` section
#' (i.e. a function) but that *don't* have `\value` and `\examples` sections.
#' These missing fields are flagged by CRAN on initial submission.
#'
#' @template devtools
#' @param fields A character vector of Rd field names to check for.
#' @returns A named list of character vectors, one for each field, containing
#' the names of Rd files missing that field. Returned invisibly.
#' @export
#' @examples
#' \dontrun{
#' check_doc_fields(".")
#' }
check_doc_fields <- function(pkg = ".", fields = c("value", "examples")) {
pkg <- as.package(pkg)
fields <- stats::setNames(fields, fields)

paths <- dir_ls(path(pkg$path, "man"), regexp = "\\.Rd$")
names(paths) <- path_rel(paths, pkg$path)
rd <- lapply(paths, tools::parse_Rd, permissive = TRUE)
rd_tags <- lapply(rd, \(x) unlist(lapply(x, attr, "Rd_tag")))

has_tag <- function(tags, this) {
any(paste0("\\", this) %in% tags)
}

has_usage <- vapply(rd_tags, has_tag, logical(1), this = "usage")
rd_tags <- rd_tags[has_usage]

results <- lapply(fields, function(field) {
missing <- !vapply(rd_tags, has_tag, logical(1), this = field)
names(rd_tags)[missing]
})

for (field in fields) {
missing <- results[[field]]
if (length(missing) > 0) {
cli::cli_inform(c(
"!" = "Missing {.code \\{field}} section in {length(missing)} file{?s}:",
stats::setNames(missing, rep("*", length(missing)))
))
} else {
cli::cli_inform(c("v" = "All Rd files have a {.code \\{field}} section."))
}
}

invisible(results)
}
28 changes: 28 additions & 0 deletions man/check_doc_fields.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions tests/testthat/_snaps/check-doc.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# check_doc_fields output - missing fields

Code
check_doc_fields(pkg)
Message
! Missing `\value` section in 1 file:
* man/foo.Rd
! Missing `\examples` section in 1 file:
* man/bar.Rd

# check_doc_fields output - all present

Code
check_doc_fields(pkg)
Message
v All Rd files have a `\value` section.
v All Rd files have a `\examples` section.

# check_man works

Code
Expand Down
28 changes: 28 additions & 0 deletions tests/testthat/test-check-doc.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
test_that("check_doc_fields output - missing fields", {
pkg <- local_package_create()
dir.create(file.path(pkg, "man"))

writeLines(
"\\name{foo}\\title{Foo}\\usage{foo()}\\description{A function.}\\examples{foo()}",
file.path(pkg, "man", "foo.Rd")
)
writeLines(
"\\name{bar}\\title{Bar}\\usage{foo()}\\description{A function.}\\value{Something.}",
file.path(pkg, "man", "bar.Rd")
)

expect_snapshot(check_doc_fields(pkg))
})

test_that("check_doc_fields output - all present", {
pkg <- local_package_create()
dir.create(file.path(pkg, "man"))

writeLines(
"\\name{foo}\\title{Foo}\\usage{foo()}\\description{A function.}\\value{A value.}\\examples{foo()}",
file.path(pkg, "man", "foo.Rd")
)

expect_snapshot(check_doc_fields(pkg))
})

test_that("check_man works", {
# tools:::.check_Rd_xrefs which is called by `check_man()` assumes the base
# and recommended packages will all be in the library path, which is not the
Expand Down