My package “DESCRIPTION” includes several packages under “Suggests,” which are conditionally used in some functions. Previously, my code included a lot of statements like
fx <- function(...) {
if !(requireNamespace("labelled", quietly = TRUE)) {
stop('"labelled" must be installed to use `fx()`')
}
# ...
}
I decided to streamline this by writing an internal helper to check for suggested packages:
check_pkg <- function(pkg) {
if (!all(sapply(pkg, requireNamespace, quietly = TRUE))) {
pkg <- switch(
min(length(pkg), 3),
paste0('"', pkg, '" package'),
paste0(paste0('"', pkg, '"', collapse = ' and '), ' packages'),
paste0(
paste0('"', pkg[-length(pkg)], '," ', collapse = ''),
'and "', pkg[[length(pkg)]], '" packages'
)
)
caller <- deparse(sys.call(-1)[[1]])
stop(pkg, ' must be installed to use `', caller, '`.', call. = FALSE)
}
}
Example usage:
#' @export
fx_needs_labelled <- function() {
check_pkg("labelled")
print("OK")
}
#' @export
fx_needs_fakepkg <- function() {
check_pkg("fakepkg")
print("OK")
}
fx_needs_labelled()
# "OK"
fx_needs_fakepkg()
# Error: "fakepkg" package must be installed to use `fx_needs_fakepkg`.
This all works fine, but I can no longer pass R CMD check (via devtools::check()
).
❯ checking package dependencies ... ERROR
Namespace dependency missing from DESCRIPTION Imports/Depends entries: 'labelled'
My guess is that R CMD check allows a namespace to appear in “Suggests” and not “Imports” if it’s used inside an if (requireNamespace(...)) { ... }
block, but not if that check is offloaded to another function.
Is there any way around this, or do I need to ditch my helper and do all the checking inside functions that use suggested packages?