--- title: "What R CMD check Checks" vignette: > %\VignetteIndexEntry{What R CMD check Checks} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} knitr: opts_chunk: collapse: true comment: '#>' --- `R CMD check` is a pipeline. It builds your package, installs it, and then runs roughly fifty separate checks, each of which prints a line beginning `* checking ...` and ends with a verdict. R itself parses those lines back out of the log with a single [regular expression][checktools], and this page walks through what each one is actually looking at. The checks themselves are defined in R's own `tools` package ([`check.R`][check-src]), and the manual describes the process in [Writing R Extensions, "Checking packages"][wre-check]. checktor is deliberately the other half of this story: it runs the extra-CRAN checks that a human reviewer applies but that `R CMD check` never will. Knowing exactly where `R CMD check` stops is the fastest way to see where checktor begins, so this page is a map of the territory `R CMD check` already covers. For the map of checktor's own checks, see [Where the Checks Come From](check-sources.html). ## The four verdicts Every step ends in one of four states, and only the last three matter. - `OK` means nothing to report. - `NOTE` means something a reviewer will likely ask about. A submission with NOTEs can still be accepted, but each one needs a reason. - `WARNING` means a real problem. CRAN will not accept a package with a WARNING. - `ERROR` means the check could not complete, usually because code or a test failed outright. A clean `R CMD check` is the floor for a CRAN submission, not the ceiling. Many of its steps are structural ("is this a well-formed package?") rather than editorial ("is this package good?"), which is exactly the gap a reviewer fills in, and the gap checktor is built for. ## Packaging and installation These run first and decide whether the package is even well-formed enough to install. A failure here stops everything else. | Step | What it checks | |---|---| | `checking for file 'DESCRIPTION'` | The package has a readable `DESCRIPTION` at its root. | | `checking package namespace information` | `NAMESPACE` exists and parses. | | `checking package dependencies` | Every package in `Depends`, `Imports`, `LinkingTo`, and `Suggests` is installed and available. | | `checking if this is a source package` | The tree looks like a source package, not an already-built binary. | | `checking if there is a namespace` | A `NAMESPACE` file is present. | | `checking for executable files` | No stray executables are present in the sources. | | `checking for hidden files and directories` | Flags hidden files (`.foo`) that are usually build detritus. | | `checking for portable file names` | File names are ASCII, case-insensitively unique, and free of characters that break on other platforms. | | `checking for sufficient/correct file permissions` | Every file is readable, and nothing is unexpectedly executable. | | `checking whether package can be installed` | The package installs cleanly with `R CMD INSTALL`; the install log is scanned for warnings. | | `checking installed package size` | Flags an installed package that is large (a NOTE above ~5 MB). | | `checking package directory` | The installed layout has the directories R expects. | | `checking 'build' directory` | The `build/` metadata (from `R CMD build`) is consistent. | | `checking index information` | `INDEX` and demo/vignette indices are present and consistent. | | `checking package subdirectories` | Subdirectories are named and cased as R requires, with no empty ones. | | `checking top-level files` | Only recognised files sit at the package root. | | `checking for left-over files` | No editor backups or merge-conflict leftovers are present. | ## DESCRIPTION and metadata | Step | What it checks | |---|---| | `checking DESCRIPTION meta-information` | `DESCRIPTION` parses, the `License` is recognised, `Authors@R` is valid, the encoding is declared, and the dependency fields are well-formed. | ## R code The heart of the static analysis. `checking R code for possible problems` is R's own linter (`codetools`), and it catches a great deal on its own. | Step | What it checks | |---|---| | `checking code files for non-ASCII characters` | R sources are ASCII, or their non-ASCII content is declared. | | `checking R files for syntax errors` | Every `.R` file parses. | | `checking whether the package can be loaded` | The package loads without error. | | `checking whether the package can be loaded with stated dependencies` | It loads using only the declared dependencies, catching an undeclared `Depends`. | | `checking whether the package can be unloaded cleanly` | Unloading raises no error. | | `checking whether the namespace can be loaded with stated dependencies` | The namespace imports resolve against the declared dependencies. | | `checking whether the namespace can be unloaded cleanly` | The namespace unloads without error. | | `checking use of S3 registration` | S3 methods are registered through `NAMESPACE`, not attached by hand. | | `checking dependencies in R code` | Every `pkg::fn` and imported symbol traces to a declared dependency. | | `checking S3 generic/method consistency` | An S3 method's arguments are compatible with its generic. | | `checking replacement functions` | A `foo<-` function takes `value` as its final argument. | | `checking foreign function calls` | `.C`, `.Call`, and friends name registered, correctly-shaped native routines. | | `checking R code for possible problems` | `codetools` flags undefined globals, unused arguments, questionable `.Internal` use, and similar issues across all R code. | ## Documentation Everything here works on the `.Rd` files, whether written by hand or generated by roxygen2. | Step | What it checks | |---|---| | `checking Rd files` | Every `.Rd` file parses and has the required tags. | | `checking Rd metadata` | `\name` and `\alias` entries are present and unique. | | `checking Rd line widths` | (`--as-cran`) Flags `\usage` lines wider than 90 characters and `\examples` lines wider than 100. | | `checking Rd cross-references` | Every `\link{}` points at a topic that exists. | | `checking for missing documentation entries` | Every exported object has a documented `\alias`. | | `checking for code/documentation mismatches` | Argument names in `\usage`, `\arguments`, and function signatures agree. | | `checking Rd \usage sections` | Each `\usage` block matches the object it documents. | | `checking Rd contents` | Flags placeholder or empty sections left in a documentation template. | ## Examples, tests, and vignettes The dynamic checks: R actually runs your code and fails on any error. | Step | What it checks | |---|---| | `checking for unstated dependencies in examples` | Examples use only declared packages. | | `checking examples` | Every `\examples{}` block runs without error. `\dontrun{}` and `\donttest{}` code is skipped. | | `checking examples with --run-donttest` | (`--as-cran`) When the examples contain `\donttest{}`, they run again with that code included, so it must run without error too. | | `checking installed files from 'inst/doc'` | Files under `inst/doc` are consistent with the vignettes. | | `checking files in 'vignettes'` | The `vignettes/` sources are well-formed. | | `checking for unstated dependencies in 'tests'` | Tests use only declared packages. | | `checking tests` | The test suite runs; any failure is an ERROR. | | `checking for unstated dependencies in vignettes` | Vignettes use only declared packages. | | `checking package vignettes` | Vignette metadata and index entries are present and consistent. | | `checking re-building of vignette outputs` | Every vignette rebuilds from source without error. | ## The CRAN incoming checks (`--as-cran`) With `--as-cran`, the checks people actually mean by "the CRAN checks" are added. Most of a maintainer's NOTEs come from the first line here. | Step | What it checks | |---|---| | `checking CRAN incoming feasibility` | The submission-readiness pass: the `Title` case, `Version`, `Date`, `Description`, `Authors@R`, `License`, URLs, and DOIs, plus a spell-check and a look for prior versions and problematic dependencies. | | `checking for future file timestamps` | No file is dated in the future. | | `checking serialization versions` | No saved object uses a serialization format newer than the package's stated R dependency. | ## Cleanup The last two steps confirm the check itself left nothing behind. | Step | What it checks | |---|---| | `checking for non-standard things in the check directory` | No unexpected files were produced during the check. | | `checking for detritus in the temp directory` | The package cleaned up after itself in `tempdir()`. | ## Steps you will only see sometimes Several checks run only when the package has the matching content. | Step | Runs when | |---|---| | `checking contents of 'data' directory` | The package includes a `data/` directory. | | `checking data for non-ASCII characters` | The package includes data. | | `checking data for ASCII and uncompressed saves` | The package includes data, and efficient compression is preferred. | | `checking line endings in ... sources and headers` | The package includes C, C++, or Fortran code. | | `checking compilation flags in Makevars` | The package includes a `src/Makevars`. | | `checking compiled code` | The package includes compiled code, and calls to disallowed entry points are reported. | | `checking PDF version of manual` | The manual is built (skipped by `--no-manual`). | ## Where checktor fits Read the tables above and a pattern emerges. `R CMD check` asks, thoroughly, *is this a well-formed package that builds, installs, and runs?* What it almost never asks is *is this the way a CRAN reviewer wants it written?* It will not object to a bare `T` in place of `TRUE`, a `set.seed()` buried in a function, an unquoted package name in the `Title`, an exported function with no `\value{}` tag, or a one-line `Description`. Those are judgement calls a human makes, and they are where a passing check and a passing review part ways. That gap is checktor's whole job. It runs the extra-CRAN checks that live in the Repository Policy and reviewers' habits but nowhere in `R CMD check`. Run the two together: `R CMD check` for the structure, checktor for the review. See [Where the Checks Come From](check-sources.html) for the source and severity behind each one checktor adds. [checktools]: https://github.com/wch/r-source/blob/trunk/src/library/tools/R/checktools.R [check-src]: https://github.com/wch/r-source/blob/trunk/src/library/tools/R/check.R [wre-check]: https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Checking-packages