Skip to content

Commit

Permalink
Improve revdep check docs. Closes #635
Browse files Browse the repository at this point in the history
  • Loading branch information
hadley committed Nov 5, 2014
1 parent 7f83206 commit 66f951a
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 56 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# devtools 1.X

* Improved documentation for `revdep_check()` (#635)

* `use_git_hook()` allows you to easily add a git hook to a package.

* `use_readme_rmd()` makes it easier to generate a `README.md` from
Expand Down
36 changes: 17 additions & 19 deletions R/check-cran.r
Original file line number Diff line number Diff line change
@@ -1,46 +1,44 @@
#' Check a package from CRAN.
#'
#' This is useful for automatically checking that dependencies of your
#' packages work.
#' Internal function used to power \code{\link{revdep_check}()}.
#'
#' This function does not clean up after itself, but does work in a
#' session-specific temporary directory, so all files will be removed
#' when your current R session ends.
#'
#' @param pkgs Vector of package names - note that unlike other \pkg{devtools}
#' functions this is the name of a CRAN package, not a path.
#' @param libpath path to library to store dependencies packages - if you
#' @param libpath Path to library to store dependencies packages - if you
#' you're doing this a lot it's a good idea to pick a directory and stick
#' with it so you don't have to download all the packages every time.
#' @param srcpath path to directory to store source versions of dependent
#' @param srcpath Path to directory to store source versions of dependent
#' packages - again, this saves a lot of time because you don't need to
#' redownload the packages every time you run the package.
#' @param bioconductor include bioconductor packages in checking?
#' @param type binary package type of test
#' @param threads number of concurrent threads to use for checking.
#' @param bioconductor Include bioconductor packages in checking?
#' @param type binary Package type to test (source, mac.binary etc). Defaults
#' to the same type as \code{\link{install.packages}()}.
#' @param threads Number of concurrent threads to use for checking.
#' It defaults to the option \code{"Ncpus"} or \code{1} if unset.
#' @param check_dir the directory in which the package is checked
#' @param check_dir Directory to store results.
#' @param revdep_pkg Optional name of a package for which this check is
#' checking the reverse dependencies of. This is normally passed in from
#' \code{\link{revdep_check}}, and is used only for logging.
#' @return invisible \code{TRUE} if successful and no ERRORs or WARNINGS,
#' @return invisible \code{TRUE} if successful and no ERRORs or WARNINGS.
#' @keywords internal
#' @export
#' @examples
#' \dontrun{
#' dep <- revdep("ggplot2")
#' check_cran(dep, "~/documents/ggplot/ggplot-check")
#' # Or, equivalently:
#' revdep_check("ggplot2")
#' }
check_cran <- function(pkgs, libpath = file.path(tempdir(), "R-lib"),
srcpath = libpath, bioconductor = FALSE, type = getOption("pkgType"),
threads = getOption("Ncpus", 1), check_dir = tempfile("check_cran"),
revdep_pkg = NULL) {
srcpath = libpath, bioconductor = FALSE,
type = getOption("pkgType"),
threads = getOption("Ncpus", 1),
check_dir = tempfile("check_cran"),
revdep_pkg = NULL) {

stopifnot(is.character(pkgs))
if (length(pkgs) == 0) return()

message("Checking ", length(pkgs), " CRAN packages")
message("Results saved in ", check_dir)

old <- options(warn = 1)
on.exit(options(old), add = TRUE)

Expand Down
59 changes: 49 additions & 10 deletions R/reverse-dependencies.r
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@
#' Tools to check and notify maintainers of all CRAN and bioconductor
#' packages that depend on the specified package.
#'
#' @param pkg package name
#' The first run in a session will be time-consuming because it must download
#' all package metadata from CRAN and bioconductor. Subsequent runs will
#' be faster.
#'
#' @param pkg Package name. This is unlike most devtools packages which
#' take a path because you might want to determine dependencies for a package
#' that you don't have installed.
#' @param ignore A character vector of package names to ignore. These packages
#' will not appear in returned vector.
#' will not appear in returned vector. This is used in
#' \code{\link{revdep_check}} to avoid packages with installation problems
#' or extremely long check times.
#' @inheritParams tools::dependsOnPkgs
#' @seealso \code{\link{revdep_check}()} to run R CMD check on all reverse
#' dependencies.
#' @export
#' @examples
#' \dontrun{
#' revdep("ggplot2")
#'
#' revdep("ggplot2", ignore = c("xkcd", "zoo"))
#'}
revdep <- function(pkg = NULL, dependencies = c("Depends", "Imports",
revdep <- function(pkg, dependencies = c("Depends", "Imports",
"Suggests", "LinkingTo"), recursive = FALSE, ignore = NULL) {
deps <- tools::dependsOnPkgs(pkg, dependencies, recursive, installed = packages())
deps <- setdiff(deps, ignore)
Expand All @@ -23,22 +33,51 @@ revdep <- function(pkg = NULL, dependencies = c("Depends", "Imports",

#' @rdname revdep
#' @export
revdep_maintainers <- function(pkg = ".") {
as.person(unique(packages()[revdep(pkg), "Maintainer"]))
revdep_maintainers <- function(pkg) {
maintainers <- unique(packages()[revdep(pkg), "Maintainer"])
as.person(maintainers)
}

#' @rdname revdep
#' @param ... Other parameters passed on to \code{\link{check_cran}}
#' Run R CMD check on all downstream dependencies.
#'
#' This is neeeded when you submit a new version of a package to CRAN.
#'
#' By \code{revdep_check} uses temporary library to store any packages that
#' are required by the packages being tests. This ensures that they don't
#' interfere with your default library, but means that if you restart R
#' between checks, you'll need to reinstall all the packages. If you're
#' doing reverse dependency checks frequently, I recommend that you create
#' a directory for these packages and set \code{libpath}.
#'
#' @inheritParams revdep
#' @inheritParams check_cran
#' @seealso \code{\link{revdep_maintainers}()} to run R CMD check on all reverse
#' dependencies.
#' @export
revdep_check <- function(pkg = NULL, recursive = FALSE, ignore = NULL, ...) {
#' @return An invisible list of results. But you'll probably want to look
#' at the check results on disk, which are saved in \code{check_dir}.
#' Summaries of all ERRORs and WARNINGs will be stored in
#' \code{check_dir/00check-summary.txt}.
#' @examples
#' \dontrun{
#' # Run R CMD check on all downstream dependencies of ggplot2
#' revdep_check("ggplot2")
#' }
revdep_check <- function(pkg, recursive = FALSE, ignore = NULL,
libpath = file.path(tempdir(), "R-lib"),
srcpath = libpath, bioconductor = FALSE,
type = getOption("pkgType"),
threads = getOption("Ncpus", 1),
check_dir = tempfile("check_cran")) {
pkgs <- revdep(pkg, recursive = recursive, ignore = ignore)
res <- check_cran(pkgs, revdep_pkg = pkg, ...)
res <- check_cran(pkgs, revdep_pkg = pkg, libpath = libpath,
srcpath = srcpath, bioconductor = bioconductor, type = type,
threads = threads, check_dir = check_dir)

res$revdep_package <- pkg
invisible(res)
}


cran_packages <- memoise::memoise(function() {
local <- file.path(tempdir(), "packages.rds")
download.file("http://cran.R-project.org/web/packages/packages.rds", local,
Expand Down
27 changes: 10 additions & 17 deletions man/check_cran.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,38 @@ check_cran(pkgs, libpath = file.path(tempdir(), "R-lib"), srcpath = libpath,
\item{pkgs}{Vector of package names - note that unlike other \pkg{devtools}
functions this is the name of a CRAN package, not a path.}

\item{libpath}{path to library to store dependencies packages - if you
\item{libpath}{Path to library to store dependencies packages - if you
you're doing this a lot it's a good idea to pick a directory and stick
with it so you don't have to download all the packages every time.}
\item{srcpath}{path to directory to store source versions of dependent
\item{srcpath}{Path to directory to store source versions of dependent
packages - again, this saves a lot of time because you don't need to
redownload the packages every time you run the package.}

\item{bioconductor}{include bioconductor packages in checking?}
\item{bioconductor}{Include bioconductor packages in checking?}

\item{type}{binary package type of test}
\item{type}{binary Package type to test (source, mac.binary etc). Defaults
to the same type as \code{\link{install.packages}()}.}

\item{threads}{number of concurrent threads to use for checking.
\item{threads}{Number of concurrent threads to use for checking.
It defaults to the option \code{"Ncpus"} or \code{1} if unset.}

\item{check_dir}{the directory in which the package is checked}
\item{check_dir}{Directory to store results.}

\item{revdep_pkg}{Optional name of a package for which this check is
checking the reverse dependencies of. This is normally passed in from
\code{\link{revdep_check}}, and is used only for logging.}
}
\value{
invisible \code{TRUE} if successful and no ERRORs or WARNINGS,
invisible \code{TRUE} if successful and no ERRORs or WARNINGS.
}
\description{
This is useful for automatically checking that dependencies of your
packages work.
Internal function used to power \code{\link{revdep_check}()}.
}
\details{
This function does not clean up after itself, but does work in a
session-specific temporary directory, so all files will be removed
when your current R session ends.
}
\examples{
\dontrun{
dep <- revdep("ggplot2")
check_cran(dep, "~/documents/ggplot/ggplot-check")
# Or, equivalently:
revdep_check("ggplot2")
}
}
\keyword{internal}

28 changes: 18 additions & 10 deletions man/revdep.Rd
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
% Generated by roxygen2 (4.0.2): do not edit by hand
\name{revdep}
\alias{revdep}
\alias{revdep_check}
\alias{revdep_maintainers}
\title{Reverse dependency tools.}
\usage{
revdep(pkg = NULL, dependencies = c("Depends", "Imports", "Suggests",
"LinkingTo"), recursive = FALSE, ignore = NULL)
revdep(pkg, dependencies = c("Depends", "Imports", "Suggests", "LinkingTo"),
recursive = FALSE, ignore = NULL)

revdep_maintainers(pkg = ".")

revdep_check(pkg = NULL, recursive = FALSE, ignore = NULL, ...)
revdep_maintainers(pkg)
}
\arguments{
\item{pkg}{package name}
\item{pkg}{Package name. This is unlike most devtools packages which
take a path because you might want to determine dependencies for a package
that you don't have installed.}
\item{dependencies}{a character vector listing the types of
dependencies, a subset of
Expand All @@ -24,19 +23,28 @@ revdep_check(pkg = NULL, recursive = FALSE, ignore = NULL, ...)
dependencies (and so on) be included?}
\item{ignore}{A character vector of package names to ignore. These packages
will not appear in returned vector.}

\item{...}{Other parameters passed on to \code{\link{check_cran}}}
will not appear in returned vector. This is used in
\code{\link{revdep_check}} to avoid packages with installation problems
or extremely long check times.}
}
\description{
Tools to check and notify maintainers of all CRAN and bioconductor
packages that depend on the specified package.
}
\details{
The first run in a session will be time-consuming because it must download
all package metadata from CRAN and bioconductor. Subsequent runs will
be faster.
}
\examples{
\dontrun{
revdep("ggplot2")
revdep("ggplot2", ignore = c("xkcd", "zoo"))
}
}
\seealso{
\code{\link{revdep_check}()} to run R CMD check on all reverse
dependencies.
}
69 changes: 69 additions & 0 deletions man/revdep_check.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
% Generated by roxygen2 (4.0.2): do not edit by hand
\name{revdep_check}
\alias{revdep_check}
\title{Run R CMD check on all downstream dependencies.}
\usage{
revdep_check(pkg, recursive = FALSE, ignore = NULL,
libpath = file.path(tempdir(), "R-lib"), srcpath = libpath,
bioconductor = FALSE, type = getOption("pkgType"),
threads = getOption("Ncpus", 1), check_dir = tempfile("check_cran"))
}
\arguments{
\item{pkg}{Package name. This is unlike most devtools packages which
take a path because you might want to determine dependencies for a package
that you don't have installed.}
\item{recursive}{logical: should reverse dependencies of reverse
dependencies (and so on) be included?}
\item{ignore}{A character vector of package names to ignore. These packages
will not appear in returned vector. This is used in
\code{\link{revdep_check}} to avoid packages with installation problems
or extremely long check times.}
\item{libpath}{Path to library to store dependencies packages - if you
you're doing this a lot it's a good idea to pick a directory and stick
with it so you don't have to download all the packages every time.}

\item{srcpath}{Path to directory to store source versions of dependent
packages - again, this saves a lot of time because you don't need to
redownload the packages every time you run the package.}
\item{bioconductor}{Include bioconductor packages in checking?}
\item{type}{binary Package type to test (source, mac.binary etc). Defaults
to the same type as \code{\link{install.packages}()}.}
\item{threads}{Number of concurrent threads to use for checking.
It defaults to the option \code{"Ncpus"} or \code{1} if unset.}
\item{check_dir}{Directory to store results.}
}
\value{
An invisible list of results. But you'll probably want to look
at the check results on disk, which are saved in \code{check_dir}.
Summaries of all ERRORs and WARNINGs will be stored in
\code{check_dir/00check-summary.txt}.
}
\description{
This is neeeded when you submit a new version of a package to CRAN.
}
\details{
By \code{revdep_check} uses temporary library to store any packages that
are required by the packages being tests. This ensures that they don't
interfere with your default library, but means that if you restart R
between checks, you'll need to reinstall all the packages. If you're
doing reverse dependency checks frequently, I recommend that you create
a directory for these packages and set \code{libpath}.
}
\examples{
\dontrun{
# Run R CMD check on all downstream dependencies of ggplot2
revdep_check("ggplot2")
}
}
\seealso{
\code{\link{revdep_maintainers}()} to run R CMD check on all reverse
dependencies.
}

0 comments on commit 66f951a

Please sign in to comment.