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
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: tinyrox
Title: Minimal R Documentation Generator
Version: 0.3.3.1
Version: 0.3.3.2
Authors@R:
person("Troy", "Hernandez", email = "troy@cornball.ai", role = c("aut", "cre"),
comment = c(ORCID = "0009-0005-4248-604X"))
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# tinyrox 0.3.3.2

* Fix false "undocumented parameters" warning for functions documented via a sibling block in an `@rdname` group; the check is now group-wide. Also gate the warning on `cran_check` rather than `silent` (#12).

# tinyrox 0.3.1

* Replace internal `utils:::.getHelpFile()` call with `tools::parse_Rd()` for CRAN compliance.
Expand Down
34 changes: 25 additions & 9 deletions R/document.R
Original file line number Diff line number Diff line change
Expand Up @@ -57,31 +57,47 @@ document <- function(path = ".",
}

# Parse all R files
if (!silent) message("Parsing R files...")
if (!silent) {
message("Parsing R files...")
}
blocks <- parse_package(path)

if (length(blocks) == 0) {
if (!silent) message("No documentation blocks found.")
if (!silent) {
message("No documentation blocks found.")
}
return(invisible(list(rd_files = character(), namespace = NULL)))
}

if (!silent) message("Found ", length(blocks), " documentation block(s).")
if (!silent) {
message("Found ", length(blocks), " documentation block(s).")
}

# Generate Rd files
if (!silent) message("Generating Rd files...")
rd_files <- generate_all_rd(blocks, path, silent)
if (!silent) message("Generated ", length(rd_files), " Rd file(s).")
if (!silent) {
message("Generating Rd files...")
}
rd_files <- generate_all_rd(blocks, path, cran_check)
if (!silent) {
message("Generated ", length(rd_files), " Rd file(s).")
}

# Generate NAMESPACE
ns_file <- NULL
if (namespace != "none") {
if (!silent) message("Generating NAMESPACE...")
if (!silent) {
message("Generating NAMESPACE...")
}
ns_content <- generate_namespace(blocks)
ns_file <- write_namespace(ns_content, path, namespace)
if (!silent) message("Updated NAMESPACE.")
if (!silent) {
message("Updated NAMESPACE.")
}
}

if (!silent) message("Leaving DESCRIPTION alone as one should.")
if (!silent) {
message("Leaving DESCRIPTION alone as one should.")
}

invisible(list(rd_files = rd_files, namespace = ns_file))
}
Expand Down
49 changes: 34 additions & 15 deletions R/rd.R
Original file line number Diff line number Diff line change
Expand Up @@ -669,10 +669,11 @@ generate_rd_grouped <- function(topic, entries, all_tags,
#'
#' @param blocks List of documentation blocks from parse_package().
#' @param path Package root path.
#' @param silent Boolean flag whether operation whould be silent
#' @param cran_check Emit CRAN-compliance warnings (undocumented
#' parameters). Default TRUE.
#' @return Character vector of generated file paths.
#' @keywords internal
generate_all_rd <- function(blocks, path = ".", silent = FALSE) {
generate_all_rd <- function(blocks, path = ".", cran_check = TRUE) {
generated <- character()

# Find package-defined S3 generics for proper \method{}{} usage formatting
Expand Down Expand Up @@ -772,12 +773,13 @@ generate_all_rd <- function(blocks, path = ".", silent = FALSE) {
generated <- c(generated, filepath)

# Warn about undocumented params
if (block$type %in% c("function", "nn_module") &&
if (cran_check &&
block$type %in% c("function", "nn_module") &&
!is.null(block$formals)) {
formal_names <- block$formals$names
undoc <- setdiff(formal_names, names(tags$params))
undoc <- setdiff(undoc, "...")
if (length(undoc) > 0 && !silent) {
if (length(undoc) > 0) {
warning("Undocumented parameters in ", tags$name, ": ",
paste(undoc, collapse = ", "),
call. = FALSE)
Expand All @@ -789,17 +791,34 @@ generate_all_rd <- function(blocks, path = ".", silent = FALSE) {
filepath <- write_rd(rd_content, topic, path)
generated <- c(generated, filepath)

# Warn about undocumented params across all entries
for (entry in entries) {
if (entry$block$type %in% c("function", "nn_module") &&
!is.null(entry$block$formals)) {
formal_names <- entry$block$formals$names
undoc <- setdiff(formal_names, names(entry$tags$params))
undoc <- setdiff(undoc, "...")
if (length(undoc) > 0 && !silent) {
warning("Undocumented parameters in ", entry$tags$name, ": ",
paste(undoc, collapse = ", "),
call. = FALSE)
# Warn about undocumented params. Blocks sharing an @rdname
# merge into one page, so a parameter is documented if ANY
# block in the group documents it (matching the param merge in
# generate_rd_grouped()). Check each function's formals against
# the group-wide union, with @inheritParams resolved.
if (cran_check) {
documented <- character()
for (entry in entries) {
etags <- entry$tags
if (length(etags$inheritParams) > 0) {
etags <- resolve_inherit_params(etags, all_tags,
entry$block$formals)
}
documented <- c(documented, names(etags$params))
}
documented <- unique(documented)
for (entry in entries) {
if (entry$block$type %in% c("function", "nn_module") &&
!is.null(entry$block$formals)) {
formal_names <- entry$block$formals$names
undoc <- setdiff(formal_names, documented)
undoc <- setdiff(undoc, "...")
if (length(undoc) > 0) {
warning("Undocumented parameters in ",
entry$tags$name, ": ",
paste(undoc, collapse = ", "),
call. = FALSE)
}
}
}
}
Expand Down
76 changes: 76 additions & 0 deletions inst/tinytest/test_rdname.R
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,79 @@ expect_true(grepl("Detail B", rd_c))
# Examples from both blocks
expect_true(grepl("func_a\\(1\\)", rd_c))
expect_true(grepl("func_b\\(2\\)", rd_c))


# --- Test 7: @rdname params documented on a sibling block (issue #12) ---
# A function whose formals are documented on the primary block (not its own)
# must NOT be flagged as having undocumented parameters: blocks sharing an
# @rdname merge into one page, so the check is group-wide.

if (at_home()) {
tmp7 <- tempfile("rdname12")
dir.create(file.path(tmp7, "R"), recursive = TRUE, showWarnings = FALSE)
dir.create(file.path(tmp7, "man"), recursive = TRUE, showWarnings = FALSE)
writeLines(c("Package: rdname12", "Title: Test", "Version: 0.1",
"Description: Test pkg."), file.path(tmp7, "DESCRIPTION"))

# Primary block documents utc + precision; set_format has those formals
# but documents none of its own. set_level documents its own `level`.
writeLines(c(
"#' Logger setup",
"#'",
"#' Configure the logger.",
"#' @param utc Use UTC timestamps.",
"#' @param precision Sub-second digits.",
"#' @rdname logsetup",
"#' @export",
"set_format <- function(utc, precision) invisible(NULL)",
"",
"#' @param level Logging threshold.",
"#' @rdname logsetup",
"#' @export",
"set_level <- function(level) invisible(NULL)"
), file.path(tmp7, "R", "logsetup.R"))

blocks7 <- tinyrox:::parse_package(tmp7)

# No false positive: every formal is documented somewhere in the group.
expect_silent(tinyrox:::generate_all_rd(blocks7, tmp7, cran_check = TRUE))

unlink(tmp7, recursive = TRUE)
}


# --- Test 8: genuinely undocumented param still warns; cran_check gates it ---

if (at_home()) {
tmp8 <- tempfile("rdnamewarn")
dir.create(file.path(tmp8, "R"), recursive = TRUE, showWarnings = FALSE)
dir.create(file.path(tmp8, "man"), recursive = TRUE, showWarnings = FALSE)
writeLines(c("Package: rdnamewarn", "Title: Test", "Version: 0.1",
"Description: Test pkg."), file.path(tmp8, "DESCRIPTION"))

# `bogus` is documented by no block in the group -> should warn.
writeLines(c(
"#' Logger setup",
"#'",
"#' Configure the logger.",
"#' @param utc Use UTC timestamps.",
"#' @rdname logsetup",
"#' @export",
"set_format <- function(utc, bogus) invisible(NULL)",
"",
"#' @param level Logging threshold.",
"#' @rdname logsetup",
"#' @export",
"set_level <- function(level) invisible(NULL)"
), file.path(tmp8, "R", "logsetup.R"))

blocks8 <- tinyrox:::parse_package(tmp8)

# Warns about the truly-undocumented `bogus`...
expect_warning(tinyrox:::generate_all_rd(blocks8, tmp8, cran_check = TRUE),
"bogus")
# ...but cran_check = FALSE silences it.
expect_silent(tinyrox:::generate_all_rd(blocks8, tmp8, cran_check = FALSE))

unlink(tmp8, recursive = TRUE)
}
5 changes: 3 additions & 2 deletions man/generate_all_rd.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
\alias{generate_all_rd}
\title{Generate All Rd Files for a Package}
\usage{
generate_all_rd(blocks, path = ".", silent = FALSE)
generate_all_rd(blocks, path = ".", cran_check = TRUE)
}
\arguments{
\item{blocks}{List of documentation blocks from parse_package().}

\item{path}{Package root path.}

\item{silent}{Boolean flag whether operation whould be silent}
\item{cran_check}{Emit CRAN-compliance warnings (undocumented
parameters). Default TRUE.}
}
\value{
Character vector of generated file paths.
Expand Down