#!/usr/bin/env Rscript
"Ensure all dependencies of the form pkg::fun are in DESCRIPTION
Usage:
deps-in-desc [--allow_private_imports] [--root=<root_>] <files>...
Options:
--allow_private_imports Whether or not to allow the use of ::: on imported functions.
--root=<root_> Path relative to the git root that contains the R package root [default: .].
" -> doc
pre_installed <- c(
"base", "boot", "class", "cluster", "codetools", "compiler",
"datasets", "foreign", "graphics", "grDevices", "grid", "KernSmooth",
"lattice", "MASS", "Matrix", "methods", "mgcv", "nlme", "nnet",
"parallel", "rpart", "spatial", "splines", "stats", "stats4",
"survival", "tcltk", "tools", "utils"
)
arguments <- precommit::precommit_docopt(doc)
arguments$files <- normalizePath(arguments$files) # because working directory changes to root
setwd(normalizePath(arguments$root))
deps_in_desc <- function(file, arguments) {
if (basename(file) == "README.Rmd") {
# is .Rbuildignored, dependencies irrelevant
return()
}
if (grepl("(\\.Rmd|\\.Rnw|\\.rmd|\\.rnw)$", file)) {
file_ <- precommit::robust_purl(file)
} else {
file_ <- file
}
parse_data <- getParseData(parse(file = file_, keep.source = TRUE))
used <- parse_data[parse_data$token == "SYMBOL_PACKAGE", ]$text
local_pkg_name <- unname(desc::desc_get("Package"))
unregistered <- setdiff(
unique(used),
c(pre_installed, desc::desc_get_deps(file = ".")$package, local_pkg_name)
)
out <- TRUE
if (length(unregistered) > 0) {
cat(
"Not all packages used in your code are listed in DESCRIPTION. ",
"The following are missing in file `", file, "`: ",
paste(unregistered, collapse = ", "), ".\n",
"You can add them with `usethis::use_package()` or ",
"`usethis::use_dev_package()`.\n",
sep = ""
)
out <- FALSE
}
if (isTRUE(arguments$allow_private_imports)) {
return(out)
}
private <- setdiff(
parse_data[c(parse_data$token[-1], FALSE) == "NS_GET_INT", ]$text,
local_pkg_name
)
if (length(private) > 0) {
cat(
"You should generally not call any function with `:::` unless it's a function you ",
"define yourself in this package. The following files have such function calls: ",
paste0(file, collapse = ", "), "\n\n",
"If you still think `:::` is a good idea, you can ",
"allow private imports in your `.pre-commit-config.yaml` like this:
- id: deps-in-desc
args: [--allow_private_imports]
",
sep = ""
)
out <- FALSE
}
out
}
out <- lapply(arguments$files, deps_in_desc, arguments = arguments)
if (!all(unlist(out))) {
stop("Dependency check failed", call. = FALSE)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.