R CMD check
on the reverse dependencies of a packageInstall the source package, figure out the reverse dependencies on CRAN,
download all of their source packages, and run R CMD check
on them
in parallel.
rev_check(
pkg,
which = "all",
recheck = NULL,
ignore = NULL,
update = TRUE,
timeout = getOption("xfun.rev_check.timeout", 15 * 60),
src = file.path(src_dir, pkg),
src_dir = getOption("xfun.rev_check.src_dir")
)compare_Rcheck(status_only = TRUE, output = "00check_diffs.md")
A named numeric vector with the names being package names of reverse
dependencies; 0
indicates check success, 1
indicates failure,
and 2
indicates that a package was not checked due to global
timeout.
The package name.
Which types of reverse dependencies to check. See
tools::package_dependencies()
for possible values. The
special value 'hard'
means the hard dependencies, i.e.,
c('Depends', 'Imports', 'LinkingTo')
.
A vector of package names to be (re)checked. If not provided
and there are any *.Rcheck
directories left by certain packages
(this often means these packages failed the last time), recheck
will
be these packages; if there are no *.Rcheck
directories but a text
file recheck
exists, recheck
will be the character vector
read from this file. This provides a way for you to manually specify the
packages to be checked. If there are no packages to be rechecked, all
reverse dependencies will be checked.
A vector of package names to be ignored in R CMD
check
. If this argument is missing and a file 00ignore
exists, the
file will be read as a character vector and passed to this argument.
Whether to update all packages before the check.
Timeout in seconds for R CMD check
to check each
package. The (approximate) total time can be limited by the global option
xfun.rev_check.timeout_total
.
The path of the source package directory.
The parent directory of the source package directory. This can be set in a global option if all your source packages are under a common parent directory.
If TRUE
, only compare the final statuses of the
checks (the last line of 00check.log
), and delete *.Rcheck
and *.Rcheck2
if the statuses are identical, otherwise write out the
full diffs of the logs. If FALSE
, compare the full logs under
*.Rcheck
and *.Rcheck2
.
The output Markdown file to which the diffs in check logs will be written. If the markdown package is available, the Markdown file will be converted to HTML, so you can see the diffs more clearly.
Everything occurs under the current working directory, and you are
recommended to call this function under a designated directory, especially
when the number of reverse dependencies is large, because all source packages
will be downloaded to this directory, and all *.Rcheck
directories
will be generated under this directory, too.
If a source tarball of the expected version has been downloaded before (under
the tarball
directory), it will not be downloaded again (to save time
and bandwidth).
After a package has been checked, the associated *.Rcheck
directory
will be deleted if the check was successful (no warnings or errors or notes),
which means if you see a *.Rcheck
directory, it means the check
failed, and you need to take a look at the log files under that directory.
The time to finish the check is recorded for each package. As the check goes
on, the total remaining time will be roughly estimated via n * mean(times)
, where n
is the number of packages remaining to be
checked, and times
is a vector of elapsed time of packages that have
been checked.
If a check on a reverse dependency failed, its *.Rcheck
directory will
be renamed to *.Rcheck2
, and another check will be run against the
CRAN version of the package unless options(xfun.rev_check.compare = FALSE)
is set. If the logs of the two checks are the same, it means no new
problems were introduced in the package, and you can probably ignore this
particular reverse dependency. The function compare_Rcheck()
can be
used to create a summary of all the differences in the check logs under
*.Rcheck
and *.Rcheck2
. This will be done automatically if
options(xfun.rev_check.summary = TRUE)
has been set.
A recommended workflow is to use a special directory to run
rev_check()
, set the global options()
xfun.rev_check.src_dir
and repos
in the R startup (see
?
Startup
) profile file .Rprofile
under this directory,
and (optionally) set R_LIBS_USER
in .Renviron
to use a special
library path (so that your usual library will not be cluttered). Then run
xfun::rev_check(pkg)
once, investigate and fix the problems or (if you
believe it was not your fault) ignore broken packages in the file
00ignore
, and run xfun::rev_check(pkg)
again to recheck the
failed packages. Repeat this process until all *.Rcheck
directories
are gone.
As an example, I set options(repos = c(CRAN = 'https://cran.rstudio.com'), xfun.rev_check.src_dir = '~/Dropbox/repo')
in
.Rprofile
, and R_LIBS_USER=~/R-tmp
in .Renviron
. Then I
can run, for example, xfun::rev_check('knitr')
repeatedly under a
special directory ~/Downloads/revcheck
. Reverse dependencies and their
dependencies will be installed to ~/R-tmp
, and knitr will be
installed from ~/Dropbox/repo/kintr
.
devtools::revdep_check()
is more sophisticated, but currently
has a few major issues that affect me: (1) It always deletes the
*.Rcheck
directories
(https://github.com/r-lib/devtools/issues/1395), which makes it
difficult to know more information about the failures; (2) It does not
fully install the source package before checking its reverse dependencies
(https://github.com/r-lib/devtools/pull/1397); (3) I feel it is
fairly difficult to iterate the check (ignore the successful packages and
only check the failed packages); by comparison, xfun::rev_check()
only requires you to run a short command repeatedly (failed packages are
indicated by the existing *.Rcheck
directories, and automatically
checked again the next time).
xfun::rev_check()
borrowed a very nice feature from
devtools::revdep_check()
: estimating and displaying the remaining
time. This is particularly useful for packages with huge numbers of reverse
dependencies.