23.2 Checks
50 checks - for a full list, see the book.
The categories of checks are:
metadata
package structure
- files are where they should be and there aren’t any non-standard top level files
- it can be installed
- package size isn’t > 5MB
- in short: lots of pain that can be alleviated by using
{usethis}
for making any new files
DESCRIPTION
License: ____
must refer to a known license (https://svn.r-project.org/R/trunk/share/licenses/license.db) or must be afile LICENSE
and the file must exist- All dependencies including
Suggests
must be installed - Every package listed in
Depends
must also be imported in theNAMESPACE
or accessed withpkg::foo
. If you don’t do this, your package will work when attached to the search path (withlibrary(mypackage)
) because it will also be attaching those packages that it depends on but will not work when only loaded (e.g.mypackage::foo()
). In terms of good practice: don’t use Depends and always access other packages that your package depends on usingpkg::foo
.
NAMESPACE
R code
checks R scripts for errors - unlikely to get many issues here since they would have cropped up when running
devtools::load_all()
(which you probably would have before running a check)can’t access functions from other packages which aren’t exported (
:::
)- you are not allowed to use
:::
to access non-exported functions from other packages. Either ask the package maintainer to export the function you need, or write your own version of it using exported functions. Alternatively, if the licenses are compatible you can copy and paste the exported function into your own package. If you do this, remember to updateAuthors@R
.
- you are not allowed to use
S3 generic/method consistency
print <- function(x, ...){ UseMethod("print") } # BAD print.my_class <- function(x) { cat("Hi") } # GOOD print.my_class <- function(x, ...) { cat("Hi") } # Also ok print.my_class <- function(x, ..., my_arg = TRUE) { cat("Hi") }
- Don’t use
assign()
to modify objects in the global environment. If you need to maintain state across function calls, create your own environment withe <- new.env(parent = emptyenv())
and set and get values in it:
e <- new.env(parent = emptyenv()) add_up <- function(x) { if (is.null(e$last_x)) { old <- 0 } else { old <- e$last_x } new <- old + x e$last_x <- new new } add_up(10) #> [1] 10 add_up(20) #> [1] 30
- Don’t use
T
orF
in your functions - useTRUE
andFALSE
Data
Documentation
- checks for completeness in all documentation and all man/*.Rd files have correct syntax
- checks maximum linewidth
- checks examples in help files (can use
devtools::run_examples()
to check these alone)
Demos
Compiled Code
checks all foreign function calls with in compiled code
runs all tests (
devtools::test()
)- if the
devtools::test()
passes but test within theR CMD CHECK
fails, there’s something that’s changed in your testing environment and it can be tricky to figure out. I’ve found restarting R before runningdevtools::test()
seems to make the problem apparent.
- if the
Vignettes
checks for dependencies in vignettes and that the files are in right place within the pkg directory
builds the vignettes
running vignettes requires that the package is installed (
devtools::install()
)can be pretty slow - if you’re wanting to quicky iterate through
check()
s and focus on other problems in your package:- add
--no-build-vignettes
to “Build Source Packages” field in project options devtools::check(vignettes=FALSE)
- add