14

Given the DESCRIPTION file of an R package, I would like to obtain a list of the package dependencies (e.g. Depends, Imports, Suggests). It seems like this should be a solved problem (e.g. by devtools::install_github) but I cannot seem to come up with an elegant way to do this. My current solution is to rely on an unexported function from tools:

## adapted.from biocLite("pkgDepTools")
cleanPkgField <- function(val) {
    if (is.na(val))
      return(character(0))
    val <- names(tools:::.split_dependencies(val))
    if (is.null(val))
      return(character(0))
    val <- val[! val %in% "R"]
    if (length(val))
      return(val)
    return(character(0))
}

get_deps <- function(dp){
  dcf <- read.dcf(paste0(dp, "/DESCRIPTION"))
  suggests <- imports <- depends <- NULL
  if("Suggests" %in% colnames(dcf))
  suggests <- cleanPkgField(dcf[,"Suggests"])
  if("Imports" %in% colnames(dcf))
  imports <- cleanPkgField(dcf[,"Imports"])
  if("Depends" %in% colnames(dcf))
  depends <- cleanPkgField(dcf[,"Depends"])

  c(suggests, imports, depends)

  ## Doesn't work for packages not on CRAN
#  unlist(tools::package_dependencies(package_names, available.packages(),
#         which=c("Depends", "Imports", "Suggests"), recursive=FALSE))
}

where dp is the package directory. This seems to work, but it feels like there should be an extant function to do this, or at least something cleaner than relying on the hidden and non-exported .split_dependencies() function in the tools package.

Note that the more widely cited way to get dependencies for a package is not to rely on the DESCRIPTION file at all, but rather to use something like tools::package_dependencies which assumes the package can be found on some CRAN-like repository, e.g. these SO questions:

note that while the problem description is the same, the fact that the package is not on CRAN (or similar repository) makes that approach impossible.

Community
  • 1
  • 1
cboettig
  • 12,377
  • 13
  • 70
  • 113

1 Answers1

13

This is at least a bit simpler and doesn't rely on any unexported functions:

get_deps <- function(path) {
    dcf <- read.dcf(file.path(path, "DESCRIPTION"))
    jj <- intersect(c("Depends", "Imports", "Suggests"), colnames(dcf))
    val <- unlist(strsplit(dcf[, jj], ","), use.names=FALSE)
    val <- gsub("\\s.*", "", trimws(val))
    val[val != "R"]
}

## Test it out on a source package with no imports ...
get_deps("C:/R/Source/Library/raster")
##  [1] "methods"   "sp"        "rgdal"     "rgeos"     "ncdf"      "ncdf4"    
##  [7] "igraph"    "snow"      "tcltk"     "rasterVis"

## ... and an installed package with no dependencies at all
get_deps("C:/R/Library/RColorBrewer/")
# named character(0)
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455